diff --git a/Web/public/config.json b/Web/public/config.json index a97e582..411e034 100644 --- a/Web/public/config.json +++ b/Web/public/config.json @@ -1,3 +1,3 @@ { - "apiEndpoint": "https://localhost:5001" + "apiEndpoint": "http://localhost:5000" } \ No newline at end of file diff --git a/theme/docs/index.html b/theme/docs/index.html new file mode 100644 index 0000000..be2abec --- /dev/null +++ b/theme/docs/index.html @@ -0,0 +1,15 @@ + + + + + Modernize Angular Premium Template | Docs + + + + +

Modernize Angular Premium Template

+ https://adminmart.github.io/premium-documentation/angular/modernize/index.html + + + \ No newline at end of file diff --git a/theme/figma-file/figma-file-to-download.txt b/theme/figma-file/figma-file-to-download.txt new file mode 100644 index 0000000..9f0b6d3 --- /dev/null +++ b/theme/figma-file/figma-file-to-download.txt @@ -0,0 +1 @@ +https://www.figma.com/file/vx7BDKIRGoSwxs5lItTMlD/Modernize \ No newline at end of file diff --git a/theme/packages/authguard/package-lock.json b/theme/packages/authguard/package-lock.json new file mode 100644 index 0000000..dfa3be9 --- /dev/null +++ b/theme/packages/authguard/package-lock.json @@ -0,0 +1,14283 @@ +{ + "name": "modernize", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "modernize", + "version": "0.0.0", + "dependencies": { + "@angular/animations": "^20.0.4", + "@angular/cdk": "^20.0.3", + "@angular/common": "^20.0.4", + "@angular/compiler": "^20.0.4", + "@angular/core": "^20.0.4", + "@angular/forms": "^20.0.4", + "@angular/material": "^20.0.3", + "@angular/platform-browser": "^20.0.4", + "@angular/platform-browser-dynamic": "^20.0.4", + "@angular/router": "^20.0.4", + "@ngx-translate/core": "^14.0.0", + "@ngx-translate/http-loader": "^7.0.0", + "angular-tabler-icons": "^3.26.0", + "ngx-scrollbar": "^18.0.0", + "rxjs": "~7.8.2", + "sass": "^1.89.2", + "tslib": "^2.8.1", + "zone.js": "~0.15.1" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^20.0.3", + "@angular/cli": "~20.0.3", + "@angular/compiler-cli": "^20.0.4", + "@types/date-fns": "^2.6.3", + "@types/jasmine": "~5.1.8", + "jasmine-core": "~5.8.0", + "karma": "~6.4.4", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.1", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.8.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.2000.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2000.4.tgz", + "integrity": "sha512-pg+EPv/j17ybCoYiKjeRCebkE5CeD009xC6XJfugBmui6CcCQ5UAN82ibBhL869PXR7xCboylcRxlFfcBmvCpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.0.4", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.0.4.tgz", + "integrity": "sha512-YUf9hRAd//yu44vGMnET1ajmUMXwSz0t4rOajDj5yb57sYS9eYu912K2pWfDNDNJncOshtpklvBqUDngDNcPDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.2000.4", + "@angular-devkit/build-webpack": "0.2000.4", + "@angular-devkit/core": "20.0.4", + "@angular/build": "20.0.4", + "@babel/core": "7.27.1", + "@babel/generator": "7.27.1", + "@babel/helper-annotate-as-pure": "7.27.1", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.27.1", + "@babel/plugin-transform-async-to-generator": "7.27.1", + "@babel/plugin-transform-runtime": "7.27.1", + "@babel/preset-env": "7.27.2", + "@babel/runtime": "7.27.1", + "@discoveryjs/json-ext": "0.6.3", + "@ngtools/webpack": "20.0.4", + "@vitejs/plugin-basic-ssl": "2.0.0", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.21", + "babel-loader": "10.0.0", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "13.0.0", + "css-loader": "7.1.2", + "esbuild-wasm": "0.25.5", + "fast-glob": "3.3.3", + "http-proxy-middleware": "3.0.5", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.3.0", + "less-loader": "12.3.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "mini-css-extract-plugin": "2.9.2", + "open": "10.1.2", + "ora": "8.2.0", + "picomatch": "4.0.2", + "piscina": "5.1.1", + "postcss": "8.5.3", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.2", + "sass": "1.88.0", + "sass-loader": "16.0.5", + "semver": "7.7.2", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.39.1", + "tree-kill": "1.2.2", + "tslib": "2.8.1", + "webpack": "5.99.8", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.2.1", + "webpack-merge": "6.0.1", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.25.5" + }, + "peerDependencies": { + "@angular/compiler-cli": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/localize": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "@angular/platform-server": "^20.0.0", + "@angular/service-worker": "^20.0.0", + "@angular/ssr": "^20.0.4", + "@web/test-runner": "^0.20.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^20.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "typescript": ">=5.8 <5.9" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, + "@angular/localize": { + "optional": true + }, + "@angular/platform-browser": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/sass": { + "version": "1.88.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.88.0.tgz", + "integrity": "sha512-sF6TWQqjFvr4JILXzG4ucGOLELkESHL+I5QJhh7CNaE+Yge0SI+ehCatsXhJ7ymU1hAFcIS3/PBpjdIbXoyVbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.2000.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2000.4.tgz", + "integrity": "sha512-ZdYSzuDJOIXzuzr3JuriAXWjjVH335K7sLF1udyd1BUeDkKjRNOrrd0Zfo8eraMgbMfEdjApf+UGzTBgU0euMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2000.4", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/core": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.0.4.tgz", + "integrity": "sha512-GmHBOEhdZn0Xh8JAdmnbSXtEMoAEqakEFy1JZmwuUo5e6uuuEp5xQY4O3MO0UQBVjYT+Wz8KNfonTvY91t/lNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.2", + "source-map": "0.7.4" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.0.4.tgz", + "integrity": "sha512-NADJed7h4KYSqbbw91AKFvFp+CsDuPUBzuMrck38R0ql0ZeaLKJtwT+IQFs7Hb6bmE4xn1i0+Z/p7v8q6ZRrKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.0.4", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "8.2.0", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/animations": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.0.5.tgz", + "integrity": "sha512-v8dzr2tnju7Sa7XUhMY6yTJpRV3isMqP3mnOjrul2kkEY870a1tZ7VI7xp0qTx36086/+nzXAvOvOItmRkUaaQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.0.5", + "@angular/core": "20.0.5" + } + }, + "node_modules/@angular/build": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.0.4.tgz", + "integrity": "sha512-SIYLg2st05Q5hgFrxwj6L4i9j2j2JNWYoYgacXp+mw9YVhFiC02Ymbakc9fq+3+sWlm0XTX5JgrupV2ac1ytNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.2000.4", + "@babel/core": "7.27.1", + "@babel/helper-annotate-as-pure": "7.27.1", + "@babel/helper-split-export-declaration": "7.24.7", + "@inquirer/confirm": "5.1.10", + "@vitejs/plugin-basic-ssl": "2.0.0", + "beasties": "0.3.4", + "browserslist": "^4.23.0", + "esbuild": "0.25.5", + "https-proxy-agent": "7.0.6", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "listr2": "8.3.3", + "magic-string": "0.30.17", + "mrmime": "2.0.1", + "parse5-html-rewriting-stream": "7.1.0", + "picomatch": "4.0.2", + "piscina": "5.1.1", + "rollup": "4.40.2", + "sass": "1.88.0", + "semver": "7.7.2", + "source-map-support": "0.5.21", + "tinyglobby": "0.2.13", + "vite": "6.3.5", + "watchpack": "2.4.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.3.0" + }, + "peerDependencies": { + "@angular/compiler": "^20.0.0", + "@angular/compiler-cli": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/localize": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "@angular/platform-server": "^20.0.0", + "@angular/service-worker": "^20.0.0", + "@angular/ssr": "^20.0.4", + "karma": "^6.4.0", + "less": "^4.2.0", + "ng-packagr": "^20.0.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "tslib": "^2.3.0", + "typescript": ">=5.8 <5.9", + "vitest": "^3.1.1" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, + "@angular/localize": { + "optional": true + }, + "@angular/platform-browser": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "karma": { + "optional": true + }, + "less": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/sass": { + "version": "1.88.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.88.0.tgz", + "integrity": "sha512-sF6TWQqjFvr4JILXzG4ucGOLELkESHL+I5QJhh7CNaE+Yge0SI+ehCatsXhJ7ymU1hAFcIS3/PBpjdIbXoyVbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/@angular/cdk": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-20.0.4.tgz", + "integrity": "sha512-NCUuw0qQXwawLsT14JHApNB9or3XGs7D1pWXlOIix/fKqzHVfi4un9xHmpjH2Q1uCiwonuak7fDof8B+IXhbug==", + "license": "MIT", + "dependencies": { + "parse5": "^7.1.2", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^20.0.0 || ^21.0.0", + "@angular/core": "^20.0.0 || ^21.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.0.4.tgz", + "integrity": "sha512-WG0TxDODciNU93AjENph4v7nBowMTGRI8VwIPitPstthez7oViugnXbsPoti5wfSjPweGawMSf6fgqOTx1+yKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2000.4", + "@angular-devkit/core": "20.0.4", + "@angular-devkit/schematics": "20.0.4", + "@inquirer/prompts": "7.5.1", + "@listr2/prompt-adapter-inquirer": "2.0.22", + "@schematics/angular": "20.0.4", + "@yarnpkg/lockfile": "1.1.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "8.3.3", + "npm-package-arg": "12.0.2", + "npm-pick-manifest": "10.0.0", + "pacote": "21.0.0", + "resolve": "1.22.10", + "semver": "7.7.2", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/common": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.0.5.tgz", + "integrity": "sha512-R7SQaOVYjVnrGHOq2RnuPn0pGofGVTDgy5EoHzF8ulb5MG/d7GFwCaMgfAbp3/Cw1CJzP2ZB54O8x9SMuqExyg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/core": "20.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.0.5.tgz", + "integrity": "sha512-eHHnh+wIUC+8mfmlPnkzVfonQCA3LAbPWgYpvEQtBh0/R3cZBN6tmOxWQB8IuLu+cZ0eXS/a14mqHJp3c3u7Hg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@angular/compiler-cli": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.0.5.tgz", + "integrity": "sha512-v0DSeUU7cid7jqfK9RTkyhbZGNIiOyxRYeaqZMsu4UiYGwABIanM7lOcX++OYapfWj/TEPky+5wtbV8ScqAxiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "7.27.4", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^4.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^18.0.0" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/compiler": "20.0.5", + "typescript": ">=5.8 <5.9" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core": { + "version": "7.27.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz", + "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.4", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.4", + "@babel/types": "^7.27.3", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/generator": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@angular/compiler-cli/node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@angular/compiler-cli/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@angular/compiler-cli/node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/@angular/compiler-cli/node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/@angular/core": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.0.5.tgz", + "integrity": "sha512-r7YQXZvKPAMUXeo3psKTZxyYJrwidTwDPrzxMX3EGqZxv0eDnMPWCxH2y0O2X4BT0Nm1iAqx3zhGrSFc0vD60Q==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/compiler": "20.0.5", + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0" + }, + "peerDependenciesMeta": { + "@angular/compiler": { + "optional": true + }, + "zone.js": { + "optional": true + } + } + }, + "node_modules/@angular/forms": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.0.5.tgz", + "integrity": "sha512-zoS0SaNUZBPtDfmr/edd3cHa9Z+vvPs8UXKMo9/i4YezWCskkZmW5qIJwISYJt4DHnHWoznlGBB9BQX8HgmQRw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.0.5", + "@angular/core": "20.0.5", + "@angular/platform-browser": "20.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/material": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-20.0.4.tgz", + "integrity": "sha512-ET+znnyOVjBezHsjy7U42/88JPl9Mhumvf01gMBN8mNcaoSpeM4cc2uKBg30/3YzykKIsjXtvUJj/PaTujmJAQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/cdk": "20.0.4", + "@angular/common": "^20.0.0 || ^21.0.0", + "@angular/core": "^20.0.0 || ^21.0.0", + "@angular/forms": "^20.0.0 || ^21.0.0", + "@angular/platform-browser": "^20.0.0 || ^21.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.0.5.tgz", + "integrity": "sha512-gE3C5/ZAXdAlBFvvX/crboIy5skbV5mtxRoEULwf7xF9WJLlYzY3w+PCRHV6/Z21UJ3ikCcbaaowBx378FYhQg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/animations": "20.0.5", + "@angular/common": "20.0.5", + "@angular/core": "20.0.5" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.0.5.tgz", + "integrity": "sha512-uGkHndCWqQyhjcDziC93R5CwQBKa+Xvk0s02ia8LJwVz7iIu/bLO34vos0HM9d250W4TNZbuVFmMhJDJWCq3uQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.0.5", + "@angular/compiler": "20.0.5", + "@angular/core": "20.0.5", + "@angular/platform-browser": "20.0.5" + } + }, + "node_modules/@angular/router": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.0.5.tgz", + "integrity": "sha512-GqBxrjov6p6riqDmn+hD2FWk5JSXR638/UhWCZe+XORoOmV/gWgND1HaHPa7f/UvM422yrPEkIsFNMr7bwLmkA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.0.5", + "@angular/core": "20.0.5", + "@angular/platform-browser": "20.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz", + "integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz", + "integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.1", + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helpers": "^7.27.1", + "@babel/parser": "^7.27.1", + "@babel/template": "^7.27.1", + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz", + "integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.1", + "@babel/types": "^7.27.1", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.1.tgz", + "integrity": "sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", + "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.27.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", + "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", + "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz", + "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.1", + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", + "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", + "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", + "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.27.1.tgz", + "integrity": "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.27.1.tgz", + "integrity": "sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.5.tgz", + "integrity": "sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.27.1.tgz", + "integrity": "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.27.1.tgz", + "integrity": "sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.27.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.3.tgz", + "integrity": "sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", + "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", + "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", + "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.27.3.tgz", + "integrity": "sha512-7ZZtznF9g4l2JCImCo5LNKFHB5eXnN39lLtLY5Tg+VkR0jwOt7TBciMckuiQIOIW7L5tkQOCh3bVGYeXgMx52Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.27.3", + "@babel/plugin-transform-parameters": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", + "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.1.tgz", + "integrity": "sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.5.tgz", + "integrity": "sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.27.1.tgz", + "integrity": "sha512-TqGF3desVsTcp3WrJGj4HfKokfCXCLcHpt4PJF0D8/iT6LPd9RS82Upw3KPeyr6B22Lfd3DO8MVrmp0oRkUDdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.11.0", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.27.2.tgz", + "integrity": "sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.27.1", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.27.1", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.27.1", + "@babel/plugin-transform-classes": "^7.27.1", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.27.1", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-exponentiation-operator": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.27.2", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1", + "@babel/plugin-transform-parameters": "^7.27.1", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.27.1", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.11.0", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.40.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz", + "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", + "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", + "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.8.tgz", + "integrity": "sha512-d/QAsnwuHX2OPolxvYcgSj7A9DO9H6gVOy2DvBTx+P2LH2iRTo/RSGV3iwCzW024nP9hw98KIuDmdyhZQj1UQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.10", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.10.tgz", + "integrity": "sha512-FxbQ9giWxUWKUk2O5XZ6PduVnH2CZ/fmMKMBkH71MHJvWr7WL5AHKevhzF1L5uYWB2P548o1RzVxrNd3dpmk6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.11", + "@inquirer/type": "^3.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.13", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.13.tgz", + "integrity": "sha512-1viSxebkYN2nJULlzCxES6G9/stgHSepZ9LqqfdIGPHj5OHhiBUXVS0a6R0bEC2A+VL4D9w6QB66ebCr6HGllA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.13", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.13.tgz", + "integrity": "sha512-WbicD9SUQt/K8O5Vyk9iC2ojq5RHoCLK6itpp2fHsWe44VxxcA9z3GTWlvjSTGmMQpZr+lbVmrxdHcumJoLbMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.15.tgz", + "integrity": "sha512-4Y+pbr/U9Qcvf+N/goHzPEXiHH8680lM3Dr3Y9h9FFw4gHS+zVpbj8LfbKWIb/jayIB4aSO4pWiBTrBYWkvi5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.12.tgz", + "integrity": "sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.12.tgz", + "integrity": "sha512-xJ6PFZpDjC+tC1P8ImGprgcsrzQRsUh9aH3IZixm1lAZFK49UGHxM3ltFfuInN2kPYNfyoPRh+tU4ftsjPLKqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.15.tgz", + "integrity": "sha512-xWg+iYfqdhRiM55MvqiTCleHzszpoigUpN5+t1OMcRkJrUrw7va3AzXaxvS+Ak7Gny0j2mFSTv2JJj8sMtbV2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.15.tgz", + "integrity": "sha512-75CT2p43DGEnfGTaqFpbDC2p2EEMrq0S+IRrf9iJvYreMy5mAWj087+mdKyLHapUEPLjN10mNvABpGbk8Wdraw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.5.1.tgz", + "integrity": "sha512-5AOrZPf2/GxZ+SDRZ5WFplCA2TAQgK3OYrXCYmJL5NaTu4ECcoWFlfUZuw7Es++6Njv7iu/8vpYJhuzxUH76Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.1.6", + "@inquirer/confirm": "^5.1.10", + "@inquirer/editor": "^4.2.11", + "@inquirer/expand": "^4.0.13", + "@inquirer/input": "^4.1.10", + "@inquirer/number": "^3.0.13", + "@inquirer/password": "^4.0.13", + "@inquirer/rawlist": "^4.1.1", + "@inquirer/search": "^3.0.13", + "@inquirer/select": "^4.2.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.3.tgz", + "integrity": "sha512-7XrV//6kwYumNDSsvJIPeAqa8+p7GJh7H5kRuxirct2cgOcSWwwNGoXDRgpNFbY/MG2vQ4ccIWCi8+IXXyFMZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.15.tgz", + "integrity": "sha512-YBMwPxYBrADqyvP4nNItpwkBnGGglAvCLVW8u4pRmmvOsHUtCAUIMbUrLX5B3tFL1/WsLGdQ2HNzkqswMs5Uaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.2.3.tgz", + "integrity": "sha512-OAGhXU0Cvh0PhLz9xTF/kx6g6x+sP+PcyTiLvCrewI99P3BBeexD+VbuwkNDvqGkk3y2h5ZiWLeRP7BFlhkUDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.7.tgz", + "integrity": "sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.2.0.tgz", + "integrity": "sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.6.0.tgz", + "integrity": "sha512-sw/RMbehRhN68WRtcKCpQOPfnH6lLP4GJfqzi3iYej8tnzpZUDr6UkZYJjcjjC0FWEJOJbyM3PTIwxucUmDG2A==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.22.tgz", + "integrity": "sha512-hV36ZoY+xKL6pYOt1nPNnkciFkn89KZwqLhAFzJvYysAvL5uBQdiADZx/8bIDXIukzzwG0QlPYolgMzQUtKgpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/type": "^1.5.5" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.3.0.tgz", + "integrity": "sha512-LipbQobyEfQtu8WixasaFUZZ+JCGlho4OWwWIQ5ol0rB1RKkcZvypu7sS1CBvofBGVAa3vbOh8IOGQMrbmL5dg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.3.0.tgz", + "integrity": "sha512-yA+9P+ZeA3vg76BLXWeUomIAjxfmSmR2eg8fueHXDg5Xe1Xmkl9JCKuHXUhtJ+mMVcH12d5k4kJBLbyXTadfGQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.3.0.tgz", + "integrity": "sha512-EDYrW9kle+8wI19JCj/PhRnGoCN9bked5cdOPdo1wdgH/HzjgoLPFTn9DHlZccgTEVhp3O+bpWXdN/rWySVvjw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.3.0.tgz", + "integrity": "sha512-OeWvSgjXXZ/zmtLqqL78I3910F6UYpUubmsUU+iBHo6nTtjkpXms95rJtGrjkWQqwswKBD7xSMplbYC4LEsiPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.3.0.tgz", + "integrity": "sha512-wDd02mt5ScX4+xd6g78zKBr6ojpgCJCTrllCAabjgap5FzuETqOqaQfKhO+tJuGWv/J5q+GIds6uY7rNFueOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-arm64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.3.0.tgz", + "integrity": "sha512-COotWhHJgzXULLiEjOgWQwqig6PoA+6ji6W+sDl6M1HhMXWIymEVHGs0edsVSNtsNSCAWMxJgR3asv6FNX/2EA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.3.0.tgz", + "integrity": "sha512-kqUgQH+l8HDbkAapx+aoko7Ez4X4DqkIraOqY/k0QY5EN/iialVlFpBUXh4wFXzirdmEVjbIUMrceUh0Kh8LeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz", + "integrity": "sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.0.1", + "@napi-rs/nice-android-arm64": "1.0.1", + "@napi-rs/nice-darwin-arm64": "1.0.1", + "@napi-rs/nice-darwin-x64": "1.0.1", + "@napi-rs/nice-freebsd-x64": "1.0.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.0.1", + "@napi-rs/nice-linux-arm64-gnu": "1.0.1", + "@napi-rs/nice-linux-arm64-musl": "1.0.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.0.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.0.1", + "@napi-rs/nice-linux-s390x-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-musl": "1.0.1", + "@napi-rs/nice-win32-arm64-msvc": "1.0.1", + "@napi-rs/nice-win32-ia32-msvc": "1.0.1", + "@napi-rs/nice-win32-x64-msvc": "1.0.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz", + "integrity": "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz", + "integrity": "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", + "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz", + "integrity": "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz", + "integrity": "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz", + "integrity": "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz", + "integrity": "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz", + "integrity": "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz", + "integrity": "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz", + "integrity": "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz", + "integrity": "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz", + "integrity": "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz", + "integrity": "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz", + "integrity": "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz", + "integrity": "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ngtools/webpack": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.0.4.tgz", + "integrity": "sha512-GFke8NcaFW62d1KXd4DkKbEw4mSsjJsMGmeHkBe5LPWS6zRIAZULo0fk/qV94IZ8INDbqY2k1WoxvStg7pHTsg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^20.0.0", + "typescript": ">=5.8 <5.9", + "webpack": "^5.54.0" + } + }, + "node_modules/@ngx-translate/core": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-14.0.0.tgz", + "integrity": "sha512-UevdwNCXMRCdJv//0kC8h2eSfmi02r29xeE8E9gJ1Al4D4jEJ7eiLPdjslTMc21oJNGguqqWeEVjf64SFtvw2w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/core": ">=13.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@ngx-translate/http-loader": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-7.0.0.tgz", + "integrity": "sha512-j+NpXXlcGVdyUNyY/qsJrqqeAdJdizCd+GKh3usXExSqy1aE9866jlAIL+xrfDU4w+LiMoma5pgE4emvFebZmA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": ">=13.0.0", + "@ngx-translate/core": ">=14.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.3.tgz", + "integrity": "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.2.0.tgz", + "integrity": "sha512-rCNLSB/JzNvot0SEyXqWZ7tX2B5dD2a1br2Dp0vSYVo5jh8Z0EZ7lS9TsZ1UtziddB1UfNUaMCc538/HztnJGA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.2.tgz", + "integrity": "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.2.2.tgz", + "integrity": "sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.1.0.tgz", + "integrity": "sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT", + "optional": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.2.tgz", + "integrity": "sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.2.tgz", + "integrity": "sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.2.tgz", + "integrity": "sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.2.tgz", + "integrity": "sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.2.tgz", + "integrity": "sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.2.tgz", + "integrity": "sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.2.tgz", + "integrity": "sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.2.tgz", + "integrity": "sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.2.tgz", + "integrity": "sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.2.tgz", + "integrity": "sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.2.tgz", + "integrity": "sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.2.tgz", + "integrity": "sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.2.tgz", + "integrity": "sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.2.tgz", + "integrity": "sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.2.tgz", + "integrity": "sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.2.tgz", + "integrity": "sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.2.tgz", + "integrity": "sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.2.tgz", + "integrity": "sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.2.tgz", + "integrity": "sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.2.tgz", + "integrity": "sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@schematics/angular": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.0.4.tgz", + "integrity": "sha512-cQw0ATQW/GTcYo5wmzMJrKlQsafNKeL3vduV6q0rILfp8P3OnJk7CtlWf9sfZnpEo0PNu28viMts3/p7ZUS8nQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.0.4", + "@angular-devkit/schematics": "20.0.4", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@sigstore/bundle": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz", + "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.4.3.tgz", + "integrity": "sha512-fk2zjD9117RL9BjqEwF7fwv7Q/P9yGsMV4MUJZ/DocaQJ6+3pKr+syBq1owU5Q5qGw5CUbXzm+4yJ2JVRDQeSA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.1.0.tgz", + "integrity": "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.1.1.tgz", + "integrity": "sha512-eFFvlcBIoGwVkkwmTi/vEQFSva3xs5Ot3WmBcjgjVdiaoelBLQaQ/ZBfhlG0MnG0cmTYScPpk7eDdGDWUcFUmg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.1", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.1.1.tgz", + "integrity": "sha512-hVJD77oT67aowHxwT4+M6PGOp+E2LtLdTK3+FC0lBO9T7sYwItDMXZ7Z07IDCvR1M717a4axbIWckrW67KMP/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", + "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/date-fns": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@types/date-fns/-/date-fns-2.6.3.tgz", + "integrity": "sha512-Ke1lw2Ni1t/wMUoLtKFmSNCLozcTBd6vmMqFP4hRzXn6qzkNt97bPAX0x5Y/c15DP43kKvwW1ycStD5+43jVQA==", + "deprecated": "This is a stub types definition. date-fns provides its own type definitions, so you do not need this installed.", + "dev": true, + "license": "MIT", + "dependencies": { + "date-fns": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.16", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz", + "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.8.tgz", + "integrity": "sha512-u7/CnvRdh6AaaIzYjCgUuVbREFgulhX05Qtf6ZtW+aOcjCKKVvKgpkPYJBFTZSHtFBYimzU4zP0V2vrEsq9Wcg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.0.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.4.tgz", + "integrity": "sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.0.0.tgz", + "integrity": "sha512-gc9Tjg8bUxBVSTzeWT3Njc0Cl3PakHFKdNfABnZWiUgbxqmHDEn7uECv3fHVylxoYgNzAcmU7ZrILz+BwSo3sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "vite": "^6.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/abbrev": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", + "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/angular-tabler-icons": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/angular-tabler-icons/-/angular-tabler-icons-3.26.0.tgz", + "integrity": "sha512-gOvELHvz9TgOXAVq1YDqPQ8Z+0kII4IETzKn95x//zdZ5//3RekpeAJE2go3zczXaxoy44frmea7i7mr40BDTw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + }, + "peerDependencies": { + "@angular/common": "17 - 19", + "@angular/core": "17 - 19" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz", + "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": "^18.20.0 || ^20.10.0 || >=22.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5.61.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz", + "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.4", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", + "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz", + "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.4" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/beasties": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.3.4.tgz", + "integrity": "sha512-NmzN1zN1cvGccXFyZ73335+ASXwBlVWcUPssiUDIlFdfyatHPRRufjCd5w8oPaQPvVnf9ELklaCGb1gi9FBwIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^10.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-media-query-parser": "^0.2.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", + "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001726", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", + "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz", + "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.0.tgz", + "integrity": "sha512-FgR/h5a6hzJqATDGd9YG41SeDViH+0bkHn6WNXCi5zKAZkeESeSxLySSsFLHqLEVCh0E+rITmCf0dusXWYukeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-parent": "^6.0.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2", + "tinyglobby": "^0.2.12" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.43.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.43.0.tgz", + "integrity": "sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.176", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.176.tgz", + "integrity": "sha512-2nDK9orkm7M9ZZkjO3PjbEd3VUulQLyg5T9O3enJdFvUg46Hzd4DUvTvAuEgbdHYXyFsiG4A5sO9IzToMH1cDg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", + "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", + "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "punycode": "^1.4.1", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.5.tgz", + "integrity": "sha512-V/rbdOws2gDcnCAECfPrajhuafI0WY4WumUgc8ZHwOLnvmM0doLQ+dqvVFI2qkVxQsvo6880aC9IjpyDqcwwTw==", + "dev": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", + "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.1", + "entities": "^6.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", + "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz", + "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jasmine-core": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.8.0.tgz", + "integrity": "sha512-Q9dqmpUAfptwyueW3+HqBOkSuYd9I/clZSSfN97wXE/Nr2ROFNCwIBEC1F6kb3QXS9Fcz0LjFYSDQT+BiwjuhA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-coverage/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma-coverage/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", + "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", + "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", + "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/karma/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/karma/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/karma/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.10.0.tgz", + "integrity": "sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/less": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/less/-/less-4.3.0.tgz", + "integrity": "sha512-X9RyH9fvemArzfdP8Pi3irr7lor2Ok4rOttDXBhlwDg+wKQsXOXgHWduAJE1EsF7JJx0w0bcO6BC6tCKKYnXKA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.3.0.tgz", + "integrity": "sha512-0M6+uYulvYIWs52y0LqN4+QM9TqWAohYSNTo4htE8Z7Cn3G/qQMEmktfHmyJT23k+20kU9zHH2wrfFXkxNLtVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "dev": true, + "license": "ISC", + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.3.tgz", + "integrity": "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.3.0.tgz", + "integrity": "sha512-MgJocUI6QEiSXQBFWLeyo1R7eQj8Rke5dlPxX0KFwli8/bsCxpM/KbXO5y0qmV/5llQ3wpneDWcTYxa+4vn8iQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.3.0", + "@lmdb/lmdb-darwin-x64": "3.3.0", + "@lmdb/lmdb-linux-arm": "3.3.0", + "@lmdb/lmdb-linux-arm64": "3.3.0", + "@lmdb/lmdb-linux-x64": "3.3.0", + "@lmdb/lmdb-win32-arm64": "3.3.0", + "@lmdb/lmdb-win32-x64": "3.3.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz", + "integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.1.tgz", + "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.4.tgz", + "integrity": "sha512-uaff7RG9VIC4jacFW9xzL3jc0iM32DNHe4jYVycBcjUePT/Klnfj7pqtWJt9khvDFizmjN2TlYniYmSS2LIaZg==", + "dev": true, + "license": "MIT", + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ngx-scrollbar": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/ngx-scrollbar/-/ngx-scrollbar-18.0.0.tgz", + "integrity": "sha512-+ykmY491x+nzXvnecJvZHvDz0YWuX1r7SYMxNG4RVHXm5Z68P/8kd/3ryLD6DXdNWmJawd4NGvqq2ZkUKb/g3A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/cdk": ">=19.0.0", + "@angular/common": ">=19.0.0", + "@angular/core": ">=19.0.0", + "rxjs": ">=7.0.0" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.2.0.tgz", + "integrity": "sha512-T0S1zqskVUSxcsSTkAsLc7xCycrRYmtDHadDinzocrThjyQCn5kMlEBSj6H4qDbgsIOSLmmlRIeb0lZXj+UArA==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "tinyglobby": "^0.2.12", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.1.tgz", + "integrity": "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz", + "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-packlist": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.0.tgz", + "integrity": "sha512-rht9U6nS8WOBDc53eipZNPo5qkAV4X2rhKE2Oj1DYUQ3DieXfj0mKkVmjnf3iuNdtMd8WfLdi2L6ASkD/8a+Kg==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", + "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", + "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ordered-binary": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.0.tgz", + "integrity": "sha512-IQh2aMfMIDbPjI/8a3Edr+PiOpcsB7yo8NdW7aHWVaoR/pcDldunMvnnwbk/auPGqmKeAdxtZl7MHX/QmPwhvQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pacote": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.0.0.tgz", + "integrity": "sha512-lcqexq73AMv6QNLo7SOpz0JJoaGdS3rBFgF122NZVl1bApo2mfu+XzUBU/X/XsiJu+iUmKpekRayqQYAs+PhkA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^10.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.1.0.tgz", + "integrity": "sha512-2ifK6Jb+ONoqOy5f+cYHsqvx1obHQdvIk13Jmt/5ezxP0U9p+fqd+R6O73KblGswyuzBYfetmsfK9ThMgnuPPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.1.1.tgz", + "integrity": "sha512-9rPDIPsCwOivatEZGM8+apgM7AiTDLSnpwMmLaSmdm2PeND8bFJzZLZZxyrJjLH8Xx/MpKoVaKf+vZOWALNHbw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.x" + }, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.1" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.1.tgz", + "integrity": "sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.2.tgz", + "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.7" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.40.2", + "@rollup/rollup-android-arm64": "4.40.2", + "@rollup/rollup-darwin-arm64": "4.40.2", + "@rollup/rollup-darwin-x64": "4.40.2", + "@rollup/rollup-freebsd-arm64": "4.40.2", + "@rollup/rollup-freebsd-x64": "4.40.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.40.2", + "@rollup/rollup-linux-arm-musleabihf": "4.40.2", + "@rollup/rollup-linux-arm64-gnu": "4.40.2", + "@rollup/rollup-linux-arm64-musl": "4.40.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.40.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.40.2", + "@rollup/rollup-linux-riscv64-gnu": "4.40.2", + "@rollup/rollup-linux-riscv64-musl": "4.40.2", + "@rollup/rollup-linux-s390x-gnu": "4.40.2", + "@rollup/rollup-linux-x64-gnu": "4.40.2", + "@rollup/rollup-linux-x64-musl": "4.40.2", + "@rollup/rollup-win32-arm64-msvc": "4.40.2", + "@rollup/rollup-win32-ia32-msvc": "4.40.2", + "@rollup/rollup-win32-x64-msvc": "4.40.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.89.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz", + "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.5", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz", + "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "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": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true, + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.1.0.tgz", + "integrity": "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "@sigstore/sign": "^3.1.0", + "@sigstore/tuf": "^3.1.0", + "@sigstore/verify": "^2.1.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.17.1" + } + }, + "node_modules/socket.io-adapter/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", + "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", + "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/terser": { + "version": "5.39.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.1.tgz", + "integrity": "sha512-Mm6+uad0ZuDtcV8/4uOZQDQ8RuiC5Pu+iZRedJtF7yA/27sPL7d++In/AJKpWZlU3SYMPPkVfwetn6sgZ66pUA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-dump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.3.tgz", + "integrity": "sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tuf-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.0.1.tgz", + "integrity": "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.40", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz", + "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", + "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.1.tgz", + "integrity": "sha512-OaI//3H0J7ZkR1OqlhGA8cA+Cbk/2xFOQpJOt5+s27/ta9eZwpeervh4Mxh4w0im/kdgktowaqVNR7QOrUd7Yg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack": { + "version": "5.99.8", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.8.tgz", + "integrity": "sha512-lQ3CPiSTpfOnrEGeXDwoq5hIGzSjmwD72GdfVzF7CQAI7t47rJG9eDWvcEkEn3CUQymAElVvDg3YNTlCYj+qUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@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.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.1.tgz", + "integrity": "sha512-ml/0HIj9NLpVKOMq+SuBPLHcmbG+TGIjXRHsYfZwocUBIqEvws8NnS/V9AFQ5FKP+tgn5adwVwRrTEpGL33QFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.21.2", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.7", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", + "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", + "license": "MIT" + } + } +} diff --git a/theme/packages/authguard/package.json b/theme/packages/authguard/package.json new file mode 100644 index 0000000..304b6ca --- /dev/null +++ b/theme/packages/authguard/package.json @@ -0,0 +1,46 @@ +{ + "name": "modernize", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^20.0.4", + "@angular/cdk": "^20.0.3", + "@angular/common": "^20.0.4", + "@angular/compiler": "^20.0.4", + "@angular/core": "^20.0.4", + "@angular/forms": "^20.0.4", + "@angular/material": "^20.0.3", + "@angular/platform-browser": "^20.0.4", + "@angular/platform-browser-dynamic": "^20.0.4", + "@angular/router": "^20.0.4", + "@ngx-translate/core": "^14.0.0", + "@ngx-translate/http-loader": "^7.0.0", + "angular-tabler-icons": "^3.26.0", + "ngx-scrollbar": "^18.0.0", + "rxjs": "~7.8.2", + "sass": "^1.89.2", + "tslib": "^2.8.1", + "zone.js": "~0.15.1" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^20.0.3", + "@angular/cli": "~20.0.3", + "@angular/compiler-cli": "^20.0.4", + "@types/date-fns": "^2.6.3", + "@types/jasmine": "~5.1.8", + "jasmine-core": "~5.8.0", + "karma": "~6.4.4", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.1", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.8.3" + } +} \ No newline at end of file diff --git a/theme/packages/authguard/src/app/app.component.spec.ts b/theme/packages/authguard/src/app/app.component.spec.ts new file mode 100644 index 0000000..05e3099 --- /dev/null +++ b/theme/packages/authguard/src/app/app.component.spec.ts @@ -0,0 +1,35 @@ +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + RouterTestingModule + ], + declarations: [ + AppComponent + ], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title 'Angular20'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('Angular20'); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('.content span')?.textContent).toContain('Angular20 app is running!'); + }); +}); diff --git a/theme/packages/authguard/src/app/layouts/full/full.component.html b/theme/packages/authguard/src/app/layouts/full/full.component.html new file mode 100644 index 0000000..7f9ad4e --- /dev/null +++ b/theme/packages/authguard/src/app/layouts/full/full.component.html @@ -0,0 +1,190 @@ + + + + + @if (!options.horizontal) { + +
+ + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+
+ } + + + + + @if (resView) { + + + + + @for(item of navItems; track item) { + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+ } + + + + + + + + + @if (!options.horizontal) { + + } @else { + + + } @if(options.horizontal) { + + } + +
+ + + + + +
+ +
+
+ + +
+
+
+
+ @if(options.theme === 'light') { + + logo + + } @else { + + logo + + } +
+ +
+ + + + + Apps + +
+
+ @for(appdd of apps; track appdd.img) { + + } +
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+ + +
+
+
+ + +
+

Settings

+ + + close + +
+ + +
+
\ No newline at end of file diff --git a/theme/packages/authguard/src/app/layouts/full/horizontal/header/header.component.html b/theme/packages/authguard/src/app/layouts/full/horizontal/header/header.component.html new file mode 100644 index 0000000..1f928dd --- /dev/null +++ b/theme/packages/authguard/src/app/layouts/full/horizontal/header/header.component.html @@ -0,0 +1,296 @@ + +
+
+ +
+ + + + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/authguard/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts b/theme/packages/authguard/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts new file mode 100644 index 0000000..e9119c0 --- /dev/null +++ b/theme/packages/authguard/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { Router, NavigationEnd, ActivatedRoute, Data } from '@angular/router'; +import { filter, map, mergeMap } from 'rxjs/operators'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-breadcrumb', + imports: [RouterModule, TablerIconsModule], + templateUrl: './breadcrumb.component.html', + styleUrls: [], +}) +export class AppBreadcrumbComponent { + // @Input() layout; + pageInfo: Data | any = Object.create(null); + myurl: any = this.router.url.slice(1).split('/'); + constructor( + private router: Router, + private activatedRoute: ActivatedRoute, + private titleService: Title + ) { + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .pipe(map(() => this.activatedRoute)) + .pipe( + map((route) => { + while (route.firstChild) { + route = route.firstChild; + } + return route; + }) + ) + .pipe(filter((route) => route.outlet === 'primary')) + .pipe(mergeMap((route) => route.data)) + // tslint:disable-next-line - Disables all + .subscribe((event) => { + // tslint:disable-next-line - Disables all + this.titleService.setTitle(event['title'] + ' - Angular 20'); + this.pageInfo = event; + }); + } +} diff --git a/theme/packages/authguard/src/app/layouts/full/vertical/header/header.component.html b/theme/packages/authguard/src/app/layouts/full/vertical/header/header.component.html new file mode 100644 index 0000000..a7ba13e --- /dev/null +++ b/theme/packages/authguard/src/app/layouts/full/vertical/header/header.component.html @@ -0,0 +1,300 @@ + + + + @if(showToggle) { + + } + + + @if(!showToggle) { + + } + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently + Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + @if(options.theme=='light'){ + + }@else{ + +} + + + + + + +
+
Notifications
+ + 5 new + +
+ + @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/authguard/src/assets/scss/_container.scss b/theme/packages/authguard/src/assets/scss/_container.scss new file mode 100644 index 0000000..c9a3f6a --- /dev/null +++ b/theme/packages/authguard/src/assets/scss/_container.scss @@ -0,0 +1,153 @@ +@use "variables" as *; + +*, +:after, +:before { + box-sizing: border-box; +} + +body { + font-family: $font-family; + line-height: 1.334rem; + overflow-x: hidden; + color: var(--mat-sys-on-background); +} + +.mainWrapper { + display: flex; + min-height: 100vh; + width: 100%; + flex: 1; + height: 100%; +} + +.container { + max-width: 1200px; + padding-left: 24px; + padding-right: 24px; + margin: 0 auto; + + &.full-width { + display: flex; + align-items: center; + width: 100%; + } +} + +.pageWrapper { + padding: 24px; + min-height: calc(100vh - 70px); + + margin: 0 auto; + + &.maxWidth { + max-width: $boxedWidth; + } +} + +.w-100 { + width: 100%; +} + +.h-100 { + height: 100%; +} + +.shadow-none { + box-shadow: none !important; +} + +.rounded { + border-radius: $border-radius !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 25px !important; +} + +.overflow-hidden { + overflow: hidden; +} + +.text-decoration-none { + text-decoration: none; +} + +.position-relative { + position: relative; +} + +.table-responsive { + overflow-x: auto; + + td, + mat-cell { + white-space: nowrap; + padding: 16px; + } +} + +.op-5 { + opacity: 0.5; +} + +.cursor-pointer { + cursor: pointer; +} + +.avatar-group { + img { + border: 2px solid $white; + margin-right: -5px; + + &:last-child { + margin-right: 0; + } + } +} + +a { + color: var(--mat-sys-on-background); + + &:hover { + color: $primary; + } +} + +.filter-sidebar { + width: 290px; + position: fixed; + right: -290px; + top: 0; + z-index: 10; + height: 100%; + transition: all 0.3s ease-in-out; + box-shadow: var(--mat-sys-level3); + background-color: var(--mat-sys-background); + &.open { + right: 0; + } +} + +pre { + margin: 0; + white-space: nowrap; +} + +td.hljs-ln-line.hljs-ln-numbers { + padding-right: 10px; +} + +@media (min-width: 768px) { + html .flex-sm-row { + flex-direction: row !important; + } +} + +.mat-drawer[style*="visibility: hidden"] { + display: none; +} \ No newline at end of file diff --git a/theme/packages/authguard/src/assets/scss/layouts/_header.scss b/theme/packages/authguard/src/assets/scss/layouts/_header.scss new file mode 100644 index 0000000..a6622e9 --- /dev/null +++ b/theme/packages/authguard/src/assets/scss/layouts/_header.scss @@ -0,0 +1,64 @@ +@use "../variables" as *; + +html .topbar { + position: sticky; + top: 0; + z-index: 9; + height: $header-height; + + .notification-badge{ + .mat-badge-content{ + left: 80%; + bottom: 85%; + width: 16px; + height: 16px; + } + } +} + +.topbar-dd { + min-width: 360px !important; +} + +.apps-dd { + min-width: 830px !important; + overflow: unset !important; + + .mat-mdc-menu-content { + padding: 0; + } +} + +.text-hover-primary:hover { + .hover-text { + color: $primary; + } +} + +.upgrade-bg { + position: absolute; + top: 0px; + right: 0px; + height: 100%; +} + +.object-cover { + object-fit: cover; +} + +.profile-dd { + margin-top: -5px; + margin-left: -5px; +} + +.dark-theme { + .topbar { + .mat-mdc-icon-button { + color: $dark-text-secondary !important; + } + + .mdc-button { + --mdc-text-button-label-text-color: $dark-text-secondary !important; + } + } +} \ No newline at end of file diff --git a/theme/packages/dark/angular.json b/theme/packages/dark/angular.json new file mode 100644 index 0000000..0f19c10 --- /dev/null +++ b/theme/packages/dark/angular.json @@ -0,0 +1,126 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "Modernize": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "allowedCommonJsDependencies": ["apexcharts", "bezier-easing", "chance"], + "outputPath": { + "base": "dist/Modernize" + }, + "index": "src/index.html", + "polyfills": ["zone.js"], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": [ + + "src/styles.scss", + "src/assets/scss/style.scss", + "node_modules/ngx-toastr/toastr.css", + "node_modules/angular-calendar/css/angular-calendar.css", + "node_modules/highlight.js/styles/atom-one-dark.min.css" + ], + "scripts": [], + "browser": "src/main.ts" + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "12mb", + "maximumError": "12mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "12mb", + "maximumError": "12mb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "Modernize:build:production" + }, + "development": { + "buildTarget": "Modernize:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular/build:extract-i18n", + "options": { + "buildTarget": "Modernize:build" + } + }, + "test": { + "builder": "@angular/build:karma", + "options": { + "polyfills": ["zone.js", "zone.js/testing"], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], + "scripts": [] + } + } + } + } + }, + "cli": { + "analytics": false + }, + "schematics": { + "@schematics/angular:component": { + "type": "component" + }, + "@schematics/angular:directive": { + "type": "directive" + }, + "@schematics/angular:service": { + "type": "service" + }, + "@schematics/angular:guard": { + "typeSeparator": "." + }, + "@schematics/angular:interceptor": { + "typeSeparator": "." + }, + "@schematics/angular:module": { + "typeSeparator": "." + }, + "@schematics/angular:pipe": { + "typeSeparator": "." + }, + "@schematics/angular:resolver": { + "typeSeparator": "." + } + } +} diff --git a/theme/packages/dark/package.json b/theme/packages/dark/package.json new file mode 100644 index 0000000..51d6f74 --- /dev/null +++ b/theme/packages/dark/package.json @@ -0,0 +1,62 @@ +{ + "name": "modernize", + "version": "3.1.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^20.0.4", + "@angular/cdk": "^20.0.3", + "@angular/common": "^20.0.4", + "@angular/compiler": "^20.0.4", + "@angular/core": "^20.0.4", + "@angular/forms": "^20.0.4", + "@angular/material": "^20.0.3", + "@angular/platform-browser": "^20.0.4", + "@angular/platform-browser-dynamic": "^20.0.4", + "@angular/router": "^20.0.4", + "@ng-matero/extensions": "^20.1.0", + "@ngx-translate/core": "^16.0.4", + "@ngx-translate/http-loader": "^16.0.1", + "angular-calendar": "^0.31.1", + "angular-tabler-icons": "^3.26.0", + "apexcharts": "^4.7.0", + "chance": "^1.1.13", + "date-fns": "^4.1.0", + "highlight.js": "^11.11.1", + "ng-apexcharts": "^1.16.0", + "ng2-search-filter": "^0.5.1", + "ngx-dropzone": "^3.1.0", + "ngx-editor": "^19.0.0-beta.1", + "ngx-highlightjs": "^14.0.1", + "ngx-owl-carousel-o": "^20.0.0", + "ngx-pagination": "^6.0.3", + "ngx-permissions": "^19.0.0", + "ngx-scrollbar": "^18.0.0", + "ngx-toastr": "^19.0.0", + "rxjs": "~7.8.2", + "sass": "^1.89.2", + "tslib": "^2.8.1", + "zone.js": "~0.15.1" + }, + "devDependencies": { + "@angular/build": "^20.0.3", + "@angular/cli": "~20.0.3", + "@angular/compiler-cli": "^20.0.4", + "@types/chance": "^1.1.6", + "@types/date-fns": "^2.6.3", + "@types/jasmine": "~5.1.8", + "jasmine-core": "~5.8.0", + "karma": "~6.4.4", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.1", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.8.3" + } +} diff --git a/theme/packages/dark/src/app/app.routes.ts b/theme/packages/dark/src/app/app.routes.ts new file mode 100644 index 0000000..f1bf19f --- /dev/null +++ b/theme/packages/dark/src/app/app.routes.ts @@ -0,0 +1,107 @@ +import { Routes } from '@angular/router'; +import { BlankComponent } from './layouts/blank/blank.component'; +import { FullComponent } from './layouts/full/full.component'; + +export const routes: Routes = [ + { + path: '', + component: FullComponent, + children: [ + { + path: '', + redirectTo: '/dashboards/dashboard1', + pathMatch: 'full', + }, + { + path: 'starter', + loadChildren: () => + import('./pages/pages.routes').then((m) => m.PagesRoutes), + }, + { + path: 'dashboards', + loadChildren: () => + import('./pages/dashboards/dashboards.routes').then( + (m) => m.DashboardsRoutes + ), + }, + + { + path: 'forms', + loadChildren: () => + import('./pages/forms/forms.routes').then((m) => m.FormsRoutes), + }, + { + path: 'charts', + loadChildren: () => + import('./pages/charts/charts.routes').then((m) => m.ChartsRoutes), + }, + { + path: 'apps', + loadChildren: () => + import('./pages/apps/apps.routes').then((m) => m.AppsRoutes), + }, + { + path: 'widgets', + loadChildren: () => + import('./pages/widgets/widgets.routes').then((m) => m.WidgetsRoutes), + }, + { + path: 'tables', + loadChildren: () => + import('./pages/tables/tables.routes').then((m) => m.TablesRoutes), + }, + { + path: 'datatable', + loadChildren: () => + import('./pages/datatable/datatable.routes').then( + (m) => m.DatatablesRoutes + ), + }, + { + path: 'theme-pages', + loadChildren: () => + import('./pages/theme-pages/theme-pages.routes').then( + (m) => m.ThemePagesRoutes + ), + }, + { + path: 'ui-components', + loadChildren: () => + import('./pages/ui-components/ui-components.routes').then( + (m) => m.UiComponentsRoutes + ), + }, + ], + }, + { + path: '', + component: BlankComponent, + children: [ + { + path: 'authentication', + loadChildren: () => + import('./pages/authentication/authentication.routes').then( + (m) => m.AuthenticationRoutes + ), + }, + { + path: 'landingpage', + loadChildren: () => + import('./pages/theme-pages/landingpage/landingpage.routes').then( + (m) => m.LandingPageRoutes + ), + }, + { + path: 'front-pages', + loadChildren: () => + import('./pages/front-pages/front-pages.routes').then( + (m) => m.FrontPagesRoutes + ), + }, + ], + }, + { + path: '**', + redirectTo: 'authentication/error', + }, +]; diff --git a/theme/packages/dark/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html b/theme/packages/dark/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html new file mode 100644 index 0000000..fa78891 --- /dev/null +++ b/theme/packages/dark/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html @@ -0,0 +1,55 @@ + + + Yearly Breakup + + +
+
+

$36,358

+
+ +
+9%
+
last year
+
+ +
+
+ +
2025
+
+
+ +
2024
+
+
+
+
+ + + + +
+
+
+
diff --git a/theme/packages/dark/src/app/config.ts b/theme/packages/dark/src/app/config.ts new file mode 100644 index 0000000..5035ec1 --- /dev/null +++ b/theme/packages/dark/src/app/config.ts @@ -0,0 +1,25 @@ +export interface AppSettings { + dir: 'ltr' | 'rtl'; + theme: string; + sidenavOpened: boolean; + sidenavCollapsed: boolean; + boxed: boolean; + horizontal: boolean; + activeTheme: string; + language: string; + cardBorder: boolean; + navPos: 'side' | 'top'; +} + +export const defaults: AppSettings = { + dir: 'ltr', + theme: 'dark', + sidenavOpened: false, + sidenavCollapsed: false, + boxed: true, + horizontal: false, + cardBorder: false, + activeTheme: 'blue_theme', + language: 'en-us', + navPos: 'side', +}; \ No newline at end of file diff --git a/theme/packages/dark/src/app/layouts/full/full.component.html b/theme/packages/dark/src/app/layouts/full/full.component.html new file mode 100644 index 0000000..2ffaeb5 --- /dev/null +++ b/theme/packages/dark/src/app/layouts/full/full.component.html @@ -0,0 +1,197 @@ + + + + + + @if (!options.horizontal) { + +
+ + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+
+ } + + + + + @if (resView) { + + + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+ } + + + + + + + + + @if (!options.horizontal) { + + } @else { + + + } @if(options.horizontal) { + + } + +
+ + + + + +
+ +
+
+ + +
+
+
+
+ @if(options.theme === 'light') { + + logo + + } @else { + + logo + + } +
+ +
+ + + + + Apps + +
+
+ @for(appdd of apps; track appdd.img) { + + } +
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+ + +
+
+
+ + +
+

Settings

+ +
+ + + +
+
+
\ No newline at end of file diff --git a/theme/packages/dark/src/app/layouts/full/full.component.ts b/theme/packages/dark/src/app/layouts/full/full.component.ts new file mode 100644 index 0000000..459faac --- /dev/null +++ b/theme/packages/dark/src/app/layouts/full/full.component.ts @@ -0,0 +1,284 @@ +import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout'; +import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { MatSidenav, MatSidenavContent } from '@angular/material/sidenav'; +import { CoreService } from 'src/app/services/core.service'; +import { AppSettings } from 'src/app/config'; +import { filter } from 'rxjs/operators'; +import { NavigationEnd, Router } from '@angular/router'; +import { navItems } from './vertical/sidebar/sidebar-data'; +import { NavService } from '../../services/nav.service'; +import { AppNavItemComponent } from './vertical/sidebar/nav-item/nav-item.component'; +import { RouterModule } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { SidebarComponent } from './vertical/sidebar/sidebar.component'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { HeaderComponent } from './vertical/header/header.component'; +import { AppHorizontalHeaderComponent } from './horizontal/header/header.component'; +import { AppHorizontalSidebarComponent } from './horizontal/sidebar/sidebar.component'; +import { AppBreadcrumbComponent } from './shared/breadcrumb/breadcrumb.component'; +import { CustomizerComponent } from './shared/customizer/customizer.component'; + +const MOBILE_VIEW = 'screen and (max-width: 768px)'; +const TABLET_VIEW = 'screen and (min-width: 769px) and (max-width: 1024px)'; +const MONITOR_VIEW = 'screen and (min-width: 1024px)'; +const BELOWMONITOR = 'screen and (max-width: 1023px)'; + +// for mobile app sidebar +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +@Component({ + selector: 'app-full', + imports: [ + RouterModule, + AppNavItemComponent, + MaterialModule, + CommonModule, + SidebarComponent, + NgScrollbarModule, + TablerIconsModule, + HeaderComponent, + AppHorizontalHeaderComponent, + AppHorizontalSidebarComponent, + AppBreadcrumbComponent, + CustomizerComponent, + ], + templateUrl: './full.component.html', + + encapsulation: ViewEncapsulation.None +}) +export class FullComponent implements OnInit { + navItems = navItems; + + + + @ViewChild('leftsidenav') + public sidenav: MatSidenav; + resView = false; + @ViewChild('content', { static: true }) content!: MatSidenavContent; + //get options from service + options = this.settings.getOptions(); + private layoutChangesSubscription = Subscription.EMPTY; + private isMobileScreen = false; + private isContentWidthFixed = true; + private isCollapsedWidthFixed = false; + private htmlElement!: HTMLHtmlElement; + + get isOver(): boolean { + return this.isMobileScreen; + } + + get isTablet(): boolean { + return this.resView; + } + + // for mobile app sidebar + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/apps/chat', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'Todo App', + subtitle: 'Completed task', + link: '/apps/todo', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/apps/invoice', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/apps/calendar', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/apps/contacts', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/apps/tickets', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/apps/email/inbox', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Courses', + subtitle: 'Create new course', + link: '/apps/courses', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/theme-pages/pricing', + }, + { + id: 2, + title: 'Authentication Design', + link: '/authentication/login', + }, + { + id: 3, + title: 'Register Now', + link: '/authentication/side-register', + }, + { + id: 4, + title: '404 Error Page', + link: '/authentication/error', + }, + { + id: 5, + title: 'Notes App', + link: '/apps/notes', + }, + { + id: 6, + title: 'Employee App', + link: '/apps/employee', + }, + { + id: 7, + title: 'Todo Application', + link: '/apps/todo', + }, + { + id: 8, + title: 'Treeview', + link: '/theme-pages/treeview', + }, + ]; + + constructor( + private settings: CoreService, + private mediaMatcher: MediaMatcher, + private router: Router, + private breakpointObserver: BreakpointObserver, + private navService: NavService, private cdr: ChangeDetectorRef + ) { + this.htmlElement = document.querySelector('html')!; + this.layoutChangesSubscription = this.breakpointObserver + .observe([MOBILE_VIEW, TABLET_VIEW, MONITOR_VIEW, BELOWMONITOR]) + .subscribe((state) => { + // SidenavOpened must be reset true when layout changes + this.options.sidenavOpened = true; + this.isMobileScreen = state.breakpoints[BELOWMONITOR]; + if (this.options.sidenavCollapsed == false) { + this.options.sidenavCollapsed = state.breakpoints[TABLET_VIEW]; + } + this.isContentWidthFixed = state.breakpoints[MONITOR_VIEW]; + this.resView = state.breakpoints[BELOWMONITOR]; + }); + + // Initialize project theme with options + this.receiveOptions(this.options); + + // This is for scroll to top + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .subscribe((e) => { + this.content.scrollTo({ top: 0 }); + }); + } + + isFilterNavOpen = false; + + toggleFilterNav() { + this.isFilterNavOpen = !this.isFilterNavOpen; + console.log('Sidebar open:', this.isFilterNavOpen); + this.cdr.detectChanges(); // Ensures Angular updates the view + } + + ngOnInit(): void {} + + ngOnDestroy() { + this.layoutChangesSubscription.unsubscribe(); + } + + toggleCollapsed() { + this.isContentWidthFixed = false; + this.options.sidenavCollapsed = !this.options.sidenavCollapsed; + this.resetCollapsedState(); + } + + resetCollapsedState(timer = 400) { + setTimeout(() => this.settings.setOptions(this.options), timer); + } + + onSidenavClosedStart() { + this.isContentWidthFixed = false; + } + + onSidenavOpenedChange(isOpened: boolean) { + this.isCollapsedWidthFixed = !this.isOver; + this.options.sidenavOpened = isOpened; + this.settings.setOptions(this.options); + } + + receiveOptions(options: AppSettings): void { + this.toggleDarkTheme(options); + this.toggleColorsTheme(options); + } + + toggleDarkTheme(options: AppSettings) { + if (options.theme === 'dark') { + this.htmlElement.classList.add('dark-theme'); + this.htmlElement.classList.remove('light-theme'); + } else { + this.htmlElement.classList.remove('dark-theme'); + this.htmlElement.classList.add('light-theme'); + } + } + + toggleColorsTheme(options: AppSettings) { + // Remove any existing theme class dynamically + this.htmlElement.classList.forEach((className) => { + if (className.endsWith('_theme')) { + this.htmlElement.classList.remove(className); + } + }); + + // Add the selected theme class + this.htmlElement.classList.add(options.activeTheme); + } +} diff --git a/theme/packages/dark/src/app/layouts/full/horizontal/header/header.component.html b/theme/packages/dark/src/app/layouts/full/horizontal/header/header.component.html new file mode 100644 index 0000000..f076a2c --- /dev/null +++ b/theme/packages/dark/src/app/layouts/full/horizontal/header/header.component.html @@ -0,0 +1,296 @@ + +
+
+ +
+ + + + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/dark/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts b/theme/packages/dark/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts new file mode 100644 index 0000000..3bdf202 --- /dev/null +++ b/theme/packages/dark/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts @@ -0,0 +1,633 @@ +import { NavItem } from '../../vertical/sidebar/nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Dashboards', + iconName: 'home', + route: 'dashboards', + children: [ + { + displayName: 'Analytical', + iconName: 'point', + route: 'dashboards/dashboard1', + }, + { + displayName: 'eCommerce', + iconName: 'point', + route: 'dashboards/dashboard2', + }, + ], + }, + { + displayName: 'Frontend pages', + iconName: 'app-window', + route: 'front-pages', + children: [ + { + displayName: 'Home Page', + iconName: 'point', + route: 'front-pages/homepage', + } , + { + displayName: 'About Us', + iconName: 'point', + route: 'front-pages/about', + } , + { + displayName: 'Blog', + iconName: 'point', + route: 'front-pages/blog', + } , + { + displayName: 'Blog Details', + iconName: 'point', + route: 'front-pages/blog-details', + } , + { + displayName: 'Portfolio', + iconName: 'point', + route: 'front-pages/portfolio', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'front-pages/pricing', + }, + { + displayName: 'Contact', + iconName: 'point', + route: 'front-pages/contact', + } + ] + }, + { + displayName: 'Apps', + iconName: 'apps', + route: 'apps', + ddType: '', + children: [ + { + displayName: 'Chat', + iconName: 'point', + route: 'apps/chat', + }, + { + displayName: 'Calendar', + iconName: 'point', + route: 'apps/calendar', + }, + { + displayName: 'Email', + iconName: 'point', + route: 'apps/email/inbox', + }, + { + displayName: 'Contacts', + iconName: 'point', + route: 'apps/contacts', + }, + { + displayName: 'Contact List', + iconName: 'point', + route: 'apps/contact-list', + }, + { + displayName: 'Courses', + iconName: 'point', + route: 'apps/courses', + }, + { + displayName: 'Employee', + iconName: 'point', + route: 'apps/employee', + }, + { + displayName: 'Notes', + iconName: 'point', + route: 'apps/notes', + }, + { + displayName: 'Tickets', + iconName: 'point', + route: 'apps/tickets', + }, + { + displayName: 'Invoice', + iconName: 'point', + route: 'apps/invoice', + }, + { + displayName: 'ToDo', + iconName: 'point', + route: 'apps/todo', + }, + { + displayName: 'Kanban', + iconName: 'point', + route: 'apps/kanban', + }, + { + displayName: 'Blog', + iconName: 'point', + route: 'apps/blog', + children: [ + { + displayName: 'Post', + iconName: 'point', + route: 'apps/blog/post', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + }, + ], + }, + { + displayName: 'User Profile', + iconName: 'point', + route: 'apps/profile-details', + children: [ + { + displayName: 'Profile', + iconName: 'point', + route: 'apps/profile-details/profile', + }, + { + displayName: 'Followers', + iconName: 'point', + route: 'apps/profile-details/followers', + }, + { + displayName: 'Friends', + iconName: 'point', + route: 'apps/profile-details/friends', + }, + { + displayName: 'Gellary', + iconName: 'point', + route: 'apps/profile-details/gallery', + }, + ], + }, + { + displayName: 'Ecommerce', + iconName: 'point', + route: 'apps/product', + children: [ + { + displayName: 'Product List', + iconName: 'point', + route: 'apps/product/product-list', + }, + { + displayName: 'Add Product', + iconName: 'point', + route: 'apps/product/add-product', + }, + { + displayName: 'Edit Product', + iconName: 'point', + route: 'apps/product/edit-product', + }, + { + displayName: 'Shop', + iconName: 'point', + route: 'apps/product/shop', + }, + ], + }, + ], + }, + { + displayName: 'Ui', + iconName: 'components', + route: 'ui-components', + ddType: '', + children: [ + { + displayName: 'Badge', + iconName: 'point', + route: 'ui-components/badge', + }, + { + displayName: 'Expansion Panel', + iconName: 'point', + route: 'ui-components/expansion', + }, + { + displayName: 'Chips', + iconName: 'point', + route: 'ui-components/chips', + }, + { + displayName: 'Dialog', + iconName: 'point', + route: 'ui-components/dialog', + }, + { + displayName: 'Lists', + iconName: 'point', + route: 'ui-components/lists', + }, + { + displayName: 'Divider', + iconName: 'point', + route: 'ui-components/divider', + }, + { + displayName: 'Menu', + iconName: 'point', + route: 'ui-components/menu', + }, + { + displayName: 'Paginator', + iconName: 'point', + route: 'ui-components/paginator', + }, + { + displayName: 'Progress Bar', + iconName: 'point', + route: 'ui-components/progress', + }, + { + displayName: 'Progress Spinner', + iconName: 'point', + route: 'ui-components/progress-spinner', + }, + { + displayName: 'Ripples', + iconName: 'point', + route: 'ui-components/ripples', + }, + { + displayName: 'Slide Toggle', + iconName: 'point', + route: 'ui-components/slide-toggle', + }, + { + displayName: 'Slider', + iconName: 'point', + route: 'ui-components/slider', + }, + { + displayName: 'Snackbar', + iconName: 'point', + route: 'ui-components/snackbar', + }, + { + displayName: 'Tabs', + iconName: 'point', + route: 'ui-components/tabs', + }, + { + displayName: 'Toolbar', + iconName: 'point', + route: 'ui-components/toolbar', + }, + { + displayName: 'Tooltips', + iconName: 'point', + route: 'ui-components/tooltips', + }, + ], + }, + { + displayName: 'Pages', + iconName: 'clipboard', + route: 'theme-pages', + ddType: '', + children: [ + { + displayName: 'Treeview', + iconName: 'point', + route: 'theme-pages/treeview', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'theme-pages/pricing', + }, + { + displayName: 'Account Setting', + iconName: 'point', + route: 'theme-pages/account-setting', + }, + { + displayName: 'FAQ', + iconName: 'point', + route: 'theme-pages/faq', + }, + { + displayName: 'Landingpage', + iconName: 'point', + route: 'landingpage', + }, + { + displayName: 'Widgets', + iconName: 'point', + route: 'widgets', + children: [ + { + displayName: 'Cards', + iconName: 'point', + route: 'widgets/cards', + }, + { + displayName: 'Banners', + iconName: 'point', + route: 'widgets/banners', + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'widgets/charts', + }, + ], + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'charts', + children: [ + { + displayName: 'Line', + iconName: 'point', + route: '/charts/line', + }, + { + displayName: 'Gredient', + iconName: 'point', + route: '/charts/gredient', + }, + { + displayName: 'Area', + iconName: 'point', + route: '/charts/area', + }, + { + displayName: 'Candlestick', + iconName: 'point', + route: '/charts/candlestick', + }, + { + displayName: 'Column', + iconName: 'point', + route: '/charts/column', + }, + { + displayName: 'Doughnut & Pie', + iconName: 'point', + route: '/charts/doughnut-pie', + }, + { + displayName: 'Radialbar & Radar', + iconName: 'point', + route: '/charts/radial-radar', + }, + ], + }, + { + displayName: 'Auth', + iconName: 'point', + route: '/', + children: [ + { + displayName: 'Login', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/login', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-login', + }, + ], + }, + { + displayName: 'Register', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/side-register', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-register', + }, + ], + }, + { + displayName: 'Forgot Password', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Side Forgot Password', + iconName: 'point', + route: '/authentication/side-forgot-pwd', + }, + { + displayName: 'Boxed Forgot Password', + iconName: 'point', + route: '/authentication/boxed-forgot-pwd', + }, + ], + }, + { + displayName: 'Two Steps', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Side Two Steps', + iconName: 'point', + route: '/authentication/side-two-steps', + }, + { + displayName: 'Boxed Two Steps', + iconName: 'point', + route: '/authentication/boxed-two-steps', + }, + ], + }, + { + displayName: 'Error', + iconName: 'point', + route: '/authentication/error', + }, + { + displayName: 'Maintenance', + iconName: 'point', + route: '/authentication/maintenance', + }, + ], + }, + ], + }, + { + displayName: 'Forms', + iconName: 'file-description', + route: 'forms', + ddType: '', + children: [ + { + displayName: 'Form elements', + iconName: 'point', + route: 'forms/forms-elements', + children: [ + { + displayName: 'Autocomplete', + iconName: 'point', + route: 'forms/forms-elements/autocomplete', + }, + { + displayName: 'Button', + iconName: 'point', + route: 'forms/forms-elements/button', + }, + { + displayName: 'Checkbox', + iconName: 'point', + route: 'forms/forms-elements/checkbox', + }, + { + displayName: 'Radio', + iconName: 'point', + route: 'forms/forms-elements/radio', + }, + { + displayName: 'Datepicker', + iconName: 'point', + route: 'forms/forms-elements/datepicker', + }, + ], + }, + { + displayName: 'Form Layouts', + iconName: 'point', + route: '/forms/form-layouts', + }, + { + displayName: 'Form Horizontal', + iconName: 'point', + route: '/forms/form-horizontal', + }, + { + displayName: 'Form Vertical', + iconName: 'point', + route: '/forms/form-vertical', + }, + { + displayName: 'Form Wizard', + iconName: 'point', + route: '/forms/form-wizard', + }, + { + displayName: 'Toastr', + iconName: 'point', + route: '/forms/form-toastr', + }, + { + displayName: 'Editor', + iconName: 'point', + route: '/forms/form-editor', + }, + ], + }, + { + displayName: 'Tables', + iconName: 'layout', + route: 'tables', + ddType: '', + children: [ + { + displayName: 'Basic Table', + iconName: 'point', + route: 'tables/basic-table', + }, + { + displayName: 'Dynamic Table', + iconName: 'point', + route: 'tables/dynamic-table', + }, + { + displayName: 'Expand Table', + iconName: 'point', + route: 'tables/expand-table', + }, + { + displayName: 'Filterable Table', + iconName: 'point', + route: 'tables/filterable-table', + }, + { + displayName: 'Footer Row Table', + iconName: 'point', + route: 'tables/footer-row-table', + }, + { + displayName: 'HTTP Table', + iconName: 'point', + route: 'tables/http-table', + }, + { + displayName: 'Mix Table', + iconName: 'point', + route: 'tables/mix-table', + }, + { + displayName: 'Multi Header Footer', + iconName: 'point', + route: 'tables/multi-header-footer-table', + }, + { + displayName: 'Pagination Table', + iconName: 'point', + route: 'tables/pagination-table', + }, + { + displayName: 'Row Context Table', + iconName: 'point', + route: 'tables/row-context-table', + }, + { + displayName: 'Selection Table', + iconName: 'point', + route: 'tables/selection-table', + }, + { + displayName: 'Sortable Table', + iconName: 'point', + route: 'tables/sortable-table', + }, + { + displayName: 'Sticky Column', + iconName: 'point', + route: 'tables/sticky-column-table', + }, + { + displayName: 'Sticky Header Footer', + iconName: 'point', + route: 'tables/sticky-header-footer-table', + }, + { + displayName: 'Data table', + iconName: 'point', + route: '/datatable/kichen-sink', + }, + ], + }, +]; diff --git a/theme/packages/dark/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts b/theme/packages/dark/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts new file mode 100644 index 0000000..f0e13f5 --- /dev/null +++ b/theme/packages/dark/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts @@ -0,0 +1,48 @@ +import { + Component, + OnInit, + Input, + ChangeDetectorRef, + OnChanges, +} from '@angular/core'; +import { navItems } from './sidebar-data'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../services/nav.service'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { AppHorizontalNavItemComponent } from './nav-item/nav-item.component'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-horizontal-sidebar', + imports: [AppHorizontalNavItemComponent, CommonModule], + templateUrl: './sidebar.component.html', +}) +export class AppHorizontalSidebarComponent implements OnInit { + navItems = navItems; + parentActive = ''; + + mobileQuery: MediaQueryList; + private _mobileQueryListener: () => void; + + constructor( + public navService: NavService, + public router: Router, + media: MediaMatcher, + changeDetectorRef: ChangeDetectorRef + ) { + this.mobileQuery = media.matchMedia('(min-width: 1100px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + this.router.events.subscribe( + () => (this.parentActive = this.router.url.split('/')[1]) + ); + } + + ngOnInit(): void { + this.parentActive = this.router.url.split('/')[1]; + + this.router.events.subscribe(() => { + this.parentActive = this.router.url.split('/')[1]; + }); + } +} diff --git a/theme/packages/dark/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts b/theme/packages/dark/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts new file mode 100644 index 0000000..3cf2292 --- /dev/null +++ b/theme/packages/dark/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { Router, NavigationEnd, ActivatedRoute, Data } from '@angular/router'; +import { filter, map, mergeMap } from 'rxjs/operators'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-breadcrumb', + imports: [RouterModule, TablerIconsModule], + templateUrl: './breadcrumb.component.html', + styleUrls: [] +}) +export class AppBreadcrumbComponent { + // @Input() layout; + pageInfo: Data | any = Object.create(null); + myurl: any = this.router.url.slice(1).split('/'); + constructor( + private router: Router, + private activatedRoute: ActivatedRoute, + private titleService: Title + ) { + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .pipe(map(() => this.activatedRoute)) + .pipe( + map((route) => { + while (route.firstChild) { + route = route.firstChild; + } + return route; + }) + ) + .pipe(filter((route) => route.outlet === 'primary')) + .pipe(mergeMap((route) => route.data)) + // tslint:disable-next-line - Disables all + .subscribe((event) => { + // tslint:disable-next-line - Disables all + this.titleService.setTitle(event['title'] + ' - Angular 20'); + this.pageInfo = event; + }); + } +} diff --git a/theme/packages/dark/src/app/layouts/full/vertical/header/header.component.html b/theme/packages/dark/src/app/layouts/full/vertical/header/header.component.html new file mode 100644 index 0000000..3949a30 --- /dev/null +++ b/theme/packages/dark/src/app/layouts/full/vertical/header/header.component.html @@ -0,0 +1,301 @@ + + + + @if(showToggle) { + + } + + + @if(!showToggle) { + + } + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently + Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ + @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/dark/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts b/theme/packages/dark/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts new file mode 100644 index 0000000..3782536 --- /dev/null +++ b/theme/packages/dark/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts @@ -0,0 +1,103 @@ +import { + Component, + HostBinding, + Input, + OnInit, + OnChanges, + Output, + EventEmitter, +} from '@angular/core'; +import { NavItem } from './nav-item'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../../services/nav.service'; +import { + animate, + state, + style, + transition, + trigger, +} from '@angular/animations'; +import { TranslateModule } from '@ngx-translate/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-nav-item', + imports: [TranslateModule, TablerIconsModule, MaterialModule, CommonModule], + templateUrl: './nav-item.component.html', + styleUrls: [], + animations: [ + trigger('indicatorRotate', [ + state('collapsed', style({ transform: 'rotate(0deg)' })), + state('expanded', style({ transform: 'rotate(180deg)' })), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4,0.0,0.2,1)')), + ]), + ] +}) +export class AppNavItemComponent implements OnChanges { + @Output() toggleMobileLink: any = new EventEmitter(); + @Output() notify: EventEmitter = new EventEmitter(); + + expanded: any = false; + disabled: any = false; + twoLines: any = false; + @HostBinding('attr.aria-expanded') ariaExpanded = this.expanded; + @Input() item: NavItem | any; + @Input() depth: any; + + constructor(public navService: NavService, public router: Router) { + if (this.depth === undefined) { + this.depth = 0; + } + } + + ngOnChanges() { + const url = this.navService.currentUrl(); + if (this.item.route && url) { + this.expanded = url.indexOf(`/${this.item.route}`) === 0; + this.ariaExpanded = this.expanded; + } + } + + onItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + this.router.navigate([item.route]); + + } + if (item.children && item.children.length) { + this.expanded = !this.expanded; + } + //scroll + window.scroll({ + top: 0, + left: 0, + behavior: 'smooth', + }); + if (!this.expanded) { + if (window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + onSubItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + if (this.expanded && window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + isDirectlyActive(item: NavItem): boolean { + return !!item.route && this.router.isActive(item.route, true); + } + + isChildActive(item: NavItem): boolean { + if (!item.children) return false; + return item.children.some( + (child) => this.isDirectlyActive(child) || this.isChildActive(child) + ); + } + +} diff --git a/theme/packages/dark/src/app/layouts/full/vertical/sidebar/sidebar-data.ts b/theme/packages/dark/src/app/layouts/full/vertical/sidebar/sidebar-data.ts new file mode 100644 index 0000000..e52b956 --- /dev/null +++ b/theme/packages/dark/src/app/layouts/full/vertical/sidebar/sidebar-data.ts @@ -0,0 +1,705 @@ +import { NavItem } from './nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Analytical', + iconName: 'aperture', + route: '/dashboards/dashboard1', + }, + { + displayName: 'eCommerce', + iconName: 'shopping-cart', + route: '/dashboards/dashboard2', + }, + { + displayName: 'Frontend pages', + iconName: 'app-window', + route: 'front-pages', + children: [ + { + displayName: 'Home Page', + iconName: 'point', + route: 'front-pages/homepage', + } , + { + displayName: 'About Us', + iconName: 'point', + route: 'front-pages/about', + } , + { + displayName: 'Blog', + iconName: 'point', + route: 'front-pages/blog', + } , + { + displayName: 'Blog Details', + iconName: 'point', + route: 'front-pages/blog-details', + } , + { + displayName: 'Portfolio', + iconName: 'point', + route: 'front-pages/portfolio', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'front-pages/pricing', + }, + { + displayName: 'Contact', + iconName: 'point', + route: 'front-pages/contact', + } + ] + }, + { + navCap: 'Apps', + }, + { + displayName: 'Chat', + iconName: 'message-2', + route: 'apps/chat', + }, + { + displayName: 'Calendar', + iconName: 'calendar-event', + route: 'apps/calendar', + }, + { + displayName: 'Email', + iconName: 'mail', + route: 'apps/email/inbox', + }, + { + displayName: 'Kanban', + iconName: 'checklist', + route: 'apps/kanban', + }, + { + displayName: 'User Profile', + iconName: 'user-circle', + route: 'apps/profile-details', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'New', + children: [ + { + displayName: 'Profile', + iconName: 'point', + route: 'apps/profile-details/profile', + }, + { + displayName: 'Followers', + iconName: 'point', + route: 'apps/profile-details/followers', + }, + { + displayName: 'Friends', + iconName: 'point', + route: 'apps/profile-details/friends', + }, + { + displayName: 'Gellary', + iconName: 'point', + route: 'apps/profile-details/gallery', + }, + ], + }, + { + displayName: 'Ecommerce', + iconName: 'basket', + route: 'apps/product', + chip: true, + chipClass: 'border-error text-error', + chipContent: 'New', + children: [ + { + displayName: 'Product List', + iconName: 'point', + route: 'apps/product/product-list', + }, + { + displayName: 'Add Product', + iconName: 'point', + route: 'apps/product/add-product', + }, + { + displayName: 'Edit Product', + iconName: 'point', + route: 'apps/product/edit-product', + }, + { + displayName: 'Shop', + iconName: 'point', + route: 'apps/product/shop', + }, + ], + }, + { + displayName: 'Contacts', + iconName: 'phone', + route: 'apps/contacts', + }, + { + displayName: 'Courses', + iconName: 'certificate', + route: 'apps/courses', + }, + { + displayName: 'Employee', + iconName: 'brand-ctemplar', + route: 'apps/employee', + }, + { + displayName: 'Notes', + iconName: 'note', + route: 'apps/notes', + }, + { + displayName: 'Tickets', + iconName: 'ticket', + route: 'apps/tickets', + }, + { + displayName: 'Contact List', + iconName: 'phone', + route: 'apps/contact-list', + }, + { + displayName: 'Invoice', + iconName: 'file-invoice', + route: 'apps/invoice', + children: [ + { + displayName: 'List', + iconName: 'point', + route: 'apps/invoice/list', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/invoice/viewInvoice/101', + }, + { + displayName: 'Create', + iconName: 'point', + route: 'apps/invoice/addInvoice', + }, + { + displayName: 'Edit', + iconName: 'point', + route: 'apps/invoice/editinvoice/101', + }, + ], + }, + { + displayName: 'ToDo', + iconName: 'edit', + route: 'apps/todo', + }, + { + displayName: 'Blog', + iconName: 'chart-donut-3', + route: 'apps/blog', + children: [ + { + displayName: 'Post', + iconName: 'point', + route: 'apps/blog/post', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + }, + ], + }, + { + navCap: 'Pages', + }, + { + displayName: 'Roll Base Access', + iconName: 'lock-access', + route: 'apps/permission', + }, + { + displayName: 'Treeview', + iconName: 'git-merge', + route: 'theme-pages/treeview', + }, + { + displayName: 'Pricing', + iconName: 'currency-dollar', + route: 'theme-pages/pricing', + }, + { + displayName: 'Account Setting', + iconName: 'user-circle', + route: 'theme-pages/account-setting', + }, + { + displayName: 'FAQ', + iconName: 'help', + route: 'theme-pages/faq', + }, + { + displayName: 'Landingpage', + iconName: 'app-window', + route: 'landingpage', + }, + { + displayName: 'Widgets', + iconName: 'layout', + route: 'widgets', + children: [ + { + displayName: 'Cards', + iconName: 'point', + route: 'widgets/cards', + }, + { + displayName: 'Banners', + iconName: 'point', + route: 'widgets/banners', + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'widgets/charts', + }, + ], + }, + { + navCap: 'Forms', + }, + { + displayName: 'Form elements', + iconName: 'apps', + route: 'forms/forms-elements', + children: [ + { + displayName: 'Autocomplete', + iconName: 'point', + route: 'forms/forms-elements/autocomplete', + }, + { + displayName: 'Button', + iconName: 'point', + route: 'forms/forms-elements/button', + }, + { + displayName: 'Checkbox', + iconName: 'point', + route: 'forms/forms-elements/checkbox', + }, + { + displayName: 'Radio', + iconName: 'point', + route: 'forms/forms-elements/radio', + }, + { + displayName: 'Datepicker', + iconName: 'point', + route: 'forms/forms-elements/datepicker', + }, + ], + }, + { + displayName: 'Form Layouts', + iconName: 'file-description', + route: '/forms/form-layouts', + }, + { + displayName: 'Form Horizontal', + iconName: 'box-align-bottom', + route: '/forms/form-horizontal', + }, + { + displayName: 'Form Vertical', + iconName: 'box-align-left', + route: '/forms/form-vertical', + }, + { + displayName: 'Form Wizard', + iconName: 'files', + route: '/forms/form-wizard', + }, + { + displayName: 'Toastr', + iconName: 'notification', + route: '/forms/form-toastr', + }, + { + displayName: 'Editor', + iconName: 'edit', + route: '/forms/form-editor', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'New', + }, + { + navCap: 'Tables', + }, + { + displayName: 'Tables', + iconName: 'layout', + route: 'tables', + children: [ + { + displayName: 'Basic Table', + iconName: 'point', + route: 'tables/basic-table', + }, + { + displayName: 'Dynamic Table', + iconName: 'point', + route: 'tables/dynamic-table', + }, + { + displayName: 'Expand Table', + iconName: 'point', + route: 'tables/expand-table', + }, + { + displayName: 'Filterable Table', + iconName: 'point', + route: 'tables/filterable-table', + }, + { + displayName: 'Footer Row Table', + iconName: 'point', + route: 'tables/footer-row-table', + }, + { + displayName: 'HTTP Table', + iconName: 'point', + route: 'tables/http-table', + }, + { + displayName: 'Mix Table', + iconName: 'point', + route: 'tables/mix-table', + }, + { + displayName: 'Multi Header Footer', + iconName: 'point', + route: 'tables/multi-header-footer-table', + }, + { + displayName: 'Pagination Table', + iconName: 'point', + route: 'tables/pagination-table', + }, + { + displayName: 'Row Context Table', + iconName: 'point', + route: 'tables/row-context-table', + }, + { + displayName: 'Selection Table', + iconName: 'point', + route: 'tables/selection-table', + }, + { + displayName: 'Sortable Table', + iconName: 'point', + route: 'tables/sortable-table', + }, + { + displayName: 'Sticky Column', + iconName: 'point', + route: 'tables/sticky-column-table', + }, + { + displayName: 'Sticky Header Footer', + iconName: 'point', + route: 'tables/sticky-header-footer-table', + }, + ], + }, + { + displayName: 'Data table', + iconName: 'border-outer', + route: '/datatable/kichen-sink', + }, + { + navCap: 'Chart', + }, + { + displayName: 'Line', + iconName: 'chart-line', + route: '/charts/line', + }, + { + displayName: 'Gredient', + iconName: 'chart-arcs', + route: '/charts/gredient', + }, + { + displayName: 'Area', + iconName: 'chart-area', + route: '/charts/area', + }, + { + displayName: 'Candlestick', + iconName: 'chart-candle', + route: '/charts/candlestick', + }, + { + displayName: 'Column', + iconName: 'chart-dots', + route: '/charts/column', + }, + { + displayName: 'Doughnut & Pie', + iconName: 'chart-donut-3', + route: '/charts/doughnut-pie', + }, + { + displayName: 'Radialbar & Radar', + iconName: 'chart-radar', + route: '/charts/radial-radar', + }, + { + navCap: 'UI', + }, + { + displayName: 'Ui Components', + iconName: 'box', + route: 'ui-components', + children: [ + { + displayName: 'Badge', + iconName: 'point', + route: 'ui-components/badge', + }, + { + displayName: 'Expansion Panel', + iconName: 'point', + route: 'ui-components/expansion', + }, + { + displayName: 'Chips', + iconName: 'point', + route: 'ui-components/chips', + }, + { + displayName: 'Dialog', + iconName: 'point', + route: 'ui-components/dialog', + }, + { + displayName: 'Lists', + iconName: 'point', + route: 'ui-components/lists', + }, + { + displayName: 'Divider', + iconName: 'point', + route: 'ui-components/divider', + }, + { + displayName: 'Menu', + iconName: 'point', + route: 'ui-components/menu', + }, + { + displayName: 'Paginator', + iconName: 'point', + route: 'ui-components/paginator', + }, + { + displayName: 'Progress Bar', + iconName: 'point', + route: 'ui-components/progress', + }, + { + displayName: 'Progress Spinner', + iconName: 'point', + route: 'ui-components/progress-spinner', + }, + { + displayName: 'Ripples', + iconName: 'point', + route: 'ui-components/ripples', + }, + { + displayName: 'Slide Toggle', + iconName: 'point', + route: 'ui-components/slide-toggle', + }, + { + displayName: 'Slider', + iconName: 'point', + route: 'ui-components/slider', + }, + { + displayName: 'Snackbar', + iconName: 'point', + route: 'ui-components/snackbar', + }, + { + displayName: 'Tabs', + iconName: 'point', + route: 'ui-components/tabs', + }, + { + displayName: 'Toolbar', + iconName: 'point', + route: 'ui-components/toolbar', + }, + { + displayName: 'Tooltips', + iconName: 'point', + route: 'ui-components/tooltips', + }, + ], + }, + { + navCap: 'Auth', + }, + { + displayName: 'Login', + iconName: 'login', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/login', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-login', + }, + ], + }, + { + displayName: 'Register', + iconName: 'user-plus', + route: '/authentication', + children: [ + { + displayName: 'Side Register', + iconName: 'point', + route: '/authentication/side-register', + }, + { + displayName: 'Boxed Register', + iconName: 'point', + route: '/authentication/boxed-register', + }, + ], + }, + { + displayName: 'Forgot Password', + iconName: 'rotate', + route: '/authentication', + children: [ + { + displayName: 'Side Forgot Password', + iconName: 'point', + route: '/authentication/side-forgot-pwd', + }, + { + displayName: 'Boxed Forgot Password', + iconName: 'point', + route: '/authentication/boxed-forgot-pwd', + }, + ], + }, + { + displayName: 'Two Steps', + iconName: 'zoom-code', + route: '/authentication', + children: [ + { + displayName: 'Side Two Steps', + iconName: 'point', + route: '/authentication/side-two-steps', + }, + { + displayName: 'Boxed Two Steps', + iconName: 'point', + route: '/authentication/boxed-two-steps', + }, + ], + }, + { + displayName: 'Error', + iconName: 'alert-circle', + route: '/authentication/error', + }, + { + displayName: 'Maintenance', + iconName: 'settings', + route: '/authentication/maintenance', + }, + { + navCap: 'Other', + }, + { + displayName: 'Menu Level', + iconName: 'box-multiple', + route: '/menu-level', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + { + displayName: 'Disabled', + iconName: 'ban', + route: '/disabled', + disabled: true, + }, + { + displayName: 'Chip', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-primary text-white', + chipContent: '9', + }, + { + displayName: 'Outlined', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'outlined', + }, + { + displayName: 'External Link', + iconName: 'star', + route: 'https://www.google.com/', + external: true, + }, +]; diff --git a/theme/packages/dark/src/app/material.module.ts b/theme/packages/dark/src/app/material.module.ts new file mode 100644 index 0000000..8fd4750 --- /dev/null +++ b/theme/packages/dark/src/app/material.module.ts @@ -0,0 +1,89 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +// Material Form Controls +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatSelectModule } from '@angular/material/select'; +import { MatSliderModule } from '@angular/material/slider'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +// Material Navigation +import { MatMenuModule } from '@angular/material/menu'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatToolbarModule } from '@angular/material/toolbar'; +// Material Layout +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatListModule } from '@angular/material/list'; +import { MatStepperModule } from '@angular/material/stepper'; +import { MatTabsModule } from '@angular/material/tabs'; +import { MatTreeModule } from '@angular/material/tree'; +// Material Buttons & Indicators +import { MatButtonModule } from '@angular/material/button'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatIconModule } from '@angular/material/icon'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +// Material Popups & Modals +import { MatBottomSheetModule } from '@angular/material/bottom-sheet'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { MatTooltipModule } from '@angular/material/tooltip'; +// Material Data tables +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatSortModule } from '@angular/material/sort'; +import { MatTableModule } from '@angular/material/table'; + +@NgModule({ + declarations: [], + imports: [ + + ], + exports: [ + MatAutocompleteModule, + MatCheckboxModule, + MatDatepickerModule, + MatFormFieldModule, + MatInputModule, + MatRadioModule, + MatSelectModule, + MatSliderModule, + MatSlideToggleModule, + MatMenuModule, + MatSidenavModule, + MatToolbarModule, + MatCardModule, + MatDividerModule, + MatExpansionModule, + MatGridListModule, + MatListModule, + MatStepperModule, + MatTabsModule, + MatTreeModule, + MatButtonModule, + MatButtonToggleModule, + MatBadgeModule, + MatChipsModule, + MatIconModule, + MatProgressSpinnerModule, + MatProgressBarModule, + MatRippleModule, + MatBottomSheetModule, + MatDialogModule, + MatSnackBarModule, + MatTooltipModule, + MatPaginatorModule, + MatSortModule, + MatTableModule, + ], + +}) +export class MaterialModule {} diff --git a/theme/packages/dark/src/app/pages/apps/chat/chat.component.html b/theme/packages/dark/src/app/pages/apps/chat/chat.component.html new file mode 100644 index 0000000..1530c1f --- /dev/null +++ b/theme/packages/dark/src/app/pages/apps/chat/chat.component.html @@ -0,0 +1,123 @@ + + + + + + + +
+ +
+

Mathew Anderson

+ info@modernize.com +
+
+ +
+ + + + + + + +
+ + @if (filteredMessages() && filteredMessages().length > 0) { +
+ + @for(message of filteredMessages(); track message.from) { + + + + +

+ {{ message.from }} +

+

+ {{ message.subject }} +

+
+ } +
+
+ } @else { +
+ No messages found. +
+ } +
+
+ + + + + + +
+ +
+ {{ selectedMessage()?.from }} +
+
+ + + + + + +
+ + + + + + + @for(c of selectedMessage()?.chat; track c) { @if(c.type === 'odd') { +
+
+
+ + {{ c.msg }} +
+ + {{ c.date | date }} + +
+
+ } @else { +
+
+
+ {{ c.msg }} +
+ + {{ c.date | date }} + +
+
+ } } +
+
+ +
+ + + + +
+
+
+
\ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/apps/fullcalendar/fullcalendar.component.ts b/theme/packages/dark/src/app/pages/apps/fullcalendar/fullcalendar.component.ts new file mode 100644 index 0000000..a4565ca --- /dev/null +++ b/theme/packages/dark/src/app/pages/apps/fullcalendar/fullcalendar.component.ts @@ -0,0 +1,286 @@ +import { + Component, + ChangeDetectionStrategy, + Inject, + signal, + DOCUMENT +} from '@angular/core'; +import { CommonModule, NgSwitch } from '@angular/common'; +import { + MatDialog, + MatDialogRef, + MatDialogConfig, + MAT_DIALOG_DATA, + MatDialogModule, +} from '@angular/material/dialog'; +import { + FormsModule, + ReactiveFormsModule, + UntypedFormGroup, +} from '@angular/forms'; +import { CalendarFormDialogComponent } from './calendar-form-dialog/calendar-form-dialog.component'; +import { + startOfDay, + subDays, + addDays, + endOfMonth, + isSameDay, + isSameMonth, + addHours, + subMonths, + addMonths, +} from 'date-fns'; +import { Subject } from 'rxjs'; +import { + CalendarDateFormatter, + CalendarEvent, + CalendarEventAction, + CalendarEventTimesChangedEvent, + CalendarModule, + CalendarView, +} from 'angular-calendar'; +import { MaterialModule } from 'src/app/material.module'; +import { + MatNativeDateModule, + provideNativeDateAdapter, +} from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +const colors: any = { + red: { + primary: '#fa896b', + secondary: '#fdede8', + }, + blue: { + primary: '#5d87ff', + secondary: '#ecf2ff', + }, + yellow: { + primary: '#ffae1f', + secondary: '#fef5e5', + }, +}; + +@Component({ + selector: 'app-calendar-dialog', + templateUrl: './dialog.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + CommonModule, + MatNativeDateModule, + MatDialogModule, + MatDatepickerModule, TablerIconsModule + ], + providers: [provideNativeDateAdapter()], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CalendarDialogComponent { + options!: UntypedFormGroup; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) {} +} + +@Component({ + selector: 'app-fullcalendar', + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './fullcalendar.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + NgSwitch, + CalendarModule, + CommonModule, + MatDatepickerModule, + MatDialogModule, + MatFormFieldModule, + ], + providers: [provideNativeDateAdapter(), CalendarDateFormatter] +}) +export class AppFullcalendarComponent { + dialogRef = signal | any>(null); + dialogRef2 = signal | any>(null); + lastCloseResult = signal(''); + actionsAlignment = signal(''); + view = signal('month'); + viewDate = signal(new Date()); + activeDayIsOpen = signal(true); + + config: MatDialogConfig = { + disableClose: false, + width: '', + height: '', + position: { + top: '', + bottom: '', + left: '', + right: '', + }, + data: { + action: '', + event: [], + }, + }; + numTemplateOpens = 0; + + actions: CalendarEventAction[] = [ + { + label: ': Edit', + onClick: ({ event }: { event: CalendarEvent }): void => { + this.handleEvent('Edit', event); + }, + }, + { + label: 'Delete', + onClick: ({ event }: { event: CalendarEvent }): void => { + this.events.set( + this.events().filter((iEvent: CalendarEvent) => iEvent !== event) + ); + this.handleEvent('Deleted', event); + }, + }, + ]; + + refresh: Subject = new Subject(); + + events = signal([ + { + start: subDays(startOfDay(new Date()), 1), + end: addDays(new Date(), 1), + title: 'A 3 day event', + color: colors.red, + actions: this.actions, + }, + { + start: startOfDay(new Date()), + title: 'An event with no end date', + color: colors.blue, + actions: this.actions, + }, + { + start: subDays(endOfMonth(new Date()), 3), + end: addDays(endOfMonth(new Date()), 3), + title: 'A long event that spans 2 months', + color: colors.blue, + }, + { + start: addHours(startOfDay(new Date()), 2), + end: new Date(), + title: 'A draggable and resizable event', + color: colors.yellow, + actions: this.actions, + resizable: { + beforeStart: true, + afterEnd: true, + }, + draggable: true, + }, + ]); + + constructor(public dialog: MatDialog, @Inject(DOCUMENT) doc: any) {} + + dayClicked({ date, events }: { date: Date; events: CalendarEvent[] }): void { + if (isSameMonth(date, this.viewDate())) { + if ( + (isSameDay(this.viewDate(), date) && this.activeDayIsOpen() === true) || + events.length === 0 + ) { + this.activeDayIsOpen.set(false); + } else { + this.activeDayIsOpen.set(true); + this.viewDate.set(date); + } + } + } + + eventTimesChanged({ + event, + newStart, + newEnd, + }: CalendarEventTimesChangedEvent): void { + this.events.set( + this.events().map((iEvent: CalendarEvent) => { + if (iEvent === event) { + return { + ...event, + start: newStart, + end: newEnd, + }; + } + return iEvent; + }) + ); + + this.handleEvent('Dropped or resized', event); + } + + handleEvent(action: string, event: CalendarEvent): void { + this.config.data = { event, action }; + this.dialogRef.set(this.dialog.open(CalendarDialogComponent, this.config)); + + this.dialogRef() + .afterClosed() + .subscribe((result: string) => { + this.lastCloseResult.set(result); + this.dialogRef.set(null); + this.refresh.next(result); + }); + } + + addEvent(): void { + this.dialogRef2.set( + this.dialog.open(CalendarFormDialogComponent, { + panelClass: 'calendar-form-dialog', + autoFocus: false, + data: { + action: 'add', + date: new Date(), + }, + }) + ); + this.dialogRef2() + .afterClosed() + .subscribe((res: { action: any; event: any }) => { + if (!res) { + return; + } + const dialogAction = res.action; + const responseEvent = res.event; + responseEvent.actions = this.actions; + this.events.set([...this.events(), responseEvent]); + this.dialogRef2.set(null); + this.refresh.next(res); + }); + } + + deleteEvent(eventToDelete: CalendarEvent): void { + this.events.set( + this.events().filter( + (event: CalendarEvent) => event !== eventToDelete + ) + ); + } + + setView(view: CalendarView | any): void { + this.view.set(view); + } + + goToPreviousMonth(): void { + this.viewDate.set(subMonths(this.viewDate(), 1)); + } + + goToNextMonth(): void { + this.viewDate.set(addMonths(this.viewDate(), 1)); + } + + goToToday() { + this.viewDate.set(new Date()); + } +} diff --git a/theme/packages/dark/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html b/theme/packages/dark/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html new file mode 100644 index 0000000..027a82b --- /dev/null +++ b/theme/packages/dark/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html @@ -0,0 +1,156 @@ + + +
+
+
+

+ # + + {{ invoice().id }} +

+
+
+ + Cancel + + +
+
+ + + +
+
+ + Order Status: + + +
+ {{ invoice().status }} +
+
+
+
+ + Order Date + +
+ {{ invoice().orderDate | date : "dd-MM-yyyy" }} +
+
+
+
+ + + +
+
+ + Bill From + + +
+
+ + Bill To + + +
+
+ + Enter From Address + + +
+
+ + Bill From + + +
+
+
+ +
+
+ + + + + + + + + + + + + @for(row of addForm.get('rows')['controls']; track row; let index = + $index) { + + + + + + + + + + + + + + } + +
#Item NameUnit PriceUnitsUnit Total Price
+ {{ index + 1 }} + + + + + + + + + + + + + + + + + + @if(addForm.get('rows')) { + + } + + @if(index > 0) { + + } +
+
+ +
+
Sub total: {{ subTotal() }}
+
Total Vat: {{ vat() }}%
+ +

Grand Total: {{ grandTotal() }}

+
+
+
+
\ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html b/theme/packages/dark/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html new file mode 100644 index 0000000..f5f0397 --- /dev/null +++ b/theme/packages/dark/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html @@ -0,0 +1,239 @@ + + + @if( invoice()) { + +
+
+
+

+ # + + {{ invoice().id }} +

+
+
+ + Cancel + + + +
+
+ + + +
+
+ Order Status: + + + Pending + Shipped + Delivered + + +
+
+
+ Order Date +
+ {{ invoice().orderDate | date : "dd-MM-yyyy" }} +
+
+
+
+ + + +
+
+ + Bill From + + +
+
+ + Bill To + + +
+
+ + Enter From Address + + +
+
+ + Bill From + + +
+
+
+
+ } + +
+
+ + + + + + + + + + + + + @for(a of addForm.get('item')['controls']; track a; let i =$index) { + + + + + + + + + + + + } +
#Item NameUnit PriceUnitsUnit Total Price
+ {{ i + 1 }} + + + + + + + + + + + + + + + + + + + + @if(addForm.get('item')?.length > 1) { + + } +
+
+ +
+
+ @if(addForm.get('rows')) { + + } + +
Sub total: {{ subTotal() }}
+
Total Vat: {{ vat() }}%
+ +

Grand Total: {{ grandTotal() }}

+
+
+
+
+
diff --git a/theme/packages/dark/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts b/theme/packages/dark/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts new file mode 100644 index 0000000..3e5b5b4 --- /dev/null +++ b/theme/packages/dark/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts @@ -0,0 +1,164 @@ +import { Component, signal } from '@angular/core'; +import { ActivatedRoute, Router, RouterLink } from '@angular/router'; +import { InvoiceService } from 'src/app/services/apps/invoice/invoice.service'; +import { InvoiceList, order } from '../invoice'; +import { + UntypedFormGroup, + UntypedFormArray, + UntypedFormBuilder, + Validators, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { OkDialogComponent } from './ok-dialog/ok-dialog.component'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatSnackBar } from '@angular/material/snack-bar'; +@Component({ + selector: 'app-edit-invoice', + templateUrl: './edit-invoice.component.html', + imports: [ + MaterialModule, + CommonModule, + RouterLink, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ], +}) +export class AppEditInvoiceComponent { + id = signal(null); + subTotal = signal(0); + vat = signal(0); + grandTotal = signal(0); + addForm: UntypedFormGroup | any; + invoice = signal([]); + constructor( + activatedRouter: ActivatedRoute, + private invoiceService: InvoiceService, + private router: Router, + private fb: UntypedFormBuilder, + public dialog: MatDialog, + private snackBar: MatSnackBar + ) { + this.id.set(activatedRouter.snapshot.paramMap.get('id')); + this.loadInvoice(); // Load invoice here + this.subTotal.set(this.invoice()?.totalCost || 0); + this.vat.set(this.invoice()?.vat || 0); + this.grandTotal.set(this.invoice()?.grandTotal || 0); + this.addForm = this.fb.group({ + item: this.fb.array([this.itemControl()]), + }); + + this.fillAddControls(); + } + + loadInvoice(): void { + const invoiceData = this.invoiceService + .getInvoiceList() + .find((x) => x.id === +this.id()); + this.invoice.set(invoiceData); // Set the invoice signal + } + itemControl(): UntypedFormGroup { + return this.fb.group({ + itemName: ['', Validators.required], + itemCost: ['', Validators.required], + itemSold: ['', Validators.required], + itemTotal: [{ value: 0, disabled: true }], + }); + } + + fillAddControls(): void { + this.addForm.setControl('item', this.setItem(this.invoice()?.orders)); + } + + setItem(order: any): UntypedFormArray { + const fa = new UntypedFormArray([]); + order?.forEach((s: any) => { + fa.push( + this.fb.group({ + itemName: s.itemName, + itemCost: s.unitPrice, + itemSold: s.units, + itemTotal: s.unitTotalPrice, + }) + ); + }); + return fa; + } + + btnAddItemClick(): void { + (this.addForm.get('item')).push(this.itemControl()); + } + + btnRemoveClick(i: number): void { + const totalCostOfItem = + this.addForm.get('item')?.value[i].itemCost * + this.addForm.get('item')?.value[i].itemSold; + + this.subTotal.set(this.subTotal() - totalCostOfItem); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + + (this.addForm.get('item')).removeAt(i); + } + + itemsChanged(): void { + let total = 0; + for ( + let t = 0; + t < (this.addForm.get('item')).length; + t++ + ) { + if ( + this.addForm.get('item')?.value[t].itemCost != '' && + this.addForm.get('item')?.value[t].itemSold + ) { + total += + this.addForm.get('item')?.value[t].itemCost * + this.addForm.get('item')?.value[t].itemSold; + } + } + this.subTotal.set(total); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + } + + saveDetail(event: Event): void { + event.preventDefault(); + const currentInvoice = this.invoice(); + if (currentInvoice) { + currentInvoice.grandTotal = this.grandTotal(); + currentInvoice.totalCost = this.subTotal(); + currentInvoice.vat = this.vat(); + currentInvoice.orders = []; + + for ( + let t = 0; + t < (this.addForm.get('item')).length; + t++ + ) { + const o: order = new order(); + o.itemName = this.addForm.get('item')?.value[t].itemName; + o.unitPrice = this.addForm.get('item')?.value[t].itemCost; + o.units = this.addForm.get('item')?.value[t].itemSold; + o.unitTotalPrice = o.units * o.unitPrice; + currentInvoice.orders.push(o); + } + this.dialog.open(OkDialogComponent); + this.invoiceService.updateInvoice(currentInvoice.id, currentInvoice); + this.router.navigate(['/apps/invoice/list']); + this.showSnackbar('Invoice updated successfully!'); + } + } + + showSnackbar(message: string): void { + this.snackBar.open(message, 'Close', { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } +} diff --git a/theme/packages/dark/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html b/theme/packages/dark/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html new file mode 100644 index 0000000..3942ba6 --- /dev/null +++ b/theme/packages/dark/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html @@ -0,0 +1,281 @@ +
+
+ + +
+ +
+
+
Total
+
+ {{ allInvoices().length }} invoices +
+
+
+
+
+
+ + +
+ +
+
+
Shipped
+
+ {{ countInvoicesByStatus("Shipped") }} invoices +
+
+
+
+
+ +
+ + +
+ +
+
+
Delivered
+
+ {{ countInvoicesByStatus("Delivered") }} invoices +
+
+
+
+
+ +
+ + +
+ +
+
+
Pending
+
+ {{ countInvoicesByStatus("Pending") }} invoices +
+
+
+
+
+
+ + + +
+
+ + + + + + +
+ +
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + Id + + {{ element.id }} + + Bill From + + {{ element.billFrom }} + + Bill To + + {{ element.billTo }} + + Total Cost + + {{ element.totalCost }} + + Status + + + {{ element.status }} + + + Action + + + + + + + + + + + +
+ +
+
+
diff --git a/theme/packages/dark/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html b/theme/packages/dark/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html new file mode 100644 index 0000000..b3bbc15 --- /dev/null +++ b/theme/packages/dark/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html @@ -0,0 +1,125 @@ + + + @if(invoiceDetail()){ + +
+
+

#{{ invoiceDetail()?.id }}

+
+ +
+ +
+
+ Order Status: +
+ {{ invoiceDetail()?.status }} +
+
+
+ Order Date: +
+ {{ invoiceDetail()?.orderDate | date : "fullDate" }} +
+
+
+ +
+
+ Bill From: +
+ {{ invoiceDetail()?.billFrom }} +
+
+ {{ invoiceDetail()?.billFromEmail }} +
+
+ {{ invoiceDetail()?.billFromAddress }} +
+
+ {{ invoiceDetail()?.billFromPhone }} +
+
+
+ Bill To: +
+ {{ invoiceDetail()?.billTo }} +
+
+ {{ invoiceDetail()?.billToEmail }} +
+
+ {{ invoiceDetail()?.billToAddress }} +
+
+ {{ invoiceDetail()?.billToPhone }} +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ Item Name + + {{ element.itemName }} + + Unit Price + + {{ element.unitPrice }} + + Unit + + {{ element.units }} + + Total Cost + + {{ element.unitTotalPrice }} +
+
+ +
+
+ Sub total: {{ invoiceDetail()?.totalCost }} +
+ Vat: 10% +

+ Grand Total: {{ invoiceDetail()?.grandTotal }} +

+
+
+ } +
+
diff --git a/theme/packages/dark/src/app/pages/apps/tickets/ticket-dialog-content.html b/theme/packages/dark/src/app/pages/apps/tickets/ticket-dialog-content.html new file mode 100644 index 0000000..19f96d5 --- /dev/null +++ b/theme/packages/dark/src/app/pages/apps/tickets/ticket-dialog-content.html @@ -0,0 +1,132 @@ +@if(action !== 'Delete') { + +
+

{{action}} Ticket

+ +
+
+
+ @if(action === 'Update') { +
+ Ticket Id + + + +
+ } + +
+ Ticket Title + + + +
+
+ Ticket Subtext + + + +
+
+ Assign User + + + @for(user of users; track trackByUser(user)) { + +
+ {{ user.name }} + {{ user.name }} +
+
+ } +
+
+
+ @if(action === 'Update'){ +
+ Status + + + +
+ } @if(action === 'Update') { +
+ + Date + + + + +
+ } +
+
+
+} @else { +
+ Sure to delete {{local_data.title}}? +
+} +
+ + +
diff --git a/theme/packages/dark/src/app/pages/apps/tickets/tickets.component.ts b/theme/packages/dark/src/app/pages/apps/tickets/tickets.component.ts new file mode 100644 index 0000000..f1b5f6c --- /dev/null +++ b/theme/packages/dark/src/app/pages/apps/tickets/tickets.component.ts @@ -0,0 +1,177 @@ +import { + Component, + OnInit, + ViewChild, + AfterViewInit, + Inject, +} from '@angular/core'; +import { MatTableDataSource, MatTable } from '@angular/material/table'; +import { + MatDialog, + MatDialogRef, + MAT_DIALOG_DATA, +} from '@angular/material/dialog'; +import { MatPaginator } from '@angular/material/paginator'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TicketService } from 'src/app/services/apps/ticket/ticket.service'; +import { TicketElement } from 'src/app/pages/apps/tickets/ticket'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +@Component({ + selector: 'app-ticket-list', + templateUrl: './tickets.component.html', + imports: [MaterialModule, CommonModule, TablerIconsModule], +}) +export class AppTicketlistComponent implements OnInit, AfterViewInit { + @ViewChild(MatTable, { static: true }) table: MatTable; + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; + + searchText: string = ''; + totalCount = 0; + Closed = 0; + Inprogress = 0; + Open = 0; + + displayedColumns: string[] = [ + 'id', + 'title', + 'assignee', + 'status', + 'date', + 'action', + ]; + + dataSource = new MatTableDataSource([]); + + constructor(private ticketService: TicketService, public dialog: MatDialog) {} + + ngOnInit(): void { + this.loadTickets(); // Load the initial tickets + } + + private loadTickets(): void { + const tickets = this.ticketService.tickets$; // Get tickets from the service + this.dataSource.data = tickets; // Set the dataSource to the tickets + + // Update counts based on the current tickets + this.updateCounts(); + } + + private updateCounts(): void { + this.totalCount = this.dataSource.data.length; + this.Open = this.countTicketsByStatus('open'); + this.Closed = this.countTicketsByStatus('closed'); + this.Inprogress = this.countTicketsByStatus('inprogress'); + } + + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + } + + onKeyup(event: KeyboardEvent): void { + const input = event.target as HTMLInputElement; + this.applyFilter(input.value); + } + applyFilter(filterValue: string): void { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + btnCategoryClick(val: string): number { + this.dataSource.filter = val.trim().toLowerCase(); + return this.dataSource.filteredData.length; + } + + openDialog(action: string, ticket: TicketElement | any): void { + const dialogRef = this.dialog.open(TicketDialogComponent, { + data: { action, ticket }, + autoFocus: false, + }); + + dialogRef.afterClosed().subscribe(() => { + this.loadTickets(); + }); + } + + countTicketsByStatus(status: string): number { + return this.dataSource.data.filter( + (ticket) => ticket.status.toLowerCase() === status.toLowerCase() + ).length; + } +} + +@Component({ + // tslint:disable-next-line - Disables all + selector: 'app-dialog-content', + templateUrl: 'ticket-dialog-content.html', + imports: [ + MaterialModule, + CommonModule, + TablerIconsModule, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ], +}) +export class TicketDialogComponent { + action: string; + local_data: TicketElement; + users: any[] = []; + dateControl = new FormControl(); + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + private ticketService: TicketService, + private snackBar: MatSnackBar + ) { + this.action = data.action; + this.local_data = { ...data.ticket }; + } + + ngOnInit(): void { + this.users = this.ticketService.getUsers(); // Get users from the service + + if (this.local_data.date) { + this.dateControl.setValue( + new Date(this.local_data.date).toISOString().split('T')[0] + ); // existing date + } else { + // Set to today's date if no existing date is available + this.dateControl.setValue(new Date().toISOString().split('T')[0]); + } + } + + doAction(): void { + this.local_data.date = this.dateControl.value; // Update local_data with the new date + + if (this.action === 'Update') { + this.ticketService.updateTicket(this.local_data); + this.openSnackBar('Ticket updated successfully!', 'Close'); + } else if (this.action === 'Add') { + this.ticketService.addTicket(this.local_data); + this.openSnackBar('Ticket added successfully!', 'Close'); + } else if (this.action === 'Delete') { + this.ticketService.deleteTicket(this.local_data.id); + this.openSnackBar('Ticket deleted successfully!', 'Close'); + } + this.dialogRef.close(); + } + + openSnackBar(message: string, action: string): void { + this.snackBar.open(message, action, { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } + closeDialog(): void { + this.dialogRef.close(); + } + + trackByUser(user: any): any { + return user.id; + } +} diff --git a/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.html b/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.html new file mode 100644 index 0000000..0fef605 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.html @@ -0,0 +1,169 @@ +
+ + +
+
+

+ The hassle-free setup process +

+
+ @for(topcard of setupCards; track topcard.title) { +
+ + +
+ @if(topcard.id!==2){ + users + } + +
+ {{ topcard.title }} +
+

+ {{ topcard.subtitle }} +

+ @if(topcard.id===2){ + image + } +
+
+
+
+ } +
+
+
+ + + +
+
+
+
+
+

Key metric at a glance

+

+ From the year we were founded to the impressive customer base + we've built, and the growth percentages that reflect our + continuous improvement, these numbers tell our story at a glance. + Explore the data that drives our mission and underscores our + commitment to excellence. +

+
+
+
+
+ @for (stat of stats; track stat) { +
+
+

+ {{ stat.label }} +

+

+ {{ stat.value }} +

+

{{ stat.description }}

+
+
+ } +
+
+
+
+
+ +
+ +
+ +
+
+
+ +
+
+

+ What our clients
think logo + about us? +

+

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+
+
+
+ + + Features availability + +
+
+ +
+
{{ currentUser().name }}
+
+ +

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+ + + +
+ + + {{ displayCount() }} + + +
+
+
+
+
+
+
+ + + +
\ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.scss b/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.scss new file mode 100644 index 0000000..e5e27d5 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.scss @@ -0,0 +1,23 @@ +.contact-page { + + .setup-process { + + mat-card-content { + padding: 0px !important; + padding: 30px 16px !important; + } + } + + .key-metric { + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + } + + .features { + + .cardWithShadow { + mat-card-content { + padding: 0px !important; + } + } + } +} \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.spec.ts new file mode 100644 index 0000000..0d075ce --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AboutUsComponent } from './about-us.component'; + +describe('AboutUsComponent', () => { + let component: AboutUsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AboutUsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AboutUsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.ts b/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.ts new file mode 100644 index 0000000..497b22d --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/about-us/about-us.component.ts @@ -0,0 +1,48 @@ +import { Component, computed, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { ImageSliderComponent } from '../image-slider/image-slider.component'; +import { FooterComponent } from '../footer/footer.component'; +//import { PagePricingComponent } from '../page-pricing/page-pricing.component'; +import { + setupCards, + stats, + users, +} from '../front-pagesData'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-about-us', + imports: [IconModule,MaterialModule ,CommonModule,ImageSliderComponent,FooterComponent, + //PagePricingComponent + ], + templateUrl: './about-us.component.html', + styleUrl: './about-us.component.scss' +}) +export class AboutUsComponent { + setupCards=setupCards; + stats = stats; + currentIndex = signal(0); // Starting from 0 + users = users; + // Computed values to auto-update template + currentUser = computed(() => this.users[this.currentIndex()]); + displayCount = computed( + () => `${this.currentIndex() + 1}/${this.users.length}` + ); + goPrev() { + if (this.currentIndex() > 0) { + this.currentIndex.update((i) => i - 1); + } + } + + goNext() { + if (this.currentIndex() < this.users.length - 1) { + this.currentIndex.update((i) => i + 1); + } + + + } + + + +} diff --git a/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.html b/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.html new file mode 100644 index 0000000..020f82c --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.html @@ -0,0 +1,116 @@ + + +
+
+ + + + @if(blogDetail()) { + + Photo of a Shiba Inu +
+ 2 mins Read +
+ +
+
+ +
+ {{ + blogDetail()?.category }} +
+ + {{ + blogDetail()?.title }} + +
+
+ {{ + blogDetail()?.views }} + 4 +
+ + + {{ blogDetail()?.date }} + +
+
+ +

Main Heading & Points

+

+ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the + industry's standard dummy text ever since + the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It + has survived not only five centuries, + but also the leap into electronic typesetting, + remaining essentially unchanged. It was popularised in the +

+
    +
  • Vivamus eu lacus scelerisque, placerat commodo lectus.
  • +
  • Etiam et ante at ex porta fringilla.
  • +
  • Nullam dignissim sem eu magna aliquet, sit amet volutpat tellus
  • +
+

+ Unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not + only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was + popularised in the +

+ +

+ We are a dedicated team of passionate product managers, developers, UX/UI designers, QA engineers experts + helping businesses from new startups +

+ +

+ There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in + some form, by injected humour, or randomised words which don't look even slightly believable making this the + first true generator on the Internet. It uses a dictionary +

+ +

Tags

+
    +
  • Trends
  • +
  • Design
  • +
  • Research
  • +
+ + +

Share

+ + + +

Join our newsletter

+

Email address : Subscribe

+
+
+ } + + + + + + @if (!blogDetail() || blogDetail().length === 0) { + + +

No blog post available.

+
+
+ } +
+
+ + \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.scss b/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts new file mode 100644 index 0000000..241ed7b --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlogDetailsComponent } from './blog-details.component'; + +describe('BlogDetailsComponent', () => { + let component: BlogDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BlogDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BlogDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.ts b/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.ts new file mode 100644 index 0000000..9633085 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/blog-details/blog-details.component.ts @@ -0,0 +1,40 @@ +import { CommonModule } from '@angular/common'; +import { Component, inject, OnInit, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; +import { FrontEndService } from 'src/app/services/apps/front-pages/front-end.service'; + +@Component({ + selector: 'app-blog-details', + imports: [IconModule, MaterialModule, CommonModule, + FooterComponent + ], + templateUrl: './blog-details.component.html', + styleUrl: './blog-details.component.scss' +}) +export class BlogDetailsComponent implements OnInit { + blogDetail = signal(null); + private frontendService = inject(FrontEndService); + ngOnInit(): void { + const selected = this.frontendService.getBlog()(); + + if (selected) { + this.blogDetail.set(selected); + } else { + // Fallback if accessed directly (e.g., from sidebar or refresh) + const defaultBlog = { + id: 1, + time: "2 mins Read", + imgSrc: "/assets/images/blog/blog-img1.jpg", + user: "/assets/images/profile/user-1.jpg", + title: "As yen tumbles, gadget-loving Japan goes for secondhand iPhones", + views: "9,125", + category: "Social", + comments: 3, + date: "Mon, Dec 23" + }; + this.blogDetail.set(defaultBlog); + } + } +} diff --git a/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.html b/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.html new file mode 100644 index 0000000..e30ba7c --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.html @@ -0,0 +1,55 @@ + + +
+
+
+ @for(cardimg of cardimgs; track cardimg.imgSrc) { +
+ + Photo of a Shiba Inu +
+ {{ + cardimg.time + }} +
+ + +
+
+ +
+ {{ + cardimg.category + }} +
+ {{ cardimg.title }} +
+
+ {{ cardimg.views }} + {{ cardimg.comments }} +
+ + + {{ cardimg.date }} + +
+
+
+
+ } +
+
+
+ + \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.scss b/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.scss new file mode 100644 index 0000000..e5dce08 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.scss @@ -0,0 +1,24 @@ + + +.social-btns { + margin-top: 20px; + + .btn-icon { + width: 25px !important; + height: 25px !important; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + + tabler-icon { + width: 16px !important; + height: 16px !important; + } + } + + .btn-add-story { + font-size: 0.75rem; + padding: 0.35rem 0.75rem; + } +} \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.spec.ts new file mode 100644 index 0000000..7998b08 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlogComponent } from './blog.component'; + +describe('BlogComponent', () => { + let component: BlogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BlogComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BlogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.ts b/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.ts new file mode 100644 index 0000000..d25328e --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/blog/blog.component.ts @@ -0,0 +1,32 @@ +import { Component, inject, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { cardimgs } from '../front-pagesData'; +import { FooterComponent } from '../footer/footer.component'; +import { Router } from '@angular/router'; +import { FrontEndService } from 'src/app/services/apps/front-pages/front-end.service'; + +@Component({ + selector: 'app-blog', + imports: [IconModule, MaterialModule, FooterComponent,], + templateUrl: './blog.component.html', + styleUrl: './blog.component.scss' +}) +export class BlogComponent implements OnInit { + + private router = inject(Router); + private frontendService = inject(FrontEndService); + cardimgs = cardimgs; + + ngOnInit() { + console.log(cardimgs, 'cardimgs'); + } + + getNavigate(cardimg: any) { + console.log('cardimg--->', cardimg); + this.frontendService.setBlog(cardimg); + this.router.navigate(['front-pages/blog-details']) + + } + +} diff --git a/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.html b/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.html new file mode 100644 index 0000000..f2cfc62 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.html @@ -0,0 +1,103 @@ +
+ + + +
+
+
+ +
+ +
+
+
+
+
+
+ + First Name* + + + + + Phone Number* + + + +
+
+ + Last Name* + + + + + Email* + + + +
+
+ +
+
+ Enquire related to* + + + + General Enquiry + General Enquiry 2 + + +
+
+
+
+ Message + + + +
+
+ +
+
+ + +
+
Reach Out Today
+

+ Have questions or need assistance? We're just a message + away. +

+
+ +
+
Our Location
+

+ Visit us in person or find our contact details to connect + with us directly. +

+
+
+
+
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.scss b/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.scss new file mode 100644 index 0000000..572fa27 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.scss @@ -0,0 +1,3 @@ +.map-container{ + margin-top: -200px; +} \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.spec.ts new file mode 100644 index 0000000..dae8ee6 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ContactComponent } from './contact.component'; + +describe('ContactComponent', () => { + let component: ContactComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ContactComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ContactComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.ts b/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.ts new file mode 100644 index 0000000..556ed9a --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/contact/contact.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; + +@Component({ + selector: 'app-contact', + imports: [MaterialModule,IconModule,FooterComponent], + templateUrl: './contact.component.html', + styleUrl: './contact.component.scss' +}) +export class ContactComponent { + +} diff --git a/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.html b/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.html new file mode 100644 index 0000000..0177911 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.html @@ -0,0 +1,94 @@ + \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.scss b/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.scss new file mode 100644 index 0000000..6a425bb --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.scss @@ -0,0 +1,13 @@ + +.footer-content{ + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } +} + +.imgStyleDash { + position: absolute; +} diff --git a/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.spec.ts new file mode 100644 index 0000000..3f93915 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FooterComponent } from './footer.component'; + +describe('FooterComponent', () => { + let component: FooterComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FooterComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FooterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.ts b/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.ts new file mode 100644 index 0000000..7864854 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/footer/footer.component.ts @@ -0,0 +1,95 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { RouterLink } from '@angular/router'; + +@Component({ + selector: 'app-footer', + imports: [MaterialModule, IconModule, RouterLink], + templateUrl: './footer.component.html', + styleUrl: './footer.component.scss' +}) +export class FooterComponent { + applicationsItems = [ + { + title: 'Kanban', + href: "/apps/kanban" + }, + { + title: 'Invoice List', + href: "/apps/invoice/list" + }, + { + title: 'eCommerce', + href: "/apps/product/shop" + }, + { + title: 'Chats', + href: "/apps/chat" + }, + { + title: 'Tickets', + href: "/apps/tickets" + }, + { + title: 'Blog', + href: "/apps/blog/post" + }, + ]; + + formsItems = [ + { + title: 'Form Layout', + href: "/forms/form-layouts" + }, + { + title: 'Form Horizontal', + href: "/forms/form-horizontal" + }, + { + title: 'Form Wizard', + href: "/forms/form-wizard" + }, + { + title: 'Form Vertical', + href: "/forms/form-vertical" + }, + { + title: 'Form Toastr', + href: "/forms/form-toastr" + }, + ]; + + tablesItems = [ + { + title: 'Basic Table', + href: "/tables/basic-table" + }, + { + title: 'Multi Header Footer Table', + href: "/tables/multi-header-footer-table" + }, + { + title: 'Pagination Table', + href: "/tables/pagination-table" + }, + { + title: 'Dynamic Table', + href: "/tables/dynamic-table" + }, + { + title: 'HTTP Table', + href: "/tables/http-table" + }, + { + title: 'Sortable Table', + href: "/tables/sortable-table" + }, + ]; + + socialIcons = [ + { src: 'assets/images/front-pages/icon-facebook.svg', tooltip: 'Facebook' }, + { src: 'assets/images/front-pages/icon-twitter.svg', tooltip: 'Twitter' }, + { src: 'assets/images/front-pages/icon-instagram.svg', tooltip: 'Instagram' }, + ]; +} diff --git a/theme/packages/dark/src/app/pages/front-pages/front-pages.routes.ts b/theme/packages/dark/src/app/pages/front-pages/front-pages.routes.ts new file mode 100644 index 0000000..bf9375c --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/front-pages.routes.ts @@ -0,0 +1,28 @@ +import { Routes } from '@angular/router'; +import { HomepageComponent } from './homepage/homepage.component'; +import { AboutUsComponent } from './about-us/about-us.component'; +import { HomepageDetailsComponent } from './homepage-details/homepage-details.component'; +import { BlogComponent } from './blog/blog.component'; +import { PortfolioComponent } from './portfolio/portfolio.component'; +import { PricingComponent } from './pricing/pricing.component'; +import { ContactComponent } from './contact/contact.component'; +import { BlogDetailsComponent } from './blog-details/blog-details.component'; + + +export const FrontPagesRoutes: Routes = [ + + { + path: '', + component: HomepageComponent, // acts as layout shell + children: [ + { path: '', redirectTo: 'homepage', pathMatch: 'full' }, + { path: 'homepage', component: HomepageDetailsComponent }, // real homepage content + { path: 'about', component: AboutUsComponent }, + {path:'blog',component:BlogComponent }, + { path: 'portfolio', component: PortfolioComponent }, + { path: 'pricing', component: PricingComponent }, + { path: 'contact', component: ContactComponent }, + { path: 'blog-details', component: BlogDetailsComponent }, + ], + }, +]; \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/front-pagesData.ts b/theme/packages/dark/src/app/pages/front-pages/front-pagesData.ts new file mode 100644 index 0000000..0e870f4 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/front-pagesData.ts @@ -0,0 +1,768 @@ +interface cardimgs { + id: number; + time: string; + imgSrc: string; + user: string; + title: string; + views: string; + category: string; + comments: number; + date: string; +} + +interface productcards { + id: number; + imgSrc: string; + title: string; + price: string; + rprice: string; + date: string; +} + +interface Framework { + src: string; + alt: string; + tooltip: string; +} + +interface followercards { + id: number; + imgSrc: string; + title: string; +} + +interface setupCards { + id: number; + img: string; + color: string; + title: string; + subtitle: string; + imgMain?:string; +} + +export const cardimgs: cardimgs[] = [ + { + id: 1, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img1.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 2, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img2.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 3, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img3.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + { + id: 4, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img4.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 5, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img5.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 6, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img6.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + { + id: 7, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img10.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 8, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img8.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 9, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img9.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, +]; + +export const productcards: productcards[] = [ + { + id: 1, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Headphone', + price: '285', + rprice: '375', + date: 'Tue, Apr 03, 2025', + }, + { + id: 2, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Air Pro', + price: '285', + rprice: '375', + date: 'Tue, Apr 10, 2025', + }, + { + id: 3, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Red Velvet Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 15, 2025', + }, + { + id: 4, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Soft Plush Teddy', + price: '285', + rprice: '375', + date: 'Tue, Apr 12, 2025', + }, + { + id: 5, + imgSrc: 'assets/images/products/s2.jpg', + title: 'Boat Bass Booster', + price: '285', + rprice: '375', + date: 'Tue, Apr 14, 2025', + }, + { + id: 6, + imgSrc: 'assets/images/products/s6.jpg', + title: 'MacBook Ultra Slim', + price: '285', + rprice: '375', + date: 'Tue, Apr 18, 2025', + }, + { + id: 7, + imgSrc: 'assets/images/products/s8.jpg', + title: 'Crimson Party Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 20, 2025', + }, + { + id: 8, + imgSrc: 'assets/images/products/s12.jpg', + title: 'Cuddly Teddy Gift', + price: '285', + rprice: '375', + date: 'Tue, Apr 22, 2025', + }, + { + id: 9, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Sonic Headset', + price: '285', + rprice: '375', + date: 'Tue, Apr 25, 2025', + }, + { + id: 10, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Pro 2025', + price: '285', + rprice: '375', + date: 'Tue, Apr 27, 2025', + }, + { + id: 11, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Evening Gown - Red', + price: '285', + rprice: '375', + date: 'Tue, Apr 29, 2025', + }, + { + id: 12, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Fluffy Bear Surprise', + price: '285', + rprice: '375', + date: 'Tue, Apr 30, 2025', + }, +]; + +export const frameworks: Framework[] = [ + { + src: 'assets/images/landingpage/frameworks/angular.svg', + alt: 'Angular', + tooltip: 'Angular', + }, + { + src: 'assets/images/landingpage/frameworks/material.svg', + alt: 'Angular Material', + tooltip: 'Angular Material', + }, + { + src: 'assets/images/landingpage/frameworks/logo-ts.svg', + alt: 'Typescript', + tooltip: 'Typescript', + }, + { + src: 'assets/images/landingpage/frameworks/icon-tabler.svg', + alt: 'Tabler Icon', + tooltip: 'Tabler Icon', + }, +]; + +export const tiles = [ + { + id: 1, + text: 'Light & Dark Color Schemes', + cols: 1, + rows: 1, + color: '#FFF6E5', + icon: 'svgs/icon-briefcase.svg', + subtitle: 'Choose your preferred visual style effortlessly.', + }, + { + id: 2, + text: 'New Demos', + cols: 2, + rows: 2, + color: '#E9F1FF', + icon: 'logos/logoIcon.svg', + img: 'landingpage/background/screen1.png', + subtitle: + 'Brand new demos to help you build the perfect dashboard:
Dark and Right-to-Left.', + }, + { + id: 3, + text: 'Code Improvements', + cols: 1, + rows: 1, + color: '#E7FFF2', + icon: 'logos/icon-speech-bubble.svg', + subtitle: 'Benefit from continuous improvements and optimizations.', + }, + { + id: 4, + text: '12+ Ready to Use Application Designs', + cols: 1, + rows: 1, + color: '#E4F4FF', + icon: 'icon-layer.svg', + img: 'landingpage/background/feature-apps.png', + subtitle: 'Instantly deployable designs for your applications.', + }, + { + id: 5, + text: '50+ UI Components', + cols: 1, + rows: 1, + color: '#FFECEC', + icon: 'logos/icon-favorites.svg', + subtitle: 'A rich collection for seamless user experiences.', + }, +]; + +export const users = [ + { name: 'Jenny Wilson', img: '/assets/images/profile/user-1.jpg' }, + { name: 'Robert Fox', img: '/assets/images/profile/user-2.jpg' }, + { name: 'Kristin Watson', img: '/assets/images/profile/user-3.jpg' }, + { name: 'Darlene Robertson', img: '/assets/images/profile/user-4.jpg' }, + { name: 'Jacob Jones', img: '/assets/images/profile/user-5.jpg' }, +]; + +export const plans = [ + { + title: 'Single Use', + description: + 'Use for single end product which end users can’t be charged for.', + price: 49, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: false }, + { text: 'One Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Multiple Use', + description: + 'Use for unlimited end products end users can’t be charged for.', + price: 89, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: false }, + { text: 'Unlimited Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Extended Use', + description: + 'Use for single end product which end users can be charged for.', + price: 299, + period: 'one time pay', + popular: true, + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: true }, + { text: 'One Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Unlimited Use', + description: + 'Use in unlimited end products end users can be charged for.', + price: 499, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: true }, + { text: 'Unlimited Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, +]; + +export const paymentLogos = [ + { src: 'assets/images/front-pages/icon-visa.svg', alt: 'visa', tooltip: 'Visa' }, + { + src: 'assets/images/front-pages/icon-mastercard.svg', + alt: 'mastercard', + tooltip: 'Master Card', + }, + { + src: 'assets/images/front-pages/icon-american-express.svg', + alt: 'american express', + tooltip: 'American Express', + }, + { + src: 'assets/images/front-pages/icon-discover.svg', + alt: 'discover', + tooltip: 'Discover', + }, + { + src: 'assets/images/front-pages/icon-paypal.svg', + alt: 'paypal', + tooltip: 'Paypal', + }, + { + src: 'assets/images/front-pages/icon-masetro.svg', + alt: 'maestro', + tooltip: 'Maestro', + }, + { src: 'assets/images/front-pages/icon-jcb.svg', alt: 'jcb', tooltip: 'JCB' }, + { + src: 'assets/images/front-pages/icon-diners.svg', + alt: 'diners', + tooltip: 'Diners', + }, +]; + +export const faqList = [ + { + question: 'What is included with my purchase?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Are there any recurring fees?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Can i use template on multiple projects? ', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: + 'Can i use customize the admin dashboard template to match my brand?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Are any restrictions on using the template?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'How can i get support after purchase? ', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, +]; + +export const followercardsFirst: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, +]; + +export const followercardSecond: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, +]; +export const followercardThird: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-customize.svg', + title: 'Easy to Customize', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-chart.svg', + title: 'Lots of Chart Options', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-table.svg', + title: 'Lots of Table Examples', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-update.svg', + title: 'Regular Updates', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-support.svg', + title: 'Dedicated Support', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Easy to Customize', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: 'Lots of Chart Options', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Lots of Table Examples', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Regular Updates', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Dedicated Support', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Easy to Customize', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: 'Lots of Chart Options', + }, + +]; + +export const topcardsGrid = [ + { title: 'Light & Dark Color Schemes', subtitle: 'Choose your preferred visual style effortlessly.', + img: '/assets/images/svgs/icon-briefcase.svg', color: 'warning' }, + { title: '12+ Ready to Use Application Designs', subtitle: 'Instantly deployable designs for your applications.', + img: 'assets/icons/icon2.png', color: 'secondary',imgMain: '/assets/images/landingpage/background/feature-apps.png', }, + { title: 'New Demos', subtitle: 'Brand new demos to help you build the perfect dashboard: Dark and Right-to-Left.', + img: '/assets/images/front-pages/logoIcon.svg', color: 'primary',imgMain: '/assets/images/landingpage/background/screen1.png' }, + { title: 'Code Improvements', subtitle: 'Benefit from continuous improvements and optimizations.', + img: '/assets/images/front-pages/icon-speech-bubble.svg', color: 'success' }, + { title: '50+ UI Components', subtitle: 'A rich collection for seamless user experiences.', + img: '/assets/images/front-pages/icon-favorites.svg', color: 'error' }, +]; + +export const setupCards:setupCards[] = [ + { + id: 1, + color: 'warning', + img: '/assets/images/svgs/icon-briefcase.svg', + title: 'Light & Dark Color Schemes', + subtitle: 'Choose your preferred visual style effortlessly.', + }, + { + id: 2, + color: 'secondary', + img: '/assets/images/svgs/icon-connect.svg', + title: '12+ Ready to Use Application Designs', + subtitle: 'Instantly deployable designs for your applications.', + imgMain: '/assets/images/landingpage/background/feature-apps.png' + }, + + { + id: 3, + color: 'success', + img: '/assets/images/svgs/icon-speech-bubble.svg', + title: 'Code Improvements', + subtitle: 'Benefit from continuous improvements and optimizations.', + }, + { + id: 4, + color: 'error', + img: '/assets/images/svgs/icon-favorites.svg', + title: '50+ UI Components', + subtitle: 'A rich collection for seamless user experiences.', + }, + +]; + +export const stats = [ + { + label: 'Founded', + value: '2019', + description: 'When we founded Modernize', + }, + { + label: 'Growth', + value: '1,400%', + description: 'Revenue growth in 2024', + }, + { + label: 'Customers', + value: '300k+', + description: 'Customers on Modernize', + }, + { + label: 'Dashboards', + value: '25k+', + description: 'Dashboards built using Modernize', + }, +]; + +export const team = [ + {id: 1, + name: 'Alex Martinez', + position: 'CEO & Co-Founder', + image: 'assets/images/front-pages/user1.jpg' + }, + { + id: 2, + name: 'Jordan Nguyen', + position: 'CTO & Co-Founder', + image: 'assets/images/front-pages/user2.jpg' + }, + { + id: 3, + name: 'Taylor Roberts', + position: 'Product Manager', + image: 'assets/images/front-pages/user3.jpg' + }, + {id: 4, + name: 'Morgan Patel', + position: 'Lead Developer', + image: 'assets/images/front-pages/user4.jpg' + }, + { + id: 5, + name: 'Andrew Grant', + position: 'Product Manager', + image: 'assets/images/front-pages/user5.jpg' + }, + { + id: 6, + name: 'Leo Pratt', + position: 'Lead Developer', + image: 'assets/images/front-pages/user3.jpg' + }, + { + id: 7, + name: 'C. A. Nunez', + position: 'CEO & Co-Founder', + image: 'assets/images/front-pages/user2.jpg' + }, + { + id: 8, + name: 'Leo Maxwell', + position: 'Lead Developer', + image: 'assets/images/front-pages/user1.jpg' + } +]; \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.html b/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.html new file mode 100644 index 0000000..b50b52c --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.html @@ -0,0 +1,603 @@ +
+
+
+
+
+

+ Most powerful & + developer friendly + dashboard +

+
+
+
+ @if(!isMobileView){ + +
+ banner-top-left +
+ } + +
+
+
+ +
+ 52,589+ developers & agencies using our templates +
+
+
+
+ Login +
+ + See how it works +
+
+
+ @for (framework of frameworks; track framework.tooltip) { + + + + } +
+
+ @if(!isMobileView){ +
+ banner-top-right +
+ + } +
+ @if (!isMobileView) { +
+
+ bottom-part +
+
+ } +
+
+ +
+
+
+
+

+ Introducing Modernize's Light & Dark Skins, Exceptional Dashboards, + and Dynamic Pages - Stay Updated on What's New! +

+
+
+ + + + + @if (!isMobileView) { +
+ +
+
+ @for (topcard of topcards; track topcard.title) { + @if (topcard.title === 'Light & Dark Color Schemes' || topcard.title.includes('12+')) { + + + @if (topcard.title === 'Light & Dark Color Schemes') { + icon + } +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+ @if (topcard.title.includes('12+')) { + image + } +
+
+ } + } +
+
+
+
+ @for (topcard of topcards; track topcard.title) + { + @if + (topcard.title.includes('New Demos')) { + + + icon +

{{ topcard.title }}

+

+ demo +
+
+ } } +
+
+ + +
+
+ @for (topcard of topcards; track topcard.title) { + @if (topcard.title.includes('Code Improvements') || topcard.title.includes('UI Components')) { + + + icon +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+
+
+ } + } +
+
+ +
+ } + + + @else { +
+ @for (topcard of topcards; track topcard.title) { + @if (!topcard.title.includes('New Demos')) { + + + @if (!topcard.title.includes('12+')) { + icon + } +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+ + @if (topcard.title.includes('12+')) { + image + } +
+
+ } + } +
+ + +
+ @for (topcard of topcards; track topcard.title) + { + @if + (topcard.title.includes('New Demos')) { + + + icon +
{{ topcard.title }}
+

+ demo +
+
+ } } +
+ } + + +
+
+ +
+ +
+ + + + + Team Scheduling + + + + + + Payments + + + + + + Embedding + + + + + + Workflows + + + + + + +
+
+
+ slider-group +
+
+ +
+
+

Defend your focus

+
+ + + + +
+ Factor in outside colleagues + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+ + + + +
+ Combine teammate schedules + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+ + + + +
+ Round robin pooling + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+
+
+ + Learn More +
+ + +
+
+
+
+ +
+ +
+ +
+
+
+ + + Save valuable time and effort spent searching for a solution. + Contact us now + +
+
+
+ +
+
+
+
+

+ Discover Powerful Dozens of
Purpose-Fit Templates +

+
+
+
+
+ + slide + +
+
+
+
+ + slide + +
+
+
+
+ + slide + +
+
+
+
+ slide +
+
+
+
+ + slide + +
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+
+
+

High Customizability

+

+ Tailor the dashboard to your exact needs. Customize layouts, color + schemes, and widgets effortlessly for a personalized user + experience. +

+
+
+

Powerful Data Analytics

+

+ Unlock the true potential of your data with our advanced analytics + tools. Gain valuable insights and make data-driven decisions with + ease. +

+
+ +
+

Interactive Charts

+

+ Visualize complex data sets beautifully with our interactive + graphs and charts. Quickly grasp trends and patterns for smarter + analysis. +

+
+
+
+
+
+
+ +
+
+
+ +
+
+

+ What our clients
think logo + about us? +

+

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+
+
+
+ + + Features availability + +
+
+ +
+
{{ currentUser().name }}
+
+ +

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+ + + +
+ + + {{ displayCount() }} + + +
+
+
+
+
+
+
+ +
+
+
+
+
+

+ Enjoy unparalleled features & exceptional flexibility. +

+
+
+ +
+
+
+ @for (followercard of followercardsfirst; track followercard.title) + { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+ @for (followercard of followercardsecond; track followercard.title) + { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+ @for (followercard of followercardthird; track followercard.title) { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+
+
+ +
+
+

Frequently Asked Questions

+
+
+ + @for (item of faqList; track item) { + + + {{ + item.question + }} + + + + + +

{{ item.answer }}

+
+ } +
+
+
+
+
+ Still have a question? + Ask on discord + or + Submit a ticket +
+
+
+
+ + + +
\ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.scss b/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.scss new file mode 100644 index 0000000..e6e0f4b --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.scss @@ -0,0 +1,189 @@ +.home-page { + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } + + .home-page-header { + + .header-container-content { + + .cardPosition { + .float-image { + animation: floatUpDown 6s ease-in-out infinite; + } + } + + .cardPositionTwo { + + .float-image { + animation: floatUpDown 6s ease-in-out infinite; + } + } + + .loginBtn { + .play-button { + background-color: transparent; + border: 2px solid var(--mat-sys-primary); // or use your theme color + color: var(--mat-sys-primary); + box-shadow: none; + } + + .textSee { + cursor: pointer; + + &:hover { + color: var(--mat-sys-primary); + } + } + } + } + } + + .dashboardCards { + + .card-container { + + mat-card-content { + padding: 0px !important; + } + } + } + + .tab-header { + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + + .profileTabs { + background-color: var(--mdc-elevated-card-container-color) !important; + + .mat-mdc-tab.mdc-tab-indicator--active { + .mdc-tab__text-label { + color: var(--mat-sys-primary); + } + } + } + + } + + .template-slider { + .template-slider-content { + .demo-slider { + .demo-slide { + animation: slide3d 15s linear infinite; + } + } + } + } + + .features { + + .cardWithShadow { + mat-card-content { + padding: 0px !important; + } + } + } + + .exceptional { + .exceptional-content { + .demo-slider { + .demo-slide { + animation: slide3d 20s linear infinite; + } + + .demo-slide-two { + animation: slide3dTwo 20s linear infinite; + } + } + } + } + + .expansion-panel { + box-shadow: none; + background: transparent; + border-radius: 0 !important; + border-bottom: 1px solid var(--mat-sys-outline); + + .mat-expansion-panel-header { + padding: 18px 0 !important; + height: auto; + } + } + + .sliderImg { + max-width: 380px; + height: 300px; + } + + .img-border { + border: 2px solid var(--mat-sys-secondary); + /* Blue border, change color as needed */ + cursor: pointer; + } + + .img-border:hover { + border-color: var(--mat-sys-secondary); + } + + .border-dash { + border: 1px dashed var(--mat-sys-outline); // Initial border color (Bootstrap primary) + transition: border-color 0.3s ease; + flex-wrap: wrap; + + &:hover { + border-color: var(--mat-sys-primary); // Use your Angular Material primary variable or a custom color + } + } + + .faq-accordion { + .mat-expansion-panel { + border-radius: 8px !important; + + .mat-expansion-panel-header { + padding: 20px 21px !important; + } + } + } +} + +@keyframes floatUpDown { + + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(-6px); // smaller bounce + } +} + +@keyframes slide3d { + from { + transform: translate3d(0, 0, 0); + } + + to { + transform: translate3d(-2028px, 0, 0); // adjust based on actual slide width + } +} + +@keyframes slide3dTwo { + from { + transform: translate3d(-2028px, 0, 0); // Rightward (starts left) + } + + to { + transform: translate3d(0, 0, 0); + } +} + + + +@media (max-width: 1199px) { + .home-page-header { + padding-bottom: 48px; + } +} \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts new file mode 100644 index 0000000..52b6227 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HomepageDetailsComponent } from './homepage-details.component'; + +describe('HomepageDetailsComponent', () => { + let component: HomepageDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HomepageDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HomepageDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.ts b/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.ts new file mode 100644 index 0000000..46f68e1 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/homepage-details/homepage-details.component.ts @@ -0,0 +1,131 @@ +import { Component, computed, DestroyRef, inject, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { + faqList, + followercardsFirst, + followercardSecond, + followercardThird, + frameworks, + tiles, + users, + topcardsGrid, +} from '../front-pagesData'; +import { CommonModule } from '@angular/common'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { ImageSliderComponent } from '../image-slider/image-slider.component'; +import { FooterComponent } from '../footer/footer.component'; +import { MatDialog } from '@angular/material/dialog'; +import { TemplateVideoComponent } from '../template-video/template-video.component'; +import { Router, RouterModule } from '@angular/router'; + + +@Component({ + selector: 'app-homepage-details', + imports: [ + MaterialModule, + IconModule, + CommonModule, + ImageSliderComponent, + FooterComponent, + RouterModule + ], + templateUrl: './homepage-details.component.html', + styleUrl: './homepage-details.component.scss', +}) +export class HomepageDetailsComponent { + + topcards=topcardsGrid; + + + centered = false; + disabled = false; + unbounded = false; + radius: number; + color: string; + showBackground: boolean = false; + frameworks = frameworks; + selectedIndex = 1; + + readonly dialog = inject(MatDialog); + private router = inject(Router); + private destroyRef = inject(DestroyRef); // ✅ For automatic cleanup + private mediaMatcher = inject(MediaMatcher); // ✅ Proper MediaMatcher injection + + mobileQuery: MediaQueryList; + isMobileView = false; + + readonly panelOpenState = signal(false); + tiles = tiles; + hideCloserBtn: boolean = true; + users = users; + expandedIndex: number | null = null; + currentIndex = signal(0); // Starting from 0 + faqList = faqList; + selectedPath: string | null = null; + clicked = false; + + followercardsfirst = followercardsFirst; + followercardsecond = followercardSecond; + followercardthird = followercardThird; + + currentUser = computed(() => this.users[this.currentIndex()]); + displayCount = computed(() => `${this.currentIndex() + 1}/${this.users.length}`); + + constructor() { + const isSmallScreen = this.mediaMatcher.matchMedia('(max-width: 599px)'); + // ✅ Setup media query for max-width: 1199px + this.mobileQuery = this.mediaMatcher.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + const listener = (e: MediaQueryListEvent) => { + this.isMobileView = e.matches; + }; + + // ✅ Listen to viewport changes + this.mobileQuery.addEventListener('change', listener); + + // ✅ Clean up listener on component destroy + this.destroyRef.onDestroy(() => { + this.mobileQuery.removeEventListener('change', listener); + }); + } + isOver(): boolean { + return this.mediaMatcher.matchMedia('(max-width: 1199px)').matches; + } + + goPrev() { + if (this.currentIndex() > 0) { + this.currentIndex.update((i) => i - 1); + } + } + + goNext() { + if (this.currentIndex() < this.users.length - 1) { + this.currentIndex.update((i) => i + 1); + } + } + openDialog(showBackground:boolean){ + this.showBackground = showBackground; + + const dialogRef = this.dialog.open(TemplateVideoComponent, { + data: {}, + width: '1000px', + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result === false) { + this.showBackground = false; // Reset or take any action + } + }); + } + + + onImageClick(path: string) { + this.selectedPath = path; + + setTimeout(() => { + this.router.navigate([path]); + }, 100); // brief delay to show border + } +} diff --git a/theme/packages/dark/src/app/pages/front-pages/homepage/homepage.component.html b/theme/packages/dark/src/app/pages/front-pages/homepage/homepage.component.html new file mode 100644 index 0000000..532acf0 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/homepage/homepage.component.html @@ -0,0 +1,137 @@ +
+ + + @if(hideCloserBtn){ + + + + +
+ New + Frontend Pages Included! +
+ + + + +
+ + } + +
+
+
+ +
+ + @if(!isMobileView){ +
+ + + + + + + + +
+ Login + } @if(isMobileView){ + + } +
+
+
+ +
+ +
+
+ + + +
+
+ +
+
+ + + + + + + + + + + + + + + + + Get + Started + +
+
+
+
+ @if(showBackToTop){ +
+ +
+ } +
\ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/homepage/homepage.component.scss b/theme/packages/dark/src/app/pages/front-pages/homepage/homepage.component.scss new file mode 100644 index 0000000..3cee318 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/homepage/homepage.component.scss @@ -0,0 +1,32 @@ +.landing-page { + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } + + .heightToolbar { + height: 46px; + background-size: cover; + background-repeat: no-repeat; + background-image: url(../../../../assets/images/front-pages/topbar-bg.png); + } + + .toolBarContent { + .nav-item { + &.selected { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); // optional for visibility + transition: background-color 0.3s ease; + } + + &:hover { + color: var(--mat-sys-primary); + transition: color 0.3s ease; + } + } + + } + +} \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/homepage/homepage.component.ts b/theme/packages/dark/src/app/pages/front-pages/homepage/homepage.component.ts new file mode 100644 index 0000000..ca1a34a --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/homepage/homepage.component.ts @@ -0,0 +1,65 @@ +import { MediaMatcher } from '@angular/cdk/layout'; +import { CommonModule } from '@angular/common'; +import { Component, HostListener, inject, ViewChild } from '@angular/core'; +import { MatSidenav } from '@angular/material/sidenav'; +import { ActivatedRoute, Router, RouterLink, RouterOutlet } from '@angular/router'; +import { IconModule } from 'src/app/icon/icon.module'; +import { BrandingComponent } from 'src/app/layouts/full/vertical/sidebar/branding.component'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-homepage', + imports: [MaterialModule, BrandingComponent, RouterLink, + IconModule, RouterOutlet, CommonModule], + templateUrl: './homepage.component.html', + styleUrl: './homepage.component.scss' +}) +export class HomepageComponent { + @ViewChild('customizerRight') customizerRight!: MatSidenav; + selected: string = ''; // default selected + mobileQuery: MediaQueryList; + isMobileView = false; + hideCloserBtn: boolean = true; + private router = inject(Router) + private mediaMatcher: MediaQueryList = matchMedia(`(max-width: 1199px)`); + showBackToTop: boolean; + isTopbarFixed: boolean; + constructor(private route: ActivatedRoute) { + const media = inject(MediaMatcher); + this.mobileQuery = media.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + this.mobileQuery.addEventListener('change', (e) => { + + this.isMobileView = e.matches; + this.closeSidenavIfNeeded(); + }); + } + closeSidenavIfNeeded() { + if (!this.isMobileView && this.customizerRight?.opened) { + this.customizerRight.close(); + } + } + isOver(): boolean { + return this.mediaMatcher.matches; + } + + isActiveRoute(route: string): boolean { + return this.router.url.includes(`/front-pages/${route}`); + } + hideCloser() { + this.hideCloserBtn = false; + } + getNavigate() { + this.router.navigate(['/dashboards/dashboard1']) + } + + scrollToTop(): void { + window.scrollTo({ top: 0, behavior: 'smooth' }); + } + @HostListener('window:scroll', []) + onWindowScroll() { + this.showBackToTop = window.scrollY > 300; + this.isTopbarFixed = scrollY > 45; + } +} diff --git a/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.html b/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.html new file mode 100644 index 0000000..f4c4b31 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.html @@ -0,0 +1,44 @@ +
+
+
+
+
+

Our leadership

+
+

+ Our robust analytics offer rich insights into the information + buyers want, informing where teams +

+
+
+ +
+
+ + +
+
+
+ +
+ @for (member of visibleTeamMembers(); track member.id){ +
+ + + imgSrc + + +

{{ member.name }}

+

{{ member.position }}

+
+
+
+ } +
+
+
+
\ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.scss b/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.scss new file mode 100644 index 0000000..0832285 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.scss @@ -0,0 +1,22 @@ +.img-slider-content { + .img-slider { + + .mat-mdc-card { + margin-bottom: 0px !important; + } + + .productcard { + position: relative; + + .info-card { + bottom: 42px; // controls overlap depth + left: 50%; + transform: translateX(-50%); + width: 90%; + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + z-index: 2; + } + } + + } +} \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts new file mode 100644 index 0000000..c933f20 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ImageSliderComponent } from './image-slider.component'; + +describe('ImageSliderComponent', () => { + let component: ImageSliderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ImageSliderComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ImageSliderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.ts b/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.ts new file mode 100644 index 0000000..d5db5ee --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/image-slider/image-slider.component.ts @@ -0,0 +1,39 @@ +import { Component, computed, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { team } from '../front-pagesData'; + +@Component({ + selector: 'app-image-slider', + imports: [MaterialModule,IconModule], + templateUrl: './image-slider.component.html', + styleUrl: './image-slider.component.scss' +}) +export class ImageSliderComponent { + team = team; + // Signals + currentPage = signal(0); + pageSize = 4; + + visibleTeamMembers = computed(() => { + const start = this.currentPage() * this.pageSize; + const end = start + this.pageSize; + return this.team.slice(start, end); + }); + + next() { + console.log('next--->',this.visibleTeamMembers().map(m => m.id)); + const totalPages = Math.ceil(this.team.length / this.pageSize); + if (this.currentPage() < totalPages - 1) { + this.currentPage.update((p) => p + 1); + } + } + + prev() { + console.log(this.visibleTeamMembers().map(m => m.id)); + if (this.currentPage() > 0) { + this.currentPage.update((p) => p - 1); + } + } + +} diff --git a/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.html b/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.html new file mode 100644 index 0000000..32bdd60 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.html @@ -0,0 +1,68 @@ +
+
+

+ 111,476+ Trusted developers & many tech giants as well +

+
+
+
+ @for(plan of plans;track plan){ +
+ + + +
+
+ {{ plan.title }} + @if (plan.popular) { + + Popular + + } +
+
+

{{ plan.description }}

+ + +
+ ${{ plan.price }} + /{{ plan.period }} +
+
+ @for(feature of plan.features; track feature) { +
+ icon-facebook-dark + + + {{ feature.text }} + +
+ } +
+ + +
+
+ +
+ } + + +
+
+

Secured payment with PayPal & Razorpay

+
+ @for( logo of paymentLogos;track logo){ + + } +
+
\ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.scss b/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts new file mode 100644 index 0000000..fb0a9c8 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PagePricingComponent } from './page-pricing.component'; + +describe('PagePricingComponent', () => { + let component: PagePricingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PagePricingComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PagePricingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.ts b/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.ts new file mode 100644 index 0000000..7a435ae --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/page-pricing/page-pricing.component.ts @@ -0,0 +1,17 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { paymentLogos, plans } from '../front-pagesData'; + +@Component({ + selector: 'app-page-pricing', + imports: [MaterialModule, IconModule, CommonModule], + templateUrl: './page-pricing.component.html', + styleUrl: './page-pricing.component.scss', +}) +export class PagePricingComponent { + plans = plans; + + paymentLogos = paymentLogos; +} diff --git a/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.html b/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.html new file mode 100644 index 0000000..f64670b --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.html @@ -0,0 +1,57 @@ + + +
+
+
+
+
Portfolio
+
+
{{ filteredCount }}
+
+
+ + + + search + + +
+
+ @for(productcard of filteredCardImgs; track productcard.id) { +
+ + + imgSrc + + + +
+ +
+
{{ productcard.title }}
+

{{ productcard.date }}

+
+ + + +
+
+
+
+
+ } +
+
+
+ \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.scss b/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts new file mode 100644 index 0000000..073ce35 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PortfolioComponent } from './portfolio.component'; + +describe('PortfolioComponent', () => { + let component: PortfolioComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PortfolioComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PortfolioComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.ts b/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.ts new file mode 100644 index 0000000..702ebee --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/portfolio/portfolio.component.ts @@ -0,0 +1,37 @@ + + +import { Component, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { productcards } from '../front-pagesData'; +import { FooterComponent } from '../footer/footer.component'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-portfolio', + imports: [MaterialModule, IconModule, FooterComponent, CommonModule, FormsModule], + templateUrl: './portfolio.component.html', + styleUrl: './portfolio.component.scss' +}) +export class PortfolioComponent implements OnInit { + + filteredCards = productcards; + + searchText: string = ''; + + filteredCardImgs = [...this.filteredCards]; // Initialize with full data + filteredCount: number = this.filteredCardImgs.length; + ngOnInit(): void { + console.log('filteredCards', this.filteredCards) + } + onSearchChange() { + const query = this.searchText.toLowerCase().trim(); + this.filteredCardImgs = this.filteredCards.filter(item => + item.title.toLowerCase().includes(query) || + item.date.toLowerCase().includes(query) + ); + this.filteredCount = this.filteredCardImgs.length; // ✅ update the count here + } +} + diff --git a/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.html b/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.html new file mode 100644 index 0000000..6c42e4a --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.html @@ -0,0 +1,18 @@ + + +
+
+ +
+
+ + \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.scss b/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.spec.ts new file mode 100644 index 0000000..147f94e --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PricingComponent } from './pricing.component'; + +describe('PricingComponent', () => { + let component: PricingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PricingComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PricingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.ts b/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.ts new file mode 100644 index 0000000..0684d59 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/pricing/pricing.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; +import { PagePricingComponent } from '../page-pricing/page-pricing.component'; + +@Component({ + selector: 'app-pricing', + imports: [MaterialModule,IconModule,FooterComponent,PagePricingComponent], + templateUrl: './pricing.component.html', + styleUrl: './pricing.component.scss' +}) +export class PricingComponent { + +} diff --git a/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.html b/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.html new file mode 100644 index 0000000..9b7d777 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.html @@ -0,0 +1,11 @@ + + + +
+ + +
\ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.scss b/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.spec.ts b/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.spec.ts new file mode 100644 index 0000000..46d7589 --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TemplateVideoComponent } from './template-video.component'; + +describe('TemplateVideoComponent', () => { + let component: TemplateVideoComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TemplateVideoComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TemplateVideoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.ts b/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.ts new file mode 100644 index 0000000..b239adb --- /dev/null +++ b/theme/packages/dark/src/app/pages/front-pages/template-video/template-video.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { MatDialogRef } from '@angular/material/dialog'; +@Component({ + selector: 'app-template-video', + imports: [MaterialModule, + IconModule,], + templateUrl: './template-video.component.html', + styleUrl: './template-video.component.scss' +}) +export class TemplateVideoComponent { +constructor(private dialogRef: MatDialogRef){ + +} +closeDialog(): void { + this.dialogRef.close(false); // Pass false back to parent +} +} diff --git a/theme/packages/dark/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts b/theme/packages/dark/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts new file mode 100644 index 0000000..de7ba0c --- /dev/null +++ b/theme/packages/dark/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts @@ -0,0 +1,69 @@ +export const BASIC_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + + /** + * @title slide-toggle + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatSlideToggleModule], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + } +`; + +export const FORM_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component, inject} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {FormBuilder, FormGroup, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {MatButtonModule} from '@angular/material/button'; + import { MatSlideToggleModule} from '@angular/material/slide-toggle'; + + /** + * @title Slide-toggle with forms + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatSlideToggleModule, FormsModule, MatButtonModule, ReactiveFormsModule,], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + + private _formBuilder = inject(FormBuilder); + + isChecked = true; + formGroup = this._formBuilder.group({ + enableWifi: '', + acceptTerms: ['', Validators.requiredTrue], + }); + + alertFormValues(formGroup: FormGroup) { + alert(JSON.stringify(formGroup.value, null, 2)); + } + } +`; + +export const CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {MatCheckboxModule} from '@angular/material/checkbox'; + import {FormsModule} from '@angular/forms'; + import {MatRadioModule} from '@angular/material/radio'; + import {MatCardModule} from '@angular/material/card'; + + /** + * @title Configurable slide-toggle + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatCardModule, MatRadioModule, FormsModule, MatCheckboxModule, MatSlideToggleModule], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + + checked = false; + disabled = false; + } +`; \ No newline at end of file diff --git a/theme/packages/dark/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts b/theme/packages/dark/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts new file mode 100644 index 0000000..804e79f --- /dev/null +++ b/theme/packages/dark/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts @@ -0,0 +1,63 @@ +import { Component, OnInit, inject } from '@angular/core'; +import {FormBuilder, FormGroup, Validators, ReactiveFormsModule} from '@angular/forms'; +import { + MatSlideToggleModule, + // _MatSlideToggleRequiredValidatorModule, +} from '@angular/material/slide-toggle'; +import {MatCheckboxModule} from '@angular/material/checkbox'; +import {FormsModule} from '@angular/forms'; +import {MatRadioModule} from '@angular/material/radio'; +import {MatCardModule} from '@angular/material/card'; +import {MatButtonModule} from '@angular/material/button'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_SLIDE_TOGGLE_HTML_SNIPPET, CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET, FORM_SLIDE_TOGGLE_HTML_SNIPPET } from './code/slide-toggle-html-snippet'; +import { BASIC_SLIDE_TOGGLE_TS_SNIPPET, CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET, FORM_SLIDE_TOGGLE_TS_SNIPPET } from './code/slide-toggle-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-slide-toggle', + imports: [MatCardModule, MatRadioModule, FormsModule, MatCheckboxModule, MatSlideToggleModule, ReactiveFormsModule, MatButtonModule, + // _MatSlideToggleRequiredValidatorModule + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './slide-toggle.component.html' +}) +export class AppSlideToggleComponent implements OnInit { + + // 1 [Basic with Slide Toggle] + codeForSlideToggleBasic = BASIC_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleBasicTs = BASIC_SLIDE_TOGGLE_TS_SNIPPET; + + // 2 [Form with Slide Toggle] + codeForSlideToggleForm = FORM_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleFormTs = FORM_SLIDE_TOGGLE_TS_SNIPPET; + + // 3 [Configuration with Slide Toggle] + codeForSlideToggleConfiguration = CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleConfigurationTs = CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET; + + // configuration + checked = false; + disabled = false; + + private _formBuilder = inject(FormBuilder); + + isChecked = true; + formGroup = this._formBuilder.group({ + enableWifi: '', + acceptTerms: ['', Validators.requiredTrue], + }); + + alertFormValues(formGroup: FormGroup) { + alert(JSON.stringify(formGroup.value, null, 2)); + } + + ngOnInit(): void {} +} diff --git a/theme/packages/dark/src/app/pages/widgets/cards/cards.component.html b/theme/packages/dark/src/app/pages/widgets/cards/cards.component.html new file mode 100644 index 0000000..051c1c9 --- /dev/null +++ b/theme/packages/dark/src/app/pages/widgets/cards/cards.component.html @@ -0,0 +1,348 @@ + + + + +
+ @for(topcard of topcards; track topcard) { +
+ + + users +

+ {{ topcard.title }} +

+
+ {{ topcard.subtitle }} +
+
+
+
+ } +
+ + + + +
+ @for(cardimg of cardimgs; track cardimg.imgSrc) { +
+ + Photo of a Shiba Inu +
+ {{ + cardimg.time + }} +
+ + +
+
+ +
+ {{ + cardimg.category + }} +
+ {{ cardimg.title }} +
+
+ {{ cardimg.views }} + {{ cardimg.comments }} +
+ + + {{ cardimg.date }} + +
+
+
+
+ } +
+ + + + +
+ @for(productcard of productcards; track productcard.title) { +
+ + + imgSrc + + + + {{ + productcard.title + }} +
+
+
${{ productcard.price }}
+ ${{ productcard.rprice }} +
+
+ + + + + +
+
+
+
+
+ } +
+ + + + +
+ @for(musiccard of musiccards; track musiccard.title) { +
+ +
+
+
{{ musiccard.title }}
+ {{ musiccard.subtext }} + +
+ + + +
+
+
+ blog +
+
+
+
+ } +
+ + + + +
+ @for(followercard of followercards; track followercard.title) { +
+ + +
+
+ user +
+
{{ followercard.title }}
+ {{ followercard.subtext }} +
+
+ +
+
+
+
+ } +
+ + + + +
+ @for(friendcard of friendcards; track friendcard.title) { +
+ + + user + {{ friendcard.title }} +
+
+ user + user + user +
+ 3 mutual friends +
+ + +
+
+
+ } +
+ + + + +
+ @for(socialcard of socialcards; track socialcard.username) { +
+ + + + {{ + socialcard.username + }} + {{ + socialcard.post + }} + +
+ + + + +
+
+
+ } +
+ + + + +
+ @for(giftcard of giftcards; track giftcard.username) { +
+ + +
+ {{ + giftcard.username + }} + +
+ + user + + +
+
+
+ } +
+ +
+ +
+ + + Payment Gateways + Platform For Income + + @for(stat of stats; track stat.title) { +
+
+ + icon + + +
+
{{ stat.title }}
+ {{ stat.subtitle }} +
+ +${{ stat.percent }} +
+
+ } + + +
+
+
+ + +
+ + + Upcoming Activity + In New year + + @for(activity of activities; track activity.title) { +
+
+ + + + +
+
{{ activity.title }}
+ {{ activity.subtitle }} +
+ {{ activity.time }} +
+
+ } +
+
+
+ + +
+ + + Recent Transactions + +
+ @for(stat of stats2; track stat.subtext) { +
+
{{ stat.time }}
+
+ + +
+
+ @if(stat.subtext) { + {{ stat.subtext }} + } + + @if(stat.title) { + {{ + stat.title + }} + } + + @if(stat.link) { + #ML-3467 + } +
+
+ } +
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/dark/src/app/services/apps/front-pages/front-end.service.spec.ts b/theme/packages/dark/src/app/services/apps/front-pages/front-end.service.spec.ts new file mode 100644 index 0000000..950ecc8 --- /dev/null +++ b/theme/packages/dark/src/app/services/apps/front-pages/front-end.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { FrontEndService } from './front-end.service'; + +describe('FrontEndService', () => { + let service: FrontEndService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(FrontEndService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/theme/packages/dark/src/app/services/apps/front-pages/front-end.service.ts b/theme/packages/dark/src/app/services/apps/front-pages/front-end.service.ts new file mode 100644 index 0000000..a736e66 --- /dev/null +++ b/theme/packages/dark/src/app/services/apps/front-pages/front-end.service.ts @@ -0,0 +1,21 @@ +import { Injectable, signal } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class FrontEndService { + + private blog = signal(null); + + constructor() { } + + + + setBlog(blogData: any) { + this.blog.set(blogData); + } + + getBlog() { + return this.blog; + } +} diff --git a/theme/packages/dark/src/assets/images/front-pages/app-chat.jpg b/theme/packages/dark/src/assets/images/front-pages/app-chat.jpg new file mode 100644 index 0000000..cffde47 Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/app-chat.jpg differ diff --git a/theme/packages/dark/src/assets/images/front-pages/app-email.jpg b/theme/packages/dark/src/assets/images/front-pages/app-email.jpg new file mode 100644 index 0000000..5da2d90 Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/app-email.jpg differ diff --git a/theme/packages/dark/src/assets/images/front-pages/banner-top-left.svg b/theme/packages/dark/src/assets/images/front-pages/banner-top-left.svg new file mode 100644 index 0000000..0b5d123 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/banner-top-left.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/banner-top-right.svg b/theme/packages/dark/src/assets/images/front-pages/banner-top-right.svg new file mode 100644 index 0000000..ce2deff --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/banner-top-right.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/bottom-part.svg b/theme/packages/dark/src/assets/images/front-pages/bottom-part.svg new file mode 100644 index 0000000..0a9f8f9 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/bottom-part.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/demo-dark.jpg b/theme/packages/dark/src/assets/images/front-pages/demo-dark.jpg new file mode 100644 index 0000000..1181c96 Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/demo-dark.jpg differ diff --git a/theme/packages/dark/src/assets/images/front-pages/demo-horizontal.jpg b/theme/packages/dark/src/assets/images/front-pages/demo-horizontal.jpg new file mode 100644 index 0000000..a384d56 Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/demo-horizontal.jpg differ diff --git a/theme/packages/dark/src/assets/images/front-pages/demo-main.jpg b/theme/packages/dark/src/assets/images/front-pages/demo-main.jpg new file mode 100644 index 0000000..895551e Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/demo-main.jpg differ diff --git a/theme/packages/dark/src/assets/images/front-pages/demo-rtl.jpg b/theme/packages/dark/src/assets/images/front-pages/demo-rtl.jpg new file mode 100644 index 0000000..a8011a3 Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/demo-rtl.jpg differ diff --git a/theme/packages/dark/src/assets/images/front-pages/design-collection.png b/theme/packages/dark/src/assets/images/front-pages/design-collection.png new file mode 100644 index 0000000..08a4a50 Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/design-collection.png differ diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-american-express.svg b/theme/packages/dark/src/assets/images/front-pages/icon-american-express.svg new file mode 100644 index 0000000..0cc1e3c --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-american-express.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-chart.svg b/theme/packages/dark/src/assets/images/front-pages/icon-chart.svg new file mode 100644 index 0000000..fa45961 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-chart.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-circle-check.svg b/theme/packages/dark/src/assets/images/front-pages/icon-circle-check.svg new file mode 100644 index 0000000..458ffdb --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-circle-check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-circle-x.svg b/theme/packages/dark/src/assets/images/front-pages/icon-circle-x.svg new file mode 100644 index 0000000..41b5593 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-circle-x.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-color.svg b/theme/packages/dark/src/assets/images/front-pages/icon-color.svg new file mode 100644 index 0000000..14d5f1a --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-color.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-components.svg b/theme/packages/dark/src/assets/images/front-pages/icon-components.svg new file mode 100644 index 0000000..a14b4e4 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-components.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-customize.svg b/theme/packages/dark/src/assets/images/front-pages/icon-customize.svg new file mode 100644 index 0000000..300ee35 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-customize.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-diners.svg b/theme/packages/dark/src/assets/images/front-pages/icon-diners.svg new file mode 100644 index 0000000..4ea5609 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-diners.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-discover.svg b/theme/packages/dark/src/assets/images/front-pages/icon-discover.svg new file mode 100644 index 0000000..12eebd5 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-discover.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-facebook.svg b/theme/packages/dark/src/assets/images/front-pages/icon-facebook.svg new file mode 100644 index 0000000..d0cfd8a --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-facebook.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-favorites.svg b/theme/packages/dark/src/assets/images/front-pages/icon-favorites.svg new file mode 100644 index 0000000..84fedaa --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-favorites.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-framework.svg b/theme/packages/dark/src/assets/images/front-pages/icon-framework.svg new file mode 100644 index 0000000..2718d0c --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-framework.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-icons.svg b/theme/packages/dark/src/assets/images/front-pages/icon-icons.svg new file mode 100644 index 0000000..87d1ae4 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-icons.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-instagram.svg b/theme/packages/dark/src/assets/images/front-pages/icon-instagram.svg new file mode 100644 index 0000000..6a73bf9 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-instagram.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-jcb.svg b/theme/packages/dark/src/assets/images/front-pages/icon-jcb.svg new file mode 100644 index 0000000..b71e935 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-jcb.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-masetro.svg b/theme/packages/dark/src/assets/images/front-pages/icon-masetro.svg new file mode 100644 index 0000000..5a84358 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-masetro.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-mastercard.svg b/theme/packages/dark/src/assets/images/front-pages/icon-mastercard.svg new file mode 100644 index 0000000..da591ae --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-mastercard.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-pages.svg b/theme/packages/dark/src/assets/images/front-pages/icon-pages.svg new file mode 100644 index 0000000..ac7ca4b --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-pages.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-paypal.svg b/theme/packages/dark/src/assets/images/front-pages/icon-paypal.svg new file mode 100644 index 0000000..7f8de85 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-paypal.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-responsive.svg b/theme/packages/dark/src/assets/images/front-pages/icon-responsive.svg new file mode 100644 index 0000000..fc57366 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-responsive.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-sass.svg b/theme/packages/dark/src/assets/images/front-pages/icon-sass.svg new file mode 100644 index 0000000..5751e1a --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-sass.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-sidebar.svg b/theme/packages/dark/src/assets/images/front-pages/icon-sidebar.svg new file mode 100644 index 0000000..1a0ca63 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-sidebar.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-speech-bubble.svg b/theme/packages/dark/src/assets/images/front-pages/icon-speech-bubble.svg new file mode 100644 index 0000000..2e1f2bd --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-speech-bubble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-support.svg b/theme/packages/dark/src/assets/images/front-pages/icon-support.svg new file mode 100644 index 0000000..6aa77a3 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-support.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-table.svg b/theme/packages/dark/src/assets/images/front-pages/icon-table.svg new file mode 100644 index 0000000..3fd98d7 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-table.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-twitter.svg b/theme/packages/dark/src/assets/images/front-pages/icon-twitter.svg new file mode 100644 index 0000000..e0b7780 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-twitter.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-update.svg b/theme/packages/dark/src/assets/images/front-pages/icon-update.svg new file mode 100644 index 0000000..94b5ed9 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-update.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/icon-visa.svg b/theme/packages/dark/src/assets/images/front-pages/icon-visa.svg new file mode 100644 index 0000000..7a06b63 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/icon-visa.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/front-pages/logoIcon.svg b/theme/packages/dark/src/assets/images/front-pages/logoIcon.svg new file mode 100644 index 0000000..90fdce0 --- /dev/null +++ b/theme/packages/dark/src/assets/images/front-pages/logoIcon.svg @@ -0,0 +1,11 @@ + + logoIcon + + + + + + \ No newline at end of file diff --git a/theme/packages/dark/src/assets/images/front-pages/topbar-bg.png b/theme/packages/dark/src/assets/images/front-pages/topbar-bg.png new file mode 100644 index 0000000..e11b4a5 Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/topbar-bg.png differ diff --git a/theme/packages/dark/src/assets/images/front-pages/user1.jpg b/theme/packages/dark/src/assets/images/front-pages/user1.jpg new file mode 100644 index 0000000..eb505b5 Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/user1.jpg differ diff --git a/theme/packages/dark/src/assets/images/front-pages/user2.jpg b/theme/packages/dark/src/assets/images/front-pages/user2.jpg new file mode 100644 index 0000000..f8aa6af Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/user2.jpg differ diff --git a/theme/packages/dark/src/assets/images/front-pages/user3.jpg b/theme/packages/dark/src/assets/images/front-pages/user3.jpg new file mode 100644 index 0000000..6478013 Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/user3.jpg differ diff --git a/theme/packages/dark/src/assets/images/front-pages/user4.jpg b/theme/packages/dark/src/assets/images/front-pages/user4.jpg new file mode 100644 index 0000000..e599b2a Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/user4.jpg differ diff --git a/theme/packages/dark/src/assets/images/front-pages/user5.jpg b/theme/packages/dark/src/assets/images/front-pages/user5.jpg new file mode 100644 index 0000000..494e402 Binary files /dev/null and b/theme/packages/dark/src/assets/images/front-pages/user5.jpg differ diff --git a/theme/packages/dark/src/assets/images/landingpage/background/accordian1.jpg b/theme/packages/dark/src/assets/images/landingpage/background/accordian1.jpg new file mode 100644 index 0000000..d13def2 Binary files /dev/null and b/theme/packages/dark/src/assets/images/landingpage/background/accordian1.jpg differ diff --git a/theme/packages/dark/src/assets/images/landingpage/background/design-collection.png b/theme/packages/dark/src/assets/images/landingpage/background/design-collection.png new file mode 100644 index 0000000..2886a14 Binary files /dev/null and b/theme/packages/dark/src/assets/images/landingpage/background/design-collection.png differ diff --git a/theme/packages/dark/src/assets/images/landingpage/background/feature-apps.png b/theme/packages/dark/src/assets/images/landingpage/background/feature-apps.png new file mode 100644 index 0000000..fef18c5 Binary files /dev/null and b/theme/packages/dark/src/assets/images/landingpage/background/feature-apps.png differ diff --git a/theme/packages/dark/src/assets/images/landingpage/background/screen1.png b/theme/packages/dark/src/assets/images/landingpage/background/screen1.png new file mode 100644 index 0000000..afd642a Binary files /dev/null and b/theme/packages/dark/src/assets/images/landingpage/background/screen1.png differ diff --git a/theme/packages/dark/src/assets/images/landingpage/frameworks/angular.svg b/theme/packages/dark/src/assets/images/landingpage/frameworks/angular.svg new file mode 100644 index 0000000..bf081ac --- /dev/null +++ b/theme/packages/dark/src/assets/images/landingpage/frameworks/angular.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/theme/packages/dark/src/assets/images/landingpage/frameworks/icon-tabler.svg b/theme/packages/dark/src/assets/images/landingpage/frameworks/icon-tabler.svg new file mode 100644 index 0000000..6e6810e --- /dev/null +++ b/theme/packages/dark/src/assets/images/landingpage/frameworks/icon-tabler.svg @@ -0,0 +1,3 @@ + + + diff --git a/theme/packages/dark/src/assets/images/landingpage/frameworks/material.svg b/theme/packages/dark/src/assets/images/landingpage/frameworks/material.svg new file mode 100644 index 0000000..9ac2836 --- /dev/null +++ b/theme/packages/dark/src/assets/images/landingpage/frameworks/material.svg @@ -0,0 +1 @@ +material \ No newline at end of file diff --git a/theme/packages/dark/src/assets/images/profile/user-11.jpg b/theme/packages/dark/src/assets/images/profile/user-11.jpg new file mode 100644 index 0000000..8d54dc0 Binary files /dev/null and b/theme/packages/dark/src/assets/images/profile/user-11.jpg differ diff --git a/theme/packages/dark/src/assets/images/profile/user-12.jpg b/theme/packages/dark/src/assets/images/profile/user-12.jpg new file mode 100644 index 0000000..adbbde4 Binary files /dev/null and b/theme/packages/dark/src/assets/images/profile/user-12.jpg differ diff --git a/theme/packages/dark/src/assets/scss/_container.scss b/theme/packages/dark/src/assets/scss/_container.scss new file mode 100644 index 0000000..730c06f --- /dev/null +++ b/theme/packages/dark/src/assets/scss/_container.scss @@ -0,0 +1,154 @@ +@use "variables" as *; + +*, +:after, +:before { + box-sizing: border-box; +} + +body { + font-family: $font-family; + line-height: 1.334rem; + overflow-x: hidden; + color: var(--mat-sys-on-background); +} + +.mainWrapper { + display: flex; + min-height: 100vh; + width: 100%; + flex: 1; + height: 100%; +} + +.container { + max-width: 1200px; + padding-left: 24px; + padding-right: 24px; + margin: 0 auto; + + &.full-width { + display: flex; + align-items: center; + width: 100%; + } +} + +.pageWrapper { + padding: 24px; + min-height: calc(100vh - 70px); + + margin: 0 auto; + + &.maxWidth { + max-width: $boxedWidth; + } +} + +.w-100 { + width: 100%; +} + +.h-100 { + height: 100%; +} + +.shadow-none { + box-shadow: none !important; +} + +.rounded { + border-radius: $border-radius !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 25px !important; +} + +.overflow-hidden { + overflow: hidden; +} + +.text-decoration-none { + text-decoration: none; +} + +.position-relative { + position: relative; +} + +.table-responsive { + overflow-x: auto; + + td, + mat-cell { + white-space: nowrap; + padding: 16px; + } +} + +.op-5 { + opacity: 0.5; +} + +.cursor-pointer { + cursor: pointer; +} + +.avatar-group { + img { + border: 2px solid $white; + margin-right: -5px; + + &:last-child { + margin-right: 0; + } + } +} + +a { + color: var(--mat-sys-on-background); + + &:hover { + color: $primary; + } +} + +.filter-sidebar { + width: 290px; + position: fixed; + right: -290px; + top: 0; + z-index: 10; + height: 100%; + transition: all 0.3s ease-in-out; + box-shadow: var(--mat-sys-level3); + background-color: var(--mat-sys-background); + + &.open { + right: 0; + } +} + +pre { + margin: 0; + white-space: nowrap; +} + +td.hljs-ln-line.hljs-ln-numbers { + padding-right: 10px; +} + +@media (min-width: 768px) { + html .flex-sm-row { + flex-direction: row !important; + } +} + +.mat-drawer[style*="visibility: hidden"] { + display: none; +} \ No newline at end of file diff --git a/theme/packages/dark/src/assets/scss/apps/_contact-list.scss b/theme/packages/dark/src/assets/scss/apps/_contact-list.scss new file mode 100644 index 0000000..9cf1b85 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/apps/_contact-list.scss @@ -0,0 +1,59 @@ +@use "../variables" as *; + +@media (max-width: 1279px) { + .detail-part.movetodetail { + display: block; + position: absolute; + z-index: 9; + left: 0; + background: var(--mat-card-elevated-container-color); + } +} + +@media (max-width: 1279px) { + .welcome-app { + display: none; + } +} + +@media (max-width: 959px) { + .contact-detail-part { + display: none; + } + + .contact-detail-part.activeContact { + position: absolute !important; + top: 0; + left: 0; + display: block; + width: 100%; + height: 100%; + z-index: 999; + background-color: var(--mat-card-elevated-container-color); + } +} + +// contact app +.uploader { + .upload-image { + width: 100px; + height: auto; + cursor: pointer; + } + + input[type="file"] { + position: absolute; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + } +} + +.contact-listing { + .mdc-list-item__primary-text { + margin-bottom: -11px !important; + margin-top: 10px !important; + } +} diff --git a/theme/packages/dark/src/assets/scss/apps/_ecommerce.scss b/theme/packages/dark/src/assets/scss/apps/_ecommerce.scss new file mode 100644 index 0000000..467169d --- /dev/null +++ b/theme/packages/dark/src/assets/scss/apps/_ecommerce.scss @@ -0,0 +1,94 @@ +body { + + // Add Product + + .NgxEditor__Wrapper { + border: 1px solid var(--mat-sys-outline-variant); + } + + .NgxEditor__Seperator { + border-left: 1px solid var(--mat-sys-outline-variant); + } + + .NgxEditor__MenuBar { + background-color: var(--mat-card-elevated-container-color); + border-bottom: 1px solid var(--mat-sys-outline-variant) !important; + } + + .NgxEditor { + background: var(--mat-card-elevated-container-color); + color: var(--mat-sys-on-background); + } + + .NgxEditor__MenuItem .NgxEditor__MenuItem--Icon:hover { + background-color: var(--mat-sys-primary); + color: var(--mat-sys-background); + } + + .NgxEditor__Dropdown:hover { + background-color: var(--mat-sys-primary); + + .NgxEditor__Dropdown--Text { + color: var(--mat-sys-background); + } + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--Selected, + .NgxEditor__Dropdown .NgxEditor__Dropdown--Open { + color: var(--mat-sys-background); + background-color: var(--mat-sys-primary); + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--Item:hover { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--DropdownMenu { + background-color: var(--mat-card-elevated-container-color); + } + + + .dropzone-box { + border: 1px dashed var(--mat-sys-primary); + background-color: var(--mat-sys-primary-fixed-dim); + + .dropzone-content { + .preview-image { + width: 100px; + height: 70px; + object-fit: cover; + border-radius: 6px; + margin-bottom: 0.5rem; + } + } + + .headline { + margin: 0; + } + } + + .cards-circle { + width: 15px; + height: 15px; + border-radius: var(--mat-sys-corner-full); + display: flex; + align-items: center; + justify-content: center; + background-color: var(--mat-sys-primary); + + .theme-icon { + display: none; + } + + &.selected { + .theme-icon { + display: block; + color: white; + width: 18px; + height: 25px; + } + } + } + +} \ No newline at end of file diff --git a/theme/packages/dark/src/assets/scss/helpers/_custom-flex.scss b/theme/packages/dark/src/assets/scss/helpers/_custom-flex.scss new file mode 100644 index 0000000..fb36a29 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/helpers/_custom-flex.scss @@ -0,0 +1,59 @@ +@media (min-width: 1200px) { + body { + .d-lg-flex { + display: flex !important; + } + + .d-lg-none { + display: none !important; + } + + .d-lg-block { + display: block !important; + } + + .align-items-lg-center { + align-items: center !important; + } + } +} + +@media (min-width: 960px) { + .d-md-none { + display: none !important; + } +} + +@media (min-width: 768px) { + body { + .d-sm-flex { + display: flex !important; + } + } +} + +@media (max-width: 767px) { + .p-xs-6 { + padding: 0 6px !important; + } +} + +.flex-shrink-0 { + flex-shrink: 0; +} + +.flex-1-auto { + flex: 1 1 0%; +} + +.hstack { + display: flex; + flex-direction: row; + gap: 20px; +} + +@media (max-width: 767px) { + .hstack { + flex-direction: column; + } +} \ No newline at end of file diff --git a/theme/packages/dark/src/assets/scss/helpers/_icon-size.scss b/theme/packages/dark/src/assets/scss/helpers/_icon-size.scss new file mode 100644 index 0000000..ac526ef --- /dev/null +++ b/theme/packages/dark/src/assets/scss/helpers/_icon-size.scss @@ -0,0 +1,15 @@ +@use "sass:meta"; + +$columns: 54; + +@mixin icon_size { + @for $i from 1 through $columns { + .icon-#{$i} { + height: #{$i}px !important; + width: #{$i}px !important; + line-height: #{$i + 8}px !important; + } + } +} + +@include icon_size; diff --git a/theme/packages/dark/src/assets/scss/helpers/_text.scss b/theme/packages/dark/src/assets/scss/helpers/_text.scss new file mode 100644 index 0000000..1c2636e --- /dev/null +++ b/theme/packages/dark/src/assets/scss/helpers/_text.scss @@ -0,0 +1,84 @@ +@use "sass:map"; +@use "variables"; + +$utilities: ( + "font-size": ( + property: font-size, + class: f-s, + values: variables.$font-sizes, + ), + "font-weight": ( + property: font-weight, + class: f-w, + values: variables.$font-wieghts, + ), + "font-style": ( + property: font-style, + class: font, + values: italic normal, + ), + "text-align": ( + property: text-align, + class: text, + values: center right left, + ), + "text-decoration": ( + property: text-decoration, + class: text, + values: none underline line-through, + ), + "text-transform": ( + property: text-transform, + class: text, + values: capitalize uppercase lowercase, + ), + "white-space": ( + property: white-space, + class: text, + values: ( + wrap: normal, + nowrap: nowrap, + ), + ), + "word-wrap": ( + property: word-wrap word-break, + class: text, + values: ( + break: break-word, + ), + ), + "text-overflow": ( + property: text-overflow, + class: text, + values: ellipsis, + ), + "text-color": ( + property: color, + class: text, + values: ( + reset: inherit, + current: currentColor, + ), + ), +); + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0px; +} + +.lh-lg { + line-height: 36px !important; +} + +.lh-sm { + line-height: 20px !important; +} + +.lh-normal { + line-height: normal !important; +} \ No newline at end of file diff --git a/theme/packages/dark/src/assets/scss/helpers/_variables.scss b/theme/packages/dark/src/assets/scss/helpers/_variables.scss new file mode 100644 index 0000000..844ddf4 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/helpers/_variables.scss @@ -0,0 +1,102 @@ +@use "functions" as *; + +// Utility Map + +$utilities: () !default; + +// Spacing + +$spacer: 16px !default; +$spacers: ( + 0: 0, + 2: $spacer * 0.125, + 4: $spacer * 0.25, + 5: 5px, + 6: 7px, + 8: $spacer * 0.5, + 10: 10px, + 12: $spacer * 0.75, + 14: 14px, + 15: 15px, + 16: $spacer, + 20: 20px, + 24: $spacer * 1.5, + 30: 30px, + 32: $spacer * 2, + 44: 44px, + 48: $spacer * 3, + 60: 60px, + 66: 66px, + 80: 80px, +) !default; +$negative-spacers: negativify-map($spacers) !default; + +// Border + +$border-color: var(--mat-sys-outline-variant) !default; +$borders: ( + 0: 0, + 1: 1px solid $border-color, + 2: 2px solid $border-color, + 4: 4px solid $border-color, + 8: 8px solid $border-color, +) !default; + +// Border radius + +$radius-base: 7px !default; +$radius: ( + 0: 0, + 7: $radius-base, + 8: $radius-base * 2, + 12: $radius-base * 3, + 16: $radius-base * 4, + full: 9999px, +) !default; + +// Text + +$font-wieghts: ( + 100: 100, + 200: 200, + 300: 300, + 400: 400, + 500: 500, + 600: 600, + 700: 700, + 800: 800, + 900: 900, +) !default; + +$font-sizes: ( + 0: 0, + 10: 10px, + 12: 12px, + 14: 14px, + 15: 15px, + 16: 16px, + 18: 18px, + 20: 20px, + 21: 21px, + 24: 24px, + 28: 28px, + 30: 30px, + 36: 36px, + 40: 40px, + 48: 48px, +) !default; + +// Sizing + +$sizes: ( + 0: 0, + 20: 20%, + 25: 25%, + 40: 40%, + 50: 50%, + 60: 60%, + 75: 75%, + 80: 80%, + full: 100%, + auto: auto, +) !default; diff --git a/theme/packages/dark/src/assets/scss/layouts/_header.scss b/theme/packages/dark/src/assets/scss/layouts/_header.scss new file mode 100644 index 0000000..d24e1f8 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/layouts/_header.scss @@ -0,0 +1,64 @@ +@use "../variables" as *; + +html .topbar { + position: sticky; + top: 0; + z-index: 9; + height: $header-height; + + .notification-badge{ + .mat-badge-content{ + left: 80%; + bottom: 85%; + width: 16px; + height: 16px; + } + } +} + +.topbar-dd { + min-width: 360px !important; +} + +.apps-dd { + min-width: 830px !important; + overflow: unset !important; + + .mat-mdc-menu-content { + padding: 0; + } +} + +.text-hover-primary:hover { + .hover-text { + color: $primary; + } +} + +.upgrade-bg { + position: absolute; + top: 0px; + right: 0px; + height: 100%; +} + +.object-cover { + object-fit: cover; +} + +.profile-dd { + margin-top: -5px; + margin-left: -5px; +} + +.dark-theme { + .topbar { + .mat-mdc-icon-button { + color: $dark-text-secondary !important; + } + + .mdc-button { + --mat-button-text-label-text-color: $dark-text-secondary !important; + } + } +} \ No newline at end of file diff --git a/theme/packages/dark/src/assets/scss/override-component/_checkbox.scss b/theme/packages/dark/src/assets/scss/override-component/_checkbox.scss new file mode 100644 index 0000000..eba7679 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/override-component/_checkbox.scss @@ -0,0 +1,23 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.checkbox-overrides( + ( + unselected-focus-icon-color: + var(--mat-checkbox-unselected-hover-state-layer-color), + ) +); + +// styles +html { + .mdc-checkbox__background { + border-radius: 4px; + width: 21px; + height: 21px; + border: 1px solid var(--mat-sys-outline); + } + + .mdc-checkbox .mdc-checkbox__native-control:focus ~ .mdc-checkbox__ripple { + background-color: var(--mat-checkbox-unselected-hover-state-layer-color); + } +} diff --git a/theme/packages/dark/src/assets/scss/override-component/_datepicker.scss b/theme/packages/dark/src/assets/scss/override-component/_datepicker.scss new file mode 100644 index 0000000..2686873 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/override-component/_datepicker.scss @@ -0,0 +1,11 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.datepicker-overrides( + ( + calendar-container-background-color: + var(--mat-card-elevated-container-color), + calendar-container-touch-elevation-shadow: var(--mat-sys-level1), + calendar-container-elevation-shadow: var(--mat-sys-level1), + ) +); diff --git a/theme/packages/dark/src/assets/scss/override-component/_expansion.scss b/theme/packages/dark/src/assets/scss/override-component/_expansion.scss new file mode 100644 index 0000000..0c5f781 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/override-component/_expansion.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.expansion-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/dark/src/assets/scss/override-component/_paginator.scss b/theme/packages/dark/src/assets/scss/override-component/_paginator.scss new file mode 100644 index 0000000..35479e7 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/override-component/_paginator.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.paginator-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/dark/src/assets/scss/override-component/_stepper.scss b/theme/packages/dark/src/assets/scss/override-component/_stepper.scss new file mode 100644 index 0000000..6a21bd4 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/override-component/_stepper.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.stepper-overrides( + ( + container-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/dark/src/assets/scss/override-component/_table.scss b/theme/packages/dark/src/assets/scss/override-component/_table.scss new file mode 100644 index 0000000..379ddcd --- /dev/null +++ b/theme/packages/dark/src/assets/scss/override-component/_table.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.table-overrides( + ( + background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/dark/src/assets/scss/override-component/_tree.scss b/theme/packages/dark/src/assets/scss/override-component/_tree.scss new file mode 100644 index 0000000..e755adc --- /dev/null +++ b/theme/packages/dark/src/assets/scss/override-component/_tree.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.tree-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/dark/src/assets/scss/pages/_frontend.scss b/theme/packages/dark/src/assets/scss/pages/_frontend.scss new file mode 100644 index 0000000..db45c10 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/pages/_frontend.scss @@ -0,0 +1,143 @@ +.front-topbar { + &.fixed-topbar { + position: fixed; + top: 0; + width: 100%; + background-color: var(--mat-sys-background) !important; + z-index: 9; + } +} + +.back-to-top { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 999; + transition: opacity 0.3s ease; +} + +.tab-header { + + .profileTabs { + + .mat-mdc-tab { + padding: 30px 16px; + height: auto; + border-right: 1px solid var(--mat-sys-outline); + + &:last-child { + border-right: 0; + } + } + + .mat-mdc-tab-label-container { + border-top-width: 0; + } + } + +} + +.home-page .expansion-panel .mat-expansion-panel-body { + padding: 16px 0; +} + +.faq-accordion { + .mat-expansion-panel-body { + padding: 16px 24px !important; + } +} + +.mobile-sidebar { + .mdc-list { + .mdc-list-item { + .mat-mdc-button { + color: var(--mat-sys-on-background); + min-width: 100%; + justify-content: flex-start; + + &.selected { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); + transition: background-color 0.3s ease; + } + } + } + } +} + + +.spacing-top-bottom { + padding: 80px 0; +} + +.spacing-left-right { + padding: 0 80px; +} + +.spacing-left { + padding-left: 80px; +} + +.spacing-top { + padding-top: 80px; +} + +.spacing-bottom { + padding-bottom: 80px; +} + +@media (max-width: 959px) { + .section-sub-title { + font-size: 30px !important; + } + + .spacing-top-bottom { + padding: 60px 0; + } + + .spacing-left-right { + padding: 0 60px; + } + + .spacing-left { + padding-left: 60px; + } + + .spacing-top { + padding-top: 60px; + } + + .spacing-bottom { + padding-bottom: 60px; + } +} + +@media (max-width: 767px) { + .section-sub-title { + font-size: 24px !important; + } + + .spacing-top-bottom { + padding: 30px 0; + } + + .spacing-left-right { + padding: 0 30px; + } + + .spacing-left { + padding-left: 30px; + } + + .spacing-top { + padding-top: 30px; + } + + .spacing-bottom { + padding-bottom: 30px; + } + + .footer-content .left-side-content { + padding: 30px !important; + } +} \ No newline at end of file diff --git a/theme/packages/dark/src/assets/scss/style.scss b/theme/packages/dark/src/assets/scss/style.scss new file mode 100644 index 0000000..177d3f7 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/style.scss @@ -0,0 +1,51 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@use "themecolors/blue_theme"; +@use "themecolors/orange_theme"; +@use "themecolors/aqua_theme"; +@use "themecolors/cyan_theme"; +@use "themecolors/green_theme"; +@use "themecolors/purple_theme"; + +@use "variables" as *; +@use "override-component"; +@use "theme-variables/default-variables"; +@use "theme-variables/light-theme-variables"; +@use "theme-variables/dark-theme-variables"; + +//container layout +@use "layouts/transitions"; +@use "helpers/color"; +@use "helpers/border-color"; +@use "helpers/icon-size"; +@use "container"; +@use "layouts/layouts"; +@use "grid/grid"; +@use "helpers/custom-flex"; +@use "helpers"; + +// horizontal +@use "horizontal/horizontal"; +@use "dark/dark"; + +// apps +@use "apps/calendar"; +@use "apps/email"; +@use "apps/blogs"; +@use "apps/chat"; +@use "apps/contact-list"; +@use "apps/kanban"; +@use "apps/courses"; +@use "apps/todo"; +@use "apps/ecommerce"; + +@use "pages/auth"; +@use "pages/dashboards"; +@use "pages/landingpage"; +@use "pages/toast"; +@use "pages/pricing"; +@use "pages/frontend"; + +// RTL Theme +@use "rtl/rtl"; \ No newline at end of file diff --git a/theme/packages/dark/src/assets/scss/theme-variables/_dark-theme-variables.scss b/theme/packages/dark/src/assets/scss/theme-variables/_dark-theme-variables.scss new file mode 100644 index 0000000..0375fc4 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/theme-variables/_dark-theme-variables.scss @@ -0,0 +1,32 @@ +@use "@angular/material" as mat; + +html.dark-theme { + color-scheme: dark; + --mat-sys-background: #141a21; + --mat-sys-on-background: rgba(255, 255, 255, 0.9); + --mat-sys-on-primary: #fff; + --mat-sys-surface-bright: #ffffff05; + --mat-sys-surface: #141a21; + --mat-sys-surface-container: #141a21; + --mat-sys-surface-container-low: #141a21; + --mat-sys-outline-variant: #2e3f50; + --mat-sys-outline: #2e3f50; + --mat-form-field-outlined-hover-outline-color: #465670; + --mat-checkbox-unselected-hover-state-layer-color: #19212a; + --mat-menu-item-hover-state-layer-color: #19212a; + --mat-button-toggle-state-layer-color: #19212a; + --mat-option-focus-state-layer-color: #19212a; + --mat-option-hover-state-layer-color: #19212a; + --mat-slide-toggle-unselected-track-color: #19212a; + --mat-stepper-header-focus-state-layer-color: #19212a; + --mat-stepper-header-hover-state-layer-color: #19212a; + --mat-expansion-header-hover-state-layer-color: #19212a; + @include mat.card-overrides((elevated-container-color: #1c252e, + elevated-container-elevation: rgba(0, 0, 0, 0.2) 0px 0px 2px 0px, + subtitle-text-color: rgba(255, 255, 255, 0.67), + )); + @include mat.theme-overrides((level1: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level2: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level3: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + )); +} \ No newline at end of file diff --git a/theme/packages/dark/src/assets/scss/theme-variables/_default-variables.scss b/theme/packages/dark/src/assets/scss/theme-variables/_default-variables.scss new file mode 100644 index 0000000..e3adeb2 --- /dev/null +++ b/theme/packages/dark/src/assets/scss/theme-variables/_default-variables.scss @@ -0,0 +1,12 @@ +html { + --mat-sys-error-fixed-dim: rgba(247, 68, 86, 0.15); + --mat-select-container-elevation-shadow: var(--mat-sys-level3); + --mat-list-list-item-label-text-tracking: 0; + --mat-slide-toggle-track-height: 28px; + --mat-sidenav-container-divider-color: var(--mat-sys-outline-variant); + --mat-dialog-with-actions-content-padding: 20px 24px; + --mat-form-field-container-text-tracking: unset; + --mat-slide-toggle-with-icon-handle-size: 21px; + --mat-badge-text-color: white; + --mat-slide-toggle-selected-with-icon-handle-horizontal-margin: 0 26px; +} \ No newline at end of file diff --git a/theme/packages/dark/src/assets/scss/theme-variables/_light-theme-variables.scss b/theme/packages/dark/src/assets/scss/theme-variables/_light-theme-variables.scss new file mode 100644 index 0000000..735309e --- /dev/null +++ b/theme/packages/dark/src/assets/scss/theme-variables/_light-theme-variables.scss @@ -0,0 +1,23 @@ +html.light-theme { + color-scheme: light; + --mat-sys-corner-small: 7px; + --mat-sys-background: #fff; + --mat-sys-surface-bright: #f2f6fa; + --mat-sys-surface: #fff; + --mat-sys-surface-container: #fff; + --mat-sys-surface-container-low: #fff; + --mat-sys-on-background: #2a3547; + --mat-sys-outline: #d7dde2; + --mat-sys-outline-variant: #d7dde2; + --mat-form-field-outlined-hover-outline-color: #d7dde2; + --mat-checkbox-unselected-hover-state-layer-color: #d7dde2; + --mat-menu-item-hover-state-layer-color: #f6f9fc; + --mat-button-toggle-state-layer-color: #f6f9fc; + --mat-option-focus-state-layer-color: #f6f9fc; + --mat-option-hover-state-layer-color: #f6f9fc; + --mat-slide-toggle-unselected-track-color: #f6f9fc; + --mat-stepper-header-focus-state-layer-color: #f6f9fc; + --mat-stepper-header-hover-state-layer-color: #f6f9fc; + --mat-dialog-supporting-text-color: var(--mat-sys-on-background); + --mat-expansion-header-hover-state-layer-color: #f6f9fc; + } \ No newline at end of file diff --git a/theme/packages/dark/src/index.html b/theme/packages/dark/src/index.html new file mode 100644 index 0000000..344a5f2 --- /dev/null +++ b/theme/packages/dark/src/index.html @@ -0,0 +1,17 @@ + + + + + Modernize Angular 20 Admin Template + + + + + + + + + + + \ No newline at end of file diff --git a/theme/packages/dark/tsconfig.json b/theme/packages/dark/tsconfig.json new file mode 100644 index 0000000..c3587c1 --- /dev/null +++ b/theme/packages/dark/tsconfig.json @@ -0,0 +1,34 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "strictPropertyInitialization": false, + "lib": [ + "ES2022", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true, + } +} diff --git a/theme/packages/horizontal/angular.json b/theme/packages/horizontal/angular.json new file mode 100644 index 0000000..0f19c10 --- /dev/null +++ b/theme/packages/horizontal/angular.json @@ -0,0 +1,126 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "Modernize": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "allowedCommonJsDependencies": ["apexcharts", "bezier-easing", "chance"], + "outputPath": { + "base": "dist/Modernize" + }, + "index": "src/index.html", + "polyfills": ["zone.js"], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": [ + + "src/styles.scss", + "src/assets/scss/style.scss", + "node_modules/ngx-toastr/toastr.css", + "node_modules/angular-calendar/css/angular-calendar.css", + "node_modules/highlight.js/styles/atom-one-dark.min.css" + ], + "scripts": [], + "browser": "src/main.ts" + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "12mb", + "maximumError": "12mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "12mb", + "maximumError": "12mb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "Modernize:build:production" + }, + "development": { + "buildTarget": "Modernize:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular/build:extract-i18n", + "options": { + "buildTarget": "Modernize:build" + } + }, + "test": { + "builder": "@angular/build:karma", + "options": { + "polyfills": ["zone.js", "zone.js/testing"], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], + "scripts": [] + } + } + } + } + }, + "cli": { + "analytics": false + }, + "schematics": { + "@schematics/angular:component": { + "type": "component" + }, + "@schematics/angular:directive": { + "type": "directive" + }, + "@schematics/angular:service": { + "type": "service" + }, + "@schematics/angular:guard": { + "typeSeparator": "." + }, + "@schematics/angular:interceptor": { + "typeSeparator": "." + }, + "@schematics/angular:module": { + "typeSeparator": "." + }, + "@schematics/angular:pipe": { + "typeSeparator": "." + }, + "@schematics/angular:resolver": { + "typeSeparator": "." + } + } +} diff --git a/theme/packages/horizontal/package.json b/theme/packages/horizontal/package.json new file mode 100644 index 0000000..51d6f74 --- /dev/null +++ b/theme/packages/horizontal/package.json @@ -0,0 +1,62 @@ +{ + "name": "modernize", + "version": "3.1.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^20.0.4", + "@angular/cdk": "^20.0.3", + "@angular/common": "^20.0.4", + "@angular/compiler": "^20.0.4", + "@angular/core": "^20.0.4", + "@angular/forms": "^20.0.4", + "@angular/material": "^20.0.3", + "@angular/platform-browser": "^20.0.4", + "@angular/platform-browser-dynamic": "^20.0.4", + "@angular/router": "^20.0.4", + "@ng-matero/extensions": "^20.1.0", + "@ngx-translate/core": "^16.0.4", + "@ngx-translate/http-loader": "^16.0.1", + "angular-calendar": "^0.31.1", + "angular-tabler-icons": "^3.26.0", + "apexcharts": "^4.7.0", + "chance": "^1.1.13", + "date-fns": "^4.1.0", + "highlight.js": "^11.11.1", + "ng-apexcharts": "^1.16.0", + "ng2-search-filter": "^0.5.1", + "ngx-dropzone": "^3.1.0", + "ngx-editor": "^19.0.0-beta.1", + "ngx-highlightjs": "^14.0.1", + "ngx-owl-carousel-o": "^20.0.0", + "ngx-pagination": "^6.0.3", + "ngx-permissions": "^19.0.0", + "ngx-scrollbar": "^18.0.0", + "ngx-toastr": "^19.0.0", + "rxjs": "~7.8.2", + "sass": "^1.89.2", + "tslib": "^2.8.1", + "zone.js": "~0.15.1" + }, + "devDependencies": { + "@angular/build": "^20.0.3", + "@angular/cli": "~20.0.3", + "@angular/compiler-cli": "^20.0.4", + "@types/chance": "^1.1.6", + "@types/date-fns": "^2.6.3", + "@types/jasmine": "~5.1.8", + "jasmine-core": "~5.8.0", + "karma": "~6.4.4", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.1", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.8.3" + } +} diff --git a/theme/packages/horizontal/src/app/app.routes.ts b/theme/packages/horizontal/src/app/app.routes.ts new file mode 100644 index 0000000..f1bf19f --- /dev/null +++ b/theme/packages/horizontal/src/app/app.routes.ts @@ -0,0 +1,107 @@ +import { Routes } from '@angular/router'; +import { BlankComponent } from './layouts/blank/blank.component'; +import { FullComponent } from './layouts/full/full.component'; + +export const routes: Routes = [ + { + path: '', + component: FullComponent, + children: [ + { + path: '', + redirectTo: '/dashboards/dashboard1', + pathMatch: 'full', + }, + { + path: 'starter', + loadChildren: () => + import('./pages/pages.routes').then((m) => m.PagesRoutes), + }, + { + path: 'dashboards', + loadChildren: () => + import('./pages/dashboards/dashboards.routes').then( + (m) => m.DashboardsRoutes + ), + }, + + { + path: 'forms', + loadChildren: () => + import('./pages/forms/forms.routes').then((m) => m.FormsRoutes), + }, + { + path: 'charts', + loadChildren: () => + import('./pages/charts/charts.routes').then((m) => m.ChartsRoutes), + }, + { + path: 'apps', + loadChildren: () => + import('./pages/apps/apps.routes').then((m) => m.AppsRoutes), + }, + { + path: 'widgets', + loadChildren: () => + import('./pages/widgets/widgets.routes').then((m) => m.WidgetsRoutes), + }, + { + path: 'tables', + loadChildren: () => + import('./pages/tables/tables.routes').then((m) => m.TablesRoutes), + }, + { + path: 'datatable', + loadChildren: () => + import('./pages/datatable/datatable.routes').then( + (m) => m.DatatablesRoutes + ), + }, + { + path: 'theme-pages', + loadChildren: () => + import('./pages/theme-pages/theme-pages.routes').then( + (m) => m.ThemePagesRoutes + ), + }, + { + path: 'ui-components', + loadChildren: () => + import('./pages/ui-components/ui-components.routes').then( + (m) => m.UiComponentsRoutes + ), + }, + ], + }, + { + path: '', + component: BlankComponent, + children: [ + { + path: 'authentication', + loadChildren: () => + import('./pages/authentication/authentication.routes').then( + (m) => m.AuthenticationRoutes + ), + }, + { + path: 'landingpage', + loadChildren: () => + import('./pages/theme-pages/landingpage/landingpage.routes').then( + (m) => m.LandingPageRoutes + ), + }, + { + path: 'front-pages', + loadChildren: () => + import('./pages/front-pages/front-pages.routes').then( + (m) => m.FrontPagesRoutes + ), + }, + ], + }, + { + path: '**', + redirectTo: 'authentication/error', + }, +]; diff --git a/theme/packages/horizontal/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html b/theme/packages/horizontal/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html new file mode 100644 index 0000000..fa78891 --- /dev/null +++ b/theme/packages/horizontal/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html @@ -0,0 +1,55 @@ + + + Yearly Breakup + + +
+
+

$36,358

+
+ +
+9%
+
last year
+
+ +
+
+ +
2025
+
+
+ +
2024
+
+
+
+
+ + + + +
+
+
+
diff --git a/theme/packages/horizontal/src/app/config.ts b/theme/packages/horizontal/src/app/config.ts new file mode 100644 index 0000000..7581629 --- /dev/null +++ b/theme/packages/horizontal/src/app/config.ts @@ -0,0 +1,25 @@ +export interface AppSettings { + dir: 'ltr' | 'rtl'; + theme: string; + sidenavOpened: boolean; + sidenavCollapsed: boolean; + boxed: boolean; + horizontal: boolean; + activeTheme: string; + language: string; + cardBorder: boolean; + navPos: 'side' | 'top'; +} + +export const defaults: AppSettings = { + dir: 'ltr', + theme: 'light', + sidenavOpened: false, + sidenavCollapsed: false, + boxed: true, + horizontal: true, + cardBorder: false, + activeTheme: 'blue_theme', + language: 'en-us', + navPos: 'side', +}; \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/layouts/full/full.component.html b/theme/packages/horizontal/src/app/layouts/full/full.component.html new file mode 100644 index 0000000..2ffaeb5 --- /dev/null +++ b/theme/packages/horizontal/src/app/layouts/full/full.component.html @@ -0,0 +1,197 @@ + + + + + + @if (!options.horizontal) { + +
+ + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+
+ } + + + + + @if (resView) { + + + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+ } + + + + + + + + + @if (!options.horizontal) { + + } @else { + + + } @if(options.horizontal) { + + } + +
+ + + + + +
+ +
+
+ + +
+
+
+
+ @if(options.theme === 'light') { + + logo + + } @else { + + logo + + } +
+ +
+ + + + + Apps + +
+
+ @for(appdd of apps; track appdd.img) { + + } +
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+ + +
+
+
+ + +
+

Settings

+ +
+ + + +
+
+
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/layouts/full/full.component.ts b/theme/packages/horizontal/src/app/layouts/full/full.component.ts new file mode 100644 index 0000000..459faac --- /dev/null +++ b/theme/packages/horizontal/src/app/layouts/full/full.component.ts @@ -0,0 +1,284 @@ +import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout'; +import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { MatSidenav, MatSidenavContent } from '@angular/material/sidenav'; +import { CoreService } from 'src/app/services/core.service'; +import { AppSettings } from 'src/app/config'; +import { filter } from 'rxjs/operators'; +import { NavigationEnd, Router } from '@angular/router'; +import { navItems } from './vertical/sidebar/sidebar-data'; +import { NavService } from '../../services/nav.service'; +import { AppNavItemComponent } from './vertical/sidebar/nav-item/nav-item.component'; +import { RouterModule } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { SidebarComponent } from './vertical/sidebar/sidebar.component'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { HeaderComponent } from './vertical/header/header.component'; +import { AppHorizontalHeaderComponent } from './horizontal/header/header.component'; +import { AppHorizontalSidebarComponent } from './horizontal/sidebar/sidebar.component'; +import { AppBreadcrumbComponent } from './shared/breadcrumb/breadcrumb.component'; +import { CustomizerComponent } from './shared/customizer/customizer.component'; + +const MOBILE_VIEW = 'screen and (max-width: 768px)'; +const TABLET_VIEW = 'screen and (min-width: 769px) and (max-width: 1024px)'; +const MONITOR_VIEW = 'screen and (min-width: 1024px)'; +const BELOWMONITOR = 'screen and (max-width: 1023px)'; + +// for mobile app sidebar +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +@Component({ + selector: 'app-full', + imports: [ + RouterModule, + AppNavItemComponent, + MaterialModule, + CommonModule, + SidebarComponent, + NgScrollbarModule, + TablerIconsModule, + HeaderComponent, + AppHorizontalHeaderComponent, + AppHorizontalSidebarComponent, + AppBreadcrumbComponent, + CustomizerComponent, + ], + templateUrl: './full.component.html', + + encapsulation: ViewEncapsulation.None +}) +export class FullComponent implements OnInit { + navItems = navItems; + + + + @ViewChild('leftsidenav') + public sidenav: MatSidenav; + resView = false; + @ViewChild('content', { static: true }) content!: MatSidenavContent; + //get options from service + options = this.settings.getOptions(); + private layoutChangesSubscription = Subscription.EMPTY; + private isMobileScreen = false; + private isContentWidthFixed = true; + private isCollapsedWidthFixed = false; + private htmlElement!: HTMLHtmlElement; + + get isOver(): boolean { + return this.isMobileScreen; + } + + get isTablet(): boolean { + return this.resView; + } + + // for mobile app sidebar + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/apps/chat', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'Todo App', + subtitle: 'Completed task', + link: '/apps/todo', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/apps/invoice', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/apps/calendar', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/apps/contacts', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/apps/tickets', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/apps/email/inbox', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Courses', + subtitle: 'Create new course', + link: '/apps/courses', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/theme-pages/pricing', + }, + { + id: 2, + title: 'Authentication Design', + link: '/authentication/login', + }, + { + id: 3, + title: 'Register Now', + link: '/authentication/side-register', + }, + { + id: 4, + title: '404 Error Page', + link: '/authentication/error', + }, + { + id: 5, + title: 'Notes App', + link: '/apps/notes', + }, + { + id: 6, + title: 'Employee App', + link: '/apps/employee', + }, + { + id: 7, + title: 'Todo Application', + link: '/apps/todo', + }, + { + id: 8, + title: 'Treeview', + link: '/theme-pages/treeview', + }, + ]; + + constructor( + private settings: CoreService, + private mediaMatcher: MediaMatcher, + private router: Router, + private breakpointObserver: BreakpointObserver, + private navService: NavService, private cdr: ChangeDetectorRef + ) { + this.htmlElement = document.querySelector('html')!; + this.layoutChangesSubscription = this.breakpointObserver + .observe([MOBILE_VIEW, TABLET_VIEW, MONITOR_VIEW, BELOWMONITOR]) + .subscribe((state) => { + // SidenavOpened must be reset true when layout changes + this.options.sidenavOpened = true; + this.isMobileScreen = state.breakpoints[BELOWMONITOR]; + if (this.options.sidenavCollapsed == false) { + this.options.sidenavCollapsed = state.breakpoints[TABLET_VIEW]; + } + this.isContentWidthFixed = state.breakpoints[MONITOR_VIEW]; + this.resView = state.breakpoints[BELOWMONITOR]; + }); + + // Initialize project theme with options + this.receiveOptions(this.options); + + // This is for scroll to top + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .subscribe((e) => { + this.content.scrollTo({ top: 0 }); + }); + } + + isFilterNavOpen = false; + + toggleFilterNav() { + this.isFilterNavOpen = !this.isFilterNavOpen; + console.log('Sidebar open:', this.isFilterNavOpen); + this.cdr.detectChanges(); // Ensures Angular updates the view + } + + ngOnInit(): void {} + + ngOnDestroy() { + this.layoutChangesSubscription.unsubscribe(); + } + + toggleCollapsed() { + this.isContentWidthFixed = false; + this.options.sidenavCollapsed = !this.options.sidenavCollapsed; + this.resetCollapsedState(); + } + + resetCollapsedState(timer = 400) { + setTimeout(() => this.settings.setOptions(this.options), timer); + } + + onSidenavClosedStart() { + this.isContentWidthFixed = false; + } + + onSidenavOpenedChange(isOpened: boolean) { + this.isCollapsedWidthFixed = !this.isOver; + this.options.sidenavOpened = isOpened; + this.settings.setOptions(this.options); + } + + receiveOptions(options: AppSettings): void { + this.toggleDarkTheme(options); + this.toggleColorsTheme(options); + } + + toggleDarkTheme(options: AppSettings) { + if (options.theme === 'dark') { + this.htmlElement.classList.add('dark-theme'); + this.htmlElement.classList.remove('light-theme'); + } else { + this.htmlElement.classList.remove('dark-theme'); + this.htmlElement.classList.add('light-theme'); + } + } + + toggleColorsTheme(options: AppSettings) { + // Remove any existing theme class dynamically + this.htmlElement.classList.forEach((className) => { + if (className.endsWith('_theme')) { + this.htmlElement.classList.remove(className); + } + }); + + // Add the selected theme class + this.htmlElement.classList.add(options.activeTheme); + } +} diff --git a/theme/packages/horizontal/src/app/layouts/full/horizontal/header/header.component.html b/theme/packages/horizontal/src/app/layouts/full/horizontal/header/header.component.html new file mode 100644 index 0000000..f076a2c --- /dev/null +++ b/theme/packages/horizontal/src/app/layouts/full/horizontal/header/header.component.html @@ -0,0 +1,296 @@ + +
+
+ +
+ + + + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/horizontal/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts b/theme/packages/horizontal/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts new file mode 100644 index 0000000..3bdf202 --- /dev/null +++ b/theme/packages/horizontal/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts @@ -0,0 +1,633 @@ +import { NavItem } from '../../vertical/sidebar/nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Dashboards', + iconName: 'home', + route: 'dashboards', + children: [ + { + displayName: 'Analytical', + iconName: 'point', + route: 'dashboards/dashboard1', + }, + { + displayName: 'eCommerce', + iconName: 'point', + route: 'dashboards/dashboard2', + }, + ], + }, + { + displayName: 'Frontend pages', + iconName: 'app-window', + route: 'front-pages', + children: [ + { + displayName: 'Home Page', + iconName: 'point', + route: 'front-pages/homepage', + } , + { + displayName: 'About Us', + iconName: 'point', + route: 'front-pages/about', + } , + { + displayName: 'Blog', + iconName: 'point', + route: 'front-pages/blog', + } , + { + displayName: 'Blog Details', + iconName: 'point', + route: 'front-pages/blog-details', + } , + { + displayName: 'Portfolio', + iconName: 'point', + route: 'front-pages/portfolio', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'front-pages/pricing', + }, + { + displayName: 'Contact', + iconName: 'point', + route: 'front-pages/contact', + } + ] + }, + { + displayName: 'Apps', + iconName: 'apps', + route: 'apps', + ddType: '', + children: [ + { + displayName: 'Chat', + iconName: 'point', + route: 'apps/chat', + }, + { + displayName: 'Calendar', + iconName: 'point', + route: 'apps/calendar', + }, + { + displayName: 'Email', + iconName: 'point', + route: 'apps/email/inbox', + }, + { + displayName: 'Contacts', + iconName: 'point', + route: 'apps/contacts', + }, + { + displayName: 'Contact List', + iconName: 'point', + route: 'apps/contact-list', + }, + { + displayName: 'Courses', + iconName: 'point', + route: 'apps/courses', + }, + { + displayName: 'Employee', + iconName: 'point', + route: 'apps/employee', + }, + { + displayName: 'Notes', + iconName: 'point', + route: 'apps/notes', + }, + { + displayName: 'Tickets', + iconName: 'point', + route: 'apps/tickets', + }, + { + displayName: 'Invoice', + iconName: 'point', + route: 'apps/invoice', + }, + { + displayName: 'ToDo', + iconName: 'point', + route: 'apps/todo', + }, + { + displayName: 'Kanban', + iconName: 'point', + route: 'apps/kanban', + }, + { + displayName: 'Blog', + iconName: 'point', + route: 'apps/blog', + children: [ + { + displayName: 'Post', + iconName: 'point', + route: 'apps/blog/post', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + }, + ], + }, + { + displayName: 'User Profile', + iconName: 'point', + route: 'apps/profile-details', + children: [ + { + displayName: 'Profile', + iconName: 'point', + route: 'apps/profile-details/profile', + }, + { + displayName: 'Followers', + iconName: 'point', + route: 'apps/profile-details/followers', + }, + { + displayName: 'Friends', + iconName: 'point', + route: 'apps/profile-details/friends', + }, + { + displayName: 'Gellary', + iconName: 'point', + route: 'apps/profile-details/gallery', + }, + ], + }, + { + displayName: 'Ecommerce', + iconName: 'point', + route: 'apps/product', + children: [ + { + displayName: 'Product List', + iconName: 'point', + route: 'apps/product/product-list', + }, + { + displayName: 'Add Product', + iconName: 'point', + route: 'apps/product/add-product', + }, + { + displayName: 'Edit Product', + iconName: 'point', + route: 'apps/product/edit-product', + }, + { + displayName: 'Shop', + iconName: 'point', + route: 'apps/product/shop', + }, + ], + }, + ], + }, + { + displayName: 'Ui', + iconName: 'components', + route: 'ui-components', + ddType: '', + children: [ + { + displayName: 'Badge', + iconName: 'point', + route: 'ui-components/badge', + }, + { + displayName: 'Expansion Panel', + iconName: 'point', + route: 'ui-components/expansion', + }, + { + displayName: 'Chips', + iconName: 'point', + route: 'ui-components/chips', + }, + { + displayName: 'Dialog', + iconName: 'point', + route: 'ui-components/dialog', + }, + { + displayName: 'Lists', + iconName: 'point', + route: 'ui-components/lists', + }, + { + displayName: 'Divider', + iconName: 'point', + route: 'ui-components/divider', + }, + { + displayName: 'Menu', + iconName: 'point', + route: 'ui-components/menu', + }, + { + displayName: 'Paginator', + iconName: 'point', + route: 'ui-components/paginator', + }, + { + displayName: 'Progress Bar', + iconName: 'point', + route: 'ui-components/progress', + }, + { + displayName: 'Progress Spinner', + iconName: 'point', + route: 'ui-components/progress-spinner', + }, + { + displayName: 'Ripples', + iconName: 'point', + route: 'ui-components/ripples', + }, + { + displayName: 'Slide Toggle', + iconName: 'point', + route: 'ui-components/slide-toggle', + }, + { + displayName: 'Slider', + iconName: 'point', + route: 'ui-components/slider', + }, + { + displayName: 'Snackbar', + iconName: 'point', + route: 'ui-components/snackbar', + }, + { + displayName: 'Tabs', + iconName: 'point', + route: 'ui-components/tabs', + }, + { + displayName: 'Toolbar', + iconName: 'point', + route: 'ui-components/toolbar', + }, + { + displayName: 'Tooltips', + iconName: 'point', + route: 'ui-components/tooltips', + }, + ], + }, + { + displayName: 'Pages', + iconName: 'clipboard', + route: 'theme-pages', + ddType: '', + children: [ + { + displayName: 'Treeview', + iconName: 'point', + route: 'theme-pages/treeview', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'theme-pages/pricing', + }, + { + displayName: 'Account Setting', + iconName: 'point', + route: 'theme-pages/account-setting', + }, + { + displayName: 'FAQ', + iconName: 'point', + route: 'theme-pages/faq', + }, + { + displayName: 'Landingpage', + iconName: 'point', + route: 'landingpage', + }, + { + displayName: 'Widgets', + iconName: 'point', + route: 'widgets', + children: [ + { + displayName: 'Cards', + iconName: 'point', + route: 'widgets/cards', + }, + { + displayName: 'Banners', + iconName: 'point', + route: 'widgets/banners', + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'widgets/charts', + }, + ], + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'charts', + children: [ + { + displayName: 'Line', + iconName: 'point', + route: '/charts/line', + }, + { + displayName: 'Gredient', + iconName: 'point', + route: '/charts/gredient', + }, + { + displayName: 'Area', + iconName: 'point', + route: '/charts/area', + }, + { + displayName: 'Candlestick', + iconName: 'point', + route: '/charts/candlestick', + }, + { + displayName: 'Column', + iconName: 'point', + route: '/charts/column', + }, + { + displayName: 'Doughnut & Pie', + iconName: 'point', + route: '/charts/doughnut-pie', + }, + { + displayName: 'Radialbar & Radar', + iconName: 'point', + route: '/charts/radial-radar', + }, + ], + }, + { + displayName: 'Auth', + iconName: 'point', + route: '/', + children: [ + { + displayName: 'Login', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/login', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-login', + }, + ], + }, + { + displayName: 'Register', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/side-register', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-register', + }, + ], + }, + { + displayName: 'Forgot Password', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Side Forgot Password', + iconName: 'point', + route: '/authentication/side-forgot-pwd', + }, + { + displayName: 'Boxed Forgot Password', + iconName: 'point', + route: '/authentication/boxed-forgot-pwd', + }, + ], + }, + { + displayName: 'Two Steps', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Side Two Steps', + iconName: 'point', + route: '/authentication/side-two-steps', + }, + { + displayName: 'Boxed Two Steps', + iconName: 'point', + route: '/authentication/boxed-two-steps', + }, + ], + }, + { + displayName: 'Error', + iconName: 'point', + route: '/authentication/error', + }, + { + displayName: 'Maintenance', + iconName: 'point', + route: '/authentication/maintenance', + }, + ], + }, + ], + }, + { + displayName: 'Forms', + iconName: 'file-description', + route: 'forms', + ddType: '', + children: [ + { + displayName: 'Form elements', + iconName: 'point', + route: 'forms/forms-elements', + children: [ + { + displayName: 'Autocomplete', + iconName: 'point', + route: 'forms/forms-elements/autocomplete', + }, + { + displayName: 'Button', + iconName: 'point', + route: 'forms/forms-elements/button', + }, + { + displayName: 'Checkbox', + iconName: 'point', + route: 'forms/forms-elements/checkbox', + }, + { + displayName: 'Radio', + iconName: 'point', + route: 'forms/forms-elements/radio', + }, + { + displayName: 'Datepicker', + iconName: 'point', + route: 'forms/forms-elements/datepicker', + }, + ], + }, + { + displayName: 'Form Layouts', + iconName: 'point', + route: '/forms/form-layouts', + }, + { + displayName: 'Form Horizontal', + iconName: 'point', + route: '/forms/form-horizontal', + }, + { + displayName: 'Form Vertical', + iconName: 'point', + route: '/forms/form-vertical', + }, + { + displayName: 'Form Wizard', + iconName: 'point', + route: '/forms/form-wizard', + }, + { + displayName: 'Toastr', + iconName: 'point', + route: '/forms/form-toastr', + }, + { + displayName: 'Editor', + iconName: 'point', + route: '/forms/form-editor', + }, + ], + }, + { + displayName: 'Tables', + iconName: 'layout', + route: 'tables', + ddType: '', + children: [ + { + displayName: 'Basic Table', + iconName: 'point', + route: 'tables/basic-table', + }, + { + displayName: 'Dynamic Table', + iconName: 'point', + route: 'tables/dynamic-table', + }, + { + displayName: 'Expand Table', + iconName: 'point', + route: 'tables/expand-table', + }, + { + displayName: 'Filterable Table', + iconName: 'point', + route: 'tables/filterable-table', + }, + { + displayName: 'Footer Row Table', + iconName: 'point', + route: 'tables/footer-row-table', + }, + { + displayName: 'HTTP Table', + iconName: 'point', + route: 'tables/http-table', + }, + { + displayName: 'Mix Table', + iconName: 'point', + route: 'tables/mix-table', + }, + { + displayName: 'Multi Header Footer', + iconName: 'point', + route: 'tables/multi-header-footer-table', + }, + { + displayName: 'Pagination Table', + iconName: 'point', + route: 'tables/pagination-table', + }, + { + displayName: 'Row Context Table', + iconName: 'point', + route: 'tables/row-context-table', + }, + { + displayName: 'Selection Table', + iconName: 'point', + route: 'tables/selection-table', + }, + { + displayName: 'Sortable Table', + iconName: 'point', + route: 'tables/sortable-table', + }, + { + displayName: 'Sticky Column', + iconName: 'point', + route: 'tables/sticky-column-table', + }, + { + displayName: 'Sticky Header Footer', + iconName: 'point', + route: 'tables/sticky-header-footer-table', + }, + { + displayName: 'Data table', + iconName: 'point', + route: '/datatable/kichen-sink', + }, + ], + }, +]; diff --git a/theme/packages/horizontal/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts b/theme/packages/horizontal/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts new file mode 100644 index 0000000..f0e13f5 --- /dev/null +++ b/theme/packages/horizontal/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts @@ -0,0 +1,48 @@ +import { + Component, + OnInit, + Input, + ChangeDetectorRef, + OnChanges, +} from '@angular/core'; +import { navItems } from './sidebar-data'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../services/nav.service'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { AppHorizontalNavItemComponent } from './nav-item/nav-item.component'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-horizontal-sidebar', + imports: [AppHorizontalNavItemComponent, CommonModule], + templateUrl: './sidebar.component.html', +}) +export class AppHorizontalSidebarComponent implements OnInit { + navItems = navItems; + parentActive = ''; + + mobileQuery: MediaQueryList; + private _mobileQueryListener: () => void; + + constructor( + public navService: NavService, + public router: Router, + media: MediaMatcher, + changeDetectorRef: ChangeDetectorRef + ) { + this.mobileQuery = media.matchMedia('(min-width: 1100px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + this.router.events.subscribe( + () => (this.parentActive = this.router.url.split('/')[1]) + ); + } + + ngOnInit(): void { + this.parentActive = this.router.url.split('/')[1]; + + this.router.events.subscribe(() => { + this.parentActive = this.router.url.split('/')[1]; + }); + } +} diff --git a/theme/packages/horizontal/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts b/theme/packages/horizontal/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts new file mode 100644 index 0000000..3cf2292 --- /dev/null +++ b/theme/packages/horizontal/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { Router, NavigationEnd, ActivatedRoute, Data } from '@angular/router'; +import { filter, map, mergeMap } from 'rxjs/operators'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-breadcrumb', + imports: [RouterModule, TablerIconsModule], + templateUrl: './breadcrumb.component.html', + styleUrls: [] +}) +export class AppBreadcrumbComponent { + // @Input() layout; + pageInfo: Data | any = Object.create(null); + myurl: any = this.router.url.slice(1).split('/'); + constructor( + private router: Router, + private activatedRoute: ActivatedRoute, + private titleService: Title + ) { + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .pipe(map(() => this.activatedRoute)) + .pipe( + map((route) => { + while (route.firstChild) { + route = route.firstChild; + } + return route; + }) + ) + .pipe(filter((route) => route.outlet === 'primary')) + .pipe(mergeMap((route) => route.data)) + // tslint:disable-next-line - Disables all + .subscribe((event) => { + // tslint:disable-next-line - Disables all + this.titleService.setTitle(event['title'] + ' - Angular 20'); + this.pageInfo = event; + }); + } +} diff --git a/theme/packages/horizontal/src/app/layouts/full/vertical/header/header.component.html b/theme/packages/horizontal/src/app/layouts/full/vertical/header/header.component.html new file mode 100644 index 0000000..3949a30 --- /dev/null +++ b/theme/packages/horizontal/src/app/layouts/full/vertical/header/header.component.html @@ -0,0 +1,301 @@ + + + + @if(showToggle) { + + } + + + @if(!showToggle) { + + } + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently + Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ + @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/horizontal/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts b/theme/packages/horizontal/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts new file mode 100644 index 0000000..3782536 --- /dev/null +++ b/theme/packages/horizontal/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts @@ -0,0 +1,103 @@ +import { + Component, + HostBinding, + Input, + OnInit, + OnChanges, + Output, + EventEmitter, +} from '@angular/core'; +import { NavItem } from './nav-item'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../../services/nav.service'; +import { + animate, + state, + style, + transition, + trigger, +} from '@angular/animations'; +import { TranslateModule } from '@ngx-translate/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-nav-item', + imports: [TranslateModule, TablerIconsModule, MaterialModule, CommonModule], + templateUrl: './nav-item.component.html', + styleUrls: [], + animations: [ + trigger('indicatorRotate', [ + state('collapsed', style({ transform: 'rotate(0deg)' })), + state('expanded', style({ transform: 'rotate(180deg)' })), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4,0.0,0.2,1)')), + ]), + ] +}) +export class AppNavItemComponent implements OnChanges { + @Output() toggleMobileLink: any = new EventEmitter(); + @Output() notify: EventEmitter = new EventEmitter(); + + expanded: any = false; + disabled: any = false; + twoLines: any = false; + @HostBinding('attr.aria-expanded') ariaExpanded = this.expanded; + @Input() item: NavItem | any; + @Input() depth: any; + + constructor(public navService: NavService, public router: Router) { + if (this.depth === undefined) { + this.depth = 0; + } + } + + ngOnChanges() { + const url = this.navService.currentUrl(); + if (this.item.route && url) { + this.expanded = url.indexOf(`/${this.item.route}`) === 0; + this.ariaExpanded = this.expanded; + } + } + + onItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + this.router.navigate([item.route]); + + } + if (item.children && item.children.length) { + this.expanded = !this.expanded; + } + //scroll + window.scroll({ + top: 0, + left: 0, + behavior: 'smooth', + }); + if (!this.expanded) { + if (window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + onSubItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + if (this.expanded && window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + isDirectlyActive(item: NavItem): boolean { + return !!item.route && this.router.isActive(item.route, true); + } + + isChildActive(item: NavItem): boolean { + if (!item.children) return false; + return item.children.some( + (child) => this.isDirectlyActive(child) || this.isChildActive(child) + ); + } + +} diff --git a/theme/packages/horizontal/src/app/layouts/full/vertical/sidebar/sidebar-data.ts b/theme/packages/horizontal/src/app/layouts/full/vertical/sidebar/sidebar-data.ts new file mode 100644 index 0000000..e52b956 --- /dev/null +++ b/theme/packages/horizontal/src/app/layouts/full/vertical/sidebar/sidebar-data.ts @@ -0,0 +1,705 @@ +import { NavItem } from './nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Analytical', + iconName: 'aperture', + route: '/dashboards/dashboard1', + }, + { + displayName: 'eCommerce', + iconName: 'shopping-cart', + route: '/dashboards/dashboard2', + }, + { + displayName: 'Frontend pages', + iconName: 'app-window', + route: 'front-pages', + children: [ + { + displayName: 'Home Page', + iconName: 'point', + route: 'front-pages/homepage', + } , + { + displayName: 'About Us', + iconName: 'point', + route: 'front-pages/about', + } , + { + displayName: 'Blog', + iconName: 'point', + route: 'front-pages/blog', + } , + { + displayName: 'Blog Details', + iconName: 'point', + route: 'front-pages/blog-details', + } , + { + displayName: 'Portfolio', + iconName: 'point', + route: 'front-pages/portfolio', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'front-pages/pricing', + }, + { + displayName: 'Contact', + iconName: 'point', + route: 'front-pages/contact', + } + ] + }, + { + navCap: 'Apps', + }, + { + displayName: 'Chat', + iconName: 'message-2', + route: 'apps/chat', + }, + { + displayName: 'Calendar', + iconName: 'calendar-event', + route: 'apps/calendar', + }, + { + displayName: 'Email', + iconName: 'mail', + route: 'apps/email/inbox', + }, + { + displayName: 'Kanban', + iconName: 'checklist', + route: 'apps/kanban', + }, + { + displayName: 'User Profile', + iconName: 'user-circle', + route: 'apps/profile-details', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'New', + children: [ + { + displayName: 'Profile', + iconName: 'point', + route: 'apps/profile-details/profile', + }, + { + displayName: 'Followers', + iconName: 'point', + route: 'apps/profile-details/followers', + }, + { + displayName: 'Friends', + iconName: 'point', + route: 'apps/profile-details/friends', + }, + { + displayName: 'Gellary', + iconName: 'point', + route: 'apps/profile-details/gallery', + }, + ], + }, + { + displayName: 'Ecommerce', + iconName: 'basket', + route: 'apps/product', + chip: true, + chipClass: 'border-error text-error', + chipContent: 'New', + children: [ + { + displayName: 'Product List', + iconName: 'point', + route: 'apps/product/product-list', + }, + { + displayName: 'Add Product', + iconName: 'point', + route: 'apps/product/add-product', + }, + { + displayName: 'Edit Product', + iconName: 'point', + route: 'apps/product/edit-product', + }, + { + displayName: 'Shop', + iconName: 'point', + route: 'apps/product/shop', + }, + ], + }, + { + displayName: 'Contacts', + iconName: 'phone', + route: 'apps/contacts', + }, + { + displayName: 'Courses', + iconName: 'certificate', + route: 'apps/courses', + }, + { + displayName: 'Employee', + iconName: 'brand-ctemplar', + route: 'apps/employee', + }, + { + displayName: 'Notes', + iconName: 'note', + route: 'apps/notes', + }, + { + displayName: 'Tickets', + iconName: 'ticket', + route: 'apps/tickets', + }, + { + displayName: 'Contact List', + iconName: 'phone', + route: 'apps/contact-list', + }, + { + displayName: 'Invoice', + iconName: 'file-invoice', + route: 'apps/invoice', + children: [ + { + displayName: 'List', + iconName: 'point', + route: 'apps/invoice/list', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/invoice/viewInvoice/101', + }, + { + displayName: 'Create', + iconName: 'point', + route: 'apps/invoice/addInvoice', + }, + { + displayName: 'Edit', + iconName: 'point', + route: 'apps/invoice/editinvoice/101', + }, + ], + }, + { + displayName: 'ToDo', + iconName: 'edit', + route: 'apps/todo', + }, + { + displayName: 'Blog', + iconName: 'chart-donut-3', + route: 'apps/blog', + children: [ + { + displayName: 'Post', + iconName: 'point', + route: 'apps/blog/post', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + }, + ], + }, + { + navCap: 'Pages', + }, + { + displayName: 'Roll Base Access', + iconName: 'lock-access', + route: 'apps/permission', + }, + { + displayName: 'Treeview', + iconName: 'git-merge', + route: 'theme-pages/treeview', + }, + { + displayName: 'Pricing', + iconName: 'currency-dollar', + route: 'theme-pages/pricing', + }, + { + displayName: 'Account Setting', + iconName: 'user-circle', + route: 'theme-pages/account-setting', + }, + { + displayName: 'FAQ', + iconName: 'help', + route: 'theme-pages/faq', + }, + { + displayName: 'Landingpage', + iconName: 'app-window', + route: 'landingpage', + }, + { + displayName: 'Widgets', + iconName: 'layout', + route: 'widgets', + children: [ + { + displayName: 'Cards', + iconName: 'point', + route: 'widgets/cards', + }, + { + displayName: 'Banners', + iconName: 'point', + route: 'widgets/banners', + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'widgets/charts', + }, + ], + }, + { + navCap: 'Forms', + }, + { + displayName: 'Form elements', + iconName: 'apps', + route: 'forms/forms-elements', + children: [ + { + displayName: 'Autocomplete', + iconName: 'point', + route: 'forms/forms-elements/autocomplete', + }, + { + displayName: 'Button', + iconName: 'point', + route: 'forms/forms-elements/button', + }, + { + displayName: 'Checkbox', + iconName: 'point', + route: 'forms/forms-elements/checkbox', + }, + { + displayName: 'Radio', + iconName: 'point', + route: 'forms/forms-elements/radio', + }, + { + displayName: 'Datepicker', + iconName: 'point', + route: 'forms/forms-elements/datepicker', + }, + ], + }, + { + displayName: 'Form Layouts', + iconName: 'file-description', + route: '/forms/form-layouts', + }, + { + displayName: 'Form Horizontal', + iconName: 'box-align-bottom', + route: '/forms/form-horizontal', + }, + { + displayName: 'Form Vertical', + iconName: 'box-align-left', + route: '/forms/form-vertical', + }, + { + displayName: 'Form Wizard', + iconName: 'files', + route: '/forms/form-wizard', + }, + { + displayName: 'Toastr', + iconName: 'notification', + route: '/forms/form-toastr', + }, + { + displayName: 'Editor', + iconName: 'edit', + route: '/forms/form-editor', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'New', + }, + { + navCap: 'Tables', + }, + { + displayName: 'Tables', + iconName: 'layout', + route: 'tables', + children: [ + { + displayName: 'Basic Table', + iconName: 'point', + route: 'tables/basic-table', + }, + { + displayName: 'Dynamic Table', + iconName: 'point', + route: 'tables/dynamic-table', + }, + { + displayName: 'Expand Table', + iconName: 'point', + route: 'tables/expand-table', + }, + { + displayName: 'Filterable Table', + iconName: 'point', + route: 'tables/filterable-table', + }, + { + displayName: 'Footer Row Table', + iconName: 'point', + route: 'tables/footer-row-table', + }, + { + displayName: 'HTTP Table', + iconName: 'point', + route: 'tables/http-table', + }, + { + displayName: 'Mix Table', + iconName: 'point', + route: 'tables/mix-table', + }, + { + displayName: 'Multi Header Footer', + iconName: 'point', + route: 'tables/multi-header-footer-table', + }, + { + displayName: 'Pagination Table', + iconName: 'point', + route: 'tables/pagination-table', + }, + { + displayName: 'Row Context Table', + iconName: 'point', + route: 'tables/row-context-table', + }, + { + displayName: 'Selection Table', + iconName: 'point', + route: 'tables/selection-table', + }, + { + displayName: 'Sortable Table', + iconName: 'point', + route: 'tables/sortable-table', + }, + { + displayName: 'Sticky Column', + iconName: 'point', + route: 'tables/sticky-column-table', + }, + { + displayName: 'Sticky Header Footer', + iconName: 'point', + route: 'tables/sticky-header-footer-table', + }, + ], + }, + { + displayName: 'Data table', + iconName: 'border-outer', + route: '/datatable/kichen-sink', + }, + { + navCap: 'Chart', + }, + { + displayName: 'Line', + iconName: 'chart-line', + route: '/charts/line', + }, + { + displayName: 'Gredient', + iconName: 'chart-arcs', + route: '/charts/gredient', + }, + { + displayName: 'Area', + iconName: 'chart-area', + route: '/charts/area', + }, + { + displayName: 'Candlestick', + iconName: 'chart-candle', + route: '/charts/candlestick', + }, + { + displayName: 'Column', + iconName: 'chart-dots', + route: '/charts/column', + }, + { + displayName: 'Doughnut & Pie', + iconName: 'chart-donut-3', + route: '/charts/doughnut-pie', + }, + { + displayName: 'Radialbar & Radar', + iconName: 'chart-radar', + route: '/charts/radial-radar', + }, + { + navCap: 'UI', + }, + { + displayName: 'Ui Components', + iconName: 'box', + route: 'ui-components', + children: [ + { + displayName: 'Badge', + iconName: 'point', + route: 'ui-components/badge', + }, + { + displayName: 'Expansion Panel', + iconName: 'point', + route: 'ui-components/expansion', + }, + { + displayName: 'Chips', + iconName: 'point', + route: 'ui-components/chips', + }, + { + displayName: 'Dialog', + iconName: 'point', + route: 'ui-components/dialog', + }, + { + displayName: 'Lists', + iconName: 'point', + route: 'ui-components/lists', + }, + { + displayName: 'Divider', + iconName: 'point', + route: 'ui-components/divider', + }, + { + displayName: 'Menu', + iconName: 'point', + route: 'ui-components/menu', + }, + { + displayName: 'Paginator', + iconName: 'point', + route: 'ui-components/paginator', + }, + { + displayName: 'Progress Bar', + iconName: 'point', + route: 'ui-components/progress', + }, + { + displayName: 'Progress Spinner', + iconName: 'point', + route: 'ui-components/progress-spinner', + }, + { + displayName: 'Ripples', + iconName: 'point', + route: 'ui-components/ripples', + }, + { + displayName: 'Slide Toggle', + iconName: 'point', + route: 'ui-components/slide-toggle', + }, + { + displayName: 'Slider', + iconName: 'point', + route: 'ui-components/slider', + }, + { + displayName: 'Snackbar', + iconName: 'point', + route: 'ui-components/snackbar', + }, + { + displayName: 'Tabs', + iconName: 'point', + route: 'ui-components/tabs', + }, + { + displayName: 'Toolbar', + iconName: 'point', + route: 'ui-components/toolbar', + }, + { + displayName: 'Tooltips', + iconName: 'point', + route: 'ui-components/tooltips', + }, + ], + }, + { + navCap: 'Auth', + }, + { + displayName: 'Login', + iconName: 'login', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/login', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-login', + }, + ], + }, + { + displayName: 'Register', + iconName: 'user-plus', + route: '/authentication', + children: [ + { + displayName: 'Side Register', + iconName: 'point', + route: '/authentication/side-register', + }, + { + displayName: 'Boxed Register', + iconName: 'point', + route: '/authentication/boxed-register', + }, + ], + }, + { + displayName: 'Forgot Password', + iconName: 'rotate', + route: '/authentication', + children: [ + { + displayName: 'Side Forgot Password', + iconName: 'point', + route: '/authentication/side-forgot-pwd', + }, + { + displayName: 'Boxed Forgot Password', + iconName: 'point', + route: '/authentication/boxed-forgot-pwd', + }, + ], + }, + { + displayName: 'Two Steps', + iconName: 'zoom-code', + route: '/authentication', + children: [ + { + displayName: 'Side Two Steps', + iconName: 'point', + route: '/authentication/side-two-steps', + }, + { + displayName: 'Boxed Two Steps', + iconName: 'point', + route: '/authentication/boxed-two-steps', + }, + ], + }, + { + displayName: 'Error', + iconName: 'alert-circle', + route: '/authentication/error', + }, + { + displayName: 'Maintenance', + iconName: 'settings', + route: '/authentication/maintenance', + }, + { + navCap: 'Other', + }, + { + displayName: 'Menu Level', + iconName: 'box-multiple', + route: '/menu-level', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + { + displayName: 'Disabled', + iconName: 'ban', + route: '/disabled', + disabled: true, + }, + { + displayName: 'Chip', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-primary text-white', + chipContent: '9', + }, + { + displayName: 'Outlined', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'outlined', + }, + { + displayName: 'External Link', + iconName: 'star', + route: 'https://www.google.com/', + external: true, + }, +]; diff --git a/theme/packages/horizontal/src/app/material.module.ts b/theme/packages/horizontal/src/app/material.module.ts new file mode 100644 index 0000000..8fd4750 --- /dev/null +++ b/theme/packages/horizontal/src/app/material.module.ts @@ -0,0 +1,89 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +// Material Form Controls +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatSelectModule } from '@angular/material/select'; +import { MatSliderModule } from '@angular/material/slider'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +// Material Navigation +import { MatMenuModule } from '@angular/material/menu'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatToolbarModule } from '@angular/material/toolbar'; +// Material Layout +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatListModule } from '@angular/material/list'; +import { MatStepperModule } from '@angular/material/stepper'; +import { MatTabsModule } from '@angular/material/tabs'; +import { MatTreeModule } from '@angular/material/tree'; +// Material Buttons & Indicators +import { MatButtonModule } from '@angular/material/button'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatIconModule } from '@angular/material/icon'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +// Material Popups & Modals +import { MatBottomSheetModule } from '@angular/material/bottom-sheet'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { MatTooltipModule } from '@angular/material/tooltip'; +// Material Data tables +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatSortModule } from '@angular/material/sort'; +import { MatTableModule } from '@angular/material/table'; + +@NgModule({ + declarations: [], + imports: [ + + ], + exports: [ + MatAutocompleteModule, + MatCheckboxModule, + MatDatepickerModule, + MatFormFieldModule, + MatInputModule, + MatRadioModule, + MatSelectModule, + MatSliderModule, + MatSlideToggleModule, + MatMenuModule, + MatSidenavModule, + MatToolbarModule, + MatCardModule, + MatDividerModule, + MatExpansionModule, + MatGridListModule, + MatListModule, + MatStepperModule, + MatTabsModule, + MatTreeModule, + MatButtonModule, + MatButtonToggleModule, + MatBadgeModule, + MatChipsModule, + MatIconModule, + MatProgressSpinnerModule, + MatProgressBarModule, + MatRippleModule, + MatBottomSheetModule, + MatDialogModule, + MatSnackBarModule, + MatTooltipModule, + MatPaginatorModule, + MatSortModule, + MatTableModule, + ], + +}) +export class MaterialModule {} diff --git a/theme/packages/horizontal/src/app/pages/apps/chat/chat.component.html b/theme/packages/horizontal/src/app/pages/apps/chat/chat.component.html new file mode 100644 index 0000000..1530c1f --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/apps/chat/chat.component.html @@ -0,0 +1,123 @@ + + + + + + + +
+ +
+

Mathew Anderson

+ info@modernize.com +
+
+ +
+ + + + + + + +
+ + @if (filteredMessages() && filteredMessages().length > 0) { +
+ + @for(message of filteredMessages(); track message.from) { + + + + +

+ {{ message.from }} +

+

+ {{ message.subject }} +

+
+ } +
+
+ } @else { +
+ No messages found. +
+ } +
+
+ + + + + + +
+ +
+ {{ selectedMessage()?.from }} +
+
+ + + + + + +
+ + + + + + + @for(c of selectedMessage()?.chat; track c) { @if(c.type === 'odd') { +
+
+
+ + {{ c.msg }} +
+ + {{ c.date | date }} + +
+
+ } @else { +
+
+
+ {{ c.msg }} +
+ + {{ c.date | date }} + +
+
+ } } +
+
+ +
+ + + + +
+
+
+
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/apps/fullcalendar/fullcalendar.component.ts b/theme/packages/horizontal/src/app/pages/apps/fullcalendar/fullcalendar.component.ts new file mode 100644 index 0000000..a4565ca --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/apps/fullcalendar/fullcalendar.component.ts @@ -0,0 +1,286 @@ +import { + Component, + ChangeDetectionStrategy, + Inject, + signal, + DOCUMENT +} from '@angular/core'; +import { CommonModule, NgSwitch } from '@angular/common'; +import { + MatDialog, + MatDialogRef, + MatDialogConfig, + MAT_DIALOG_DATA, + MatDialogModule, +} from '@angular/material/dialog'; +import { + FormsModule, + ReactiveFormsModule, + UntypedFormGroup, +} from '@angular/forms'; +import { CalendarFormDialogComponent } from './calendar-form-dialog/calendar-form-dialog.component'; +import { + startOfDay, + subDays, + addDays, + endOfMonth, + isSameDay, + isSameMonth, + addHours, + subMonths, + addMonths, +} from 'date-fns'; +import { Subject } from 'rxjs'; +import { + CalendarDateFormatter, + CalendarEvent, + CalendarEventAction, + CalendarEventTimesChangedEvent, + CalendarModule, + CalendarView, +} from 'angular-calendar'; +import { MaterialModule } from 'src/app/material.module'; +import { + MatNativeDateModule, + provideNativeDateAdapter, +} from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +const colors: any = { + red: { + primary: '#fa896b', + secondary: '#fdede8', + }, + blue: { + primary: '#5d87ff', + secondary: '#ecf2ff', + }, + yellow: { + primary: '#ffae1f', + secondary: '#fef5e5', + }, +}; + +@Component({ + selector: 'app-calendar-dialog', + templateUrl: './dialog.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + CommonModule, + MatNativeDateModule, + MatDialogModule, + MatDatepickerModule, TablerIconsModule + ], + providers: [provideNativeDateAdapter()], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CalendarDialogComponent { + options!: UntypedFormGroup; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) {} +} + +@Component({ + selector: 'app-fullcalendar', + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './fullcalendar.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + NgSwitch, + CalendarModule, + CommonModule, + MatDatepickerModule, + MatDialogModule, + MatFormFieldModule, + ], + providers: [provideNativeDateAdapter(), CalendarDateFormatter] +}) +export class AppFullcalendarComponent { + dialogRef = signal | any>(null); + dialogRef2 = signal | any>(null); + lastCloseResult = signal(''); + actionsAlignment = signal(''); + view = signal('month'); + viewDate = signal(new Date()); + activeDayIsOpen = signal(true); + + config: MatDialogConfig = { + disableClose: false, + width: '', + height: '', + position: { + top: '', + bottom: '', + left: '', + right: '', + }, + data: { + action: '', + event: [], + }, + }; + numTemplateOpens = 0; + + actions: CalendarEventAction[] = [ + { + label: ': Edit', + onClick: ({ event }: { event: CalendarEvent }): void => { + this.handleEvent('Edit', event); + }, + }, + { + label: 'Delete', + onClick: ({ event }: { event: CalendarEvent }): void => { + this.events.set( + this.events().filter((iEvent: CalendarEvent) => iEvent !== event) + ); + this.handleEvent('Deleted', event); + }, + }, + ]; + + refresh: Subject = new Subject(); + + events = signal([ + { + start: subDays(startOfDay(new Date()), 1), + end: addDays(new Date(), 1), + title: 'A 3 day event', + color: colors.red, + actions: this.actions, + }, + { + start: startOfDay(new Date()), + title: 'An event with no end date', + color: colors.blue, + actions: this.actions, + }, + { + start: subDays(endOfMonth(new Date()), 3), + end: addDays(endOfMonth(new Date()), 3), + title: 'A long event that spans 2 months', + color: colors.blue, + }, + { + start: addHours(startOfDay(new Date()), 2), + end: new Date(), + title: 'A draggable and resizable event', + color: colors.yellow, + actions: this.actions, + resizable: { + beforeStart: true, + afterEnd: true, + }, + draggable: true, + }, + ]); + + constructor(public dialog: MatDialog, @Inject(DOCUMENT) doc: any) {} + + dayClicked({ date, events }: { date: Date; events: CalendarEvent[] }): void { + if (isSameMonth(date, this.viewDate())) { + if ( + (isSameDay(this.viewDate(), date) && this.activeDayIsOpen() === true) || + events.length === 0 + ) { + this.activeDayIsOpen.set(false); + } else { + this.activeDayIsOpen.set(true); + this.viewDate.set(date); + } + } + } + + eventTimesChanged({ + event, + newStart, + newEnd, + }: CalendarEventTimesChangedEvent): void { + this.events.set( + this.events().map((iEvent: CalendarEvent) => { + if (iEvent === event) { + return { + ...event, + start: newStart, + end: newEnd, + }; + } + return iEvent; + }) + ); + + this.handleEvent('Dropped or resized', event); + } + + handleEvent(action: string, event: CalendarEvent): void { + this.config.data = { event, action }; + this.dialogRef.set(this.dialog.open(CalendarDialogComponent, this.config)); + + this.dialogRef() + .afterClosed() + .subscribe((result: string) => { + this.lastCloseResult.set(result); + this.dialogRef.set(null); + this.refresh.next(result); + }); + } + + addEvent(): void { + this.dialogRef2.set( + this.dialog.open(CalendarFormDialogComponent, { + panelClass: 'calendar-form-dialog', + autoFocus: false, + data: { + action: 'add', + date: new Date(), + }, + }) + ); + this.dialogRef2() + .afterClosed() + .subscribe((res: { action: any; event: any }) => { + if (!res) { + return; + } + const dialogAction = res.action; + const responseEvent = res.event; + responseEvent.actions = this.actions; + this.events.set([...this.events(), responseEvent]); + this.dialogRef2.set(null); + this.refresh.next(res); + }); + } + + deleteEvent(eventToDelete: CalendarEvent): void { + this.events.set( + this.events().filter( + (event: CalendarEvent) => event !== eventToDelete + ) + ); + } + + setView(view: CalendarView | any): void { + this.view.set(view); + } + + goToPreviousMonth(): void { + this.viewDate.set(subMonths(this.viewDate(), 1)); + } + + goToNextMonth(): void { + this.viewDate.set(addMonths(this.viewDate(), 1)); + } + + goToToday() { + this.viewDate.set(new Date()); + } +} diff --git a/theme/packages/horizontal/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html b/theme/packages/horizontal/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html new file mode 100644 index 0000000..027a82b --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html @@ -0,0 +1,156 @@ + + +
+
+
+

+ # + + {{ invoice().id }} +

+
+
+ + Cancel + + +
+
+ + + +
+
+ + Order Status: + + +
+ {{ invoice().status }} +
+
+
+
+ + Order Date + +
+ {{ invoice().orderDate | date : "dd-MM-yyyy" }} +
+
+
+
+ + + +
+
+ + Bill From + + +
+
+ + Bill To + + +
+
+ + Enter From Address + + +
+
+ + Bill From + + +
+
+
+ +
+
+ + + + + + + + + + + + + @for(row of addForm.get('rows')['controls']; track row; let index = + $index) { + + + + + + + + + + + + + + } + +
#Item NameUnit PriceUnitsUnit Total Price
+ {{ index + 1 }} + + + + + + + + + + + + + + + + + + @if(addForm.get('rows')) { + + } + + @if(index > 0) { + + } +
+
+ +
+
Sub total: {{ subTotal() }}
+
Total Vat: {{ vat() }}%
+ +

Grand Total: {{ grandTotal() }}

+
+
+
+
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html b/theme/packages/horizontal/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html new file mode 100644 index 0000000..f5f0397 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html @@ -0,0 +1,239 @@ + + + @if( invoice()) { + +
+
+
+

+ # + + {{ invoice().id }} +

+
+
+ + Cancel + + + +
+
+ + + +
+
+ Order Status: + + + Pending + Shipped + Delivered + + +
+
+
+ Order Date +
+ {{ invoice().orderDate | date : "dd-MM-yyyy" }} +
+
+
+
+ + + +
+
+ + Bill From + + +
+
+ + Bill To + + +
+
+ + Enter From Address + + +
+
+ + Bill From + + +
+
+
+
+ } + +
+
+ + + + + + + + + + + + + @for(a of addForm.get('item')['controls']; track a; let i =$index) { + + + + + + + + + + + + } +
#Item NameUnit PriceUnitsUnit Total Price
+ {{ i + 1 }} + + + + + + + + + + + + + + + + + + + + @if(addForm.get('item')?.length > 1) { + + } +
+
+ +
+
+ @if(addForm.get('rows')) { + + } + +
Sub total: {{ subTotal() }}
+
Total Vat: {{ vat() }}%
+ +

Grand Total: {{ grandTotal() }}

+
+
+
+
+
diff --git a/theme/packages/horizontal/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts b/theme/packages/horizontal/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts new file mode 100644 index 0000000..3e5b5b4 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts @@ -0,0 +1,164 @@ +import { Component, signal } from '@angular/core'; +import { ActivatedRoute, Router, RouterLink } from '@angular/router'; +import { InvoiceService } from 'src/app/services/apps/invoice/invoice.service'; +import { InvoiceList, order } from '../invoice'; +import { + UntypedFormGroup, + UntypedFormArray, + UntypedFormBuilder, + Validators, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { OkDialogComponent } from './ok-dialog/ok-dialog.component'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatSnackBar } from '@angular/material/snack-bar'; +@Component({ + selector: 'app-edit-invoice', + templateUrl: './edit-invoice.component.html', + imports: [ + MaterialModule, + CommonModule, + RouterLink, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ], +}) +export class AppEditInvoiceComponent { + id = signal(null); + subTotal = signal(0); + vat = signal(0); + grandTotal = signal(0); + addForm: UntypedFormGroup | any; + invoice = signal([]); + constructor( + activatedRouter: ActivatedRoute, + private invoiceService: InvoiceService, + private router: Router, + private fb: UntypedFormBuilder, + public dialog: MatDialog, + private snackBar: MatSnackBar + ) { + this.id.set(activatedRouter.snapshot.paramMap.get('id')); + this.loadInvoice(); // Load invoice here + this.subTotal.set(this.invoice()?.totalCost || 0); + this.vat.set(this.invoice()?.vat || 0); + this.grandTotal.set(this.invoice()?.grandTotal || 0); + this.addForm = this.fb.group({ + item: this.fb.array([this.itemControl()]), + }); + + this.fillAddControls(); + } + + loadInvoice(): void { + const invoiceData = this.invoiceService + .getInvoiceList() + .find((x) => x.id === +this.id()); + this.invoice.set(invoiceData); // Set the invoice signal + } + itemControl(): UntypedFormGroup { + return this.fb.group({ + itemName: ['', Validators.required], + itemCost: ['', Validators.required], + itemSold: ['', Validators.required], + itemTotal: [{ value: 0, disabled: true }], + }); + } + + fillAddControls(): void { + this.addForm.setControl('item', this.setItem(this.invoice()?.orders)); + } + + setItem(order: any): UntypedFormArray { + const fa = new UntypedFormArray([]); + order?.forEach((s: any) => { + fa.push( + this.fb.group({ + itemName: s.itemName, + itemCost: s.unitPrice, + itemSold: s.units, + itemTotal: s.unitTotalPrice, + }) + ); + }); + return fa; + } + + btnAddItemClick(): void { + (this.addForm.get('item')).push(this.itemControl()); + } + + btnRemoveClick(i: number): void { + const totalCostOfItem = + this.addForm.get('item')?.value[i].itemCost * + this.addForm.get('item')?.value[i].itemSold; + + this.subTotal.set(this.subTotal() - totalCostOfItem); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + + (this.addForm.get('item')).removeAt(i); + } + + itemsChanged(): void { + let total = 0; + for ( + let t = 0; + t < (this.addForm.get('item')).length; + t++ + ) { + if ( + this.addForm.get('item')?.value[t].itemCost != '' && + this.addForm.get('item')?.value[t].itemSold + ) { + total += + this.addForm.get('item')?.value[t].itemCost * + this.addForm.get('item')?.value[t].itemSold; + } + } + this.subTotal.set(total); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + } + + saveDetail(event: Event): void { + event.preventDefault(); + const currentInvoice = this.invoice(); + if (currentInvoice) { + currentInvoice.grandTotal = this.grandTotal(); + currentInvoice.totalCost = this.subTotal(); + currentInvoice.vat = this.vat(); + currentInvoice.orders = []; + + for ( + let t = 0; + t < (this.addForm.get('item')).length; + t++ + ) { + const o: order = new order(); + o.itemName = this.addForm.get('item')?.value[t].itemName; + o.unitPrice = this.addForm.get('item')?.value[t].itemCost; + o.units = this.addForm.get('item')?.value[t].itemSold; + o.unitTotalPrice = o.units * o.unitPrice; + currentInvoice.orders.push(o); + } + this.dialog.open(OkDialogComponent); + this.invoiceService.updateInvoice(currentInvoice.id, currentInvoice); + this.router.navigate(['/apps/invoice/list']); + this.showSnackbar('Invoice updated successfully!'); + } + } + + showSnackbar(message: string): void { + this.snackBar.open(message, 'Close', { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } +} diff --git a/theme/packages/horizontal/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html b/theme/packages/horizontal/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html new file mode 100644 index 0000000..3942ba6 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html @@ -0,0 +1,281 @@ +
+
+ + +
+ +
+
+
Total
+
+ {{ allInvoices().length }} invoices +
+
+
+
+
+
+ + +
+ +
+
+
Shipped
+
+ {{ countInvoicesByStatus("Shipped") }} invoices +
+
+
+
+
+ +
+ + +
+ +
+
+
Delivered
+
+ {{ countInvoicesByStatus("Delivered") }} invoices +
+
+
+
+
+ +
+ + +
+ +
+
+
Pending
+
+ {{ countInvoicesByStatus("Pending") }} invoices +
+
+
+
+
+
+ + + +
+
+ + + + + + +
+ +
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + Id + + {{ element.id }} + + Bill From + + {{ element.billFrom }} + + Bill To + + {{ element.billTo }} + + Total Cost + + {{ element.totalCost }} + + Status + + + {{ element.status }} + + + Action + + + + + + + + + + + +
+ +
+
+
diff --git a/theme/packages/horizontal/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html b/theme/packages/horizontal/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html new file mode 100644 index 0000000..b3bbc15 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html @@ -0,0 +1,125 @@ + + + @if(invoiceDetail()){ + +
+
+

#{{ invoiceDetail()?.id }}

+
+ +
+ +
+
+ Order Status: +
+ {{ invoiceDetail()?.status }} +
+
+
+ Order Date: +
+ {{ invoiceDetail()?.orderDate | date : "fullDate" }} +
+
+
+ +
+
+ Bill From: +
+ {{ invoiceDetail()?.billFrom }} +
+
+ {{ invoiceDetail()?.billFromEmail }} +
+
+ {{ invoiceDetail()?.billFromAddress }} +
+
+ {{ invoiceDetail()?.billFromPhone }} +
+
+
+ Bill To: +
+ {{ invoiceDetail()?.billTo }} +
+
+ {{ invoiceDetail()?.billToEmail }} +
+
+ {{ invoiceDetail()?.billToAddress }} +
+
+ {{ invoiceDetail()?.billToPhone }} +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ Item Name + + {{ element.itemName }} + + Unit Price + + {{ element.unitPrice }} + + Unit + + {{ element.units }} + + Total Cost + + {{ element.unitTotalPrice }} +
+
+ +
+
+ Sub total: {{ invoiceDetail()?.totalCost }} +
+ Vat: 10% +

+ Grand Total: {{ invoiceDetail()?.grandTotal }} +

+
+
+ } +
+
diff --git a/theme/packages/horizontal/src/app/pages/apps/tickets/ticket-dialog-content.html b/theme/packages/horizontal/src/app/pages/apps/tickets/ticket-dialog-content.html new file mode 100644 index 0000000..19f96d5 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/apps/tickets/ticket-dialog-content.html @@ -0,0 +1,132 @@ +@if(action !== 'Delete') { + +
+

{{action}} Ticket

+ +
+
+
+ @if(action === 'Update') { +
+ Ticket Id + + + +
+ } + +
+ Ticket Title + + + +
+
+ Ticket Subtext + + + +
+
+ Assign User + + + @for(user of users; track trackByUser(user)) { + +
+ {{ user.name }} + {{ user.name }} +
+
+ } +
+
+
+ @if(action === 'Update'){ +
+ Status + + + +
+ } @if(action === 'Update') { +
+ + Date + + + + +
+ } +
+
+
+} @else { +
+ Sure to delete {{local_data.title}}? +
+} +
+ + +
diff --git a/theme/packages/horizontal/src/app/pages/apps/tickets/tickets.component.ts b/theme/packages/horizontal/src/app/pages/apps/tickets/tickets.component.ts new file mode 100644 index 0000000..f1b5f6c --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/apps/tickets/tickets.component.ts @@ -0,0 +1,177 @@ +import { + Component, + OnInit, + ViewChild, + AfterViewInit, + Inject, +} from '@angular/core'; +import { MatTableDataSource, MatTable } from '@angular/material/table'; +import { + MatDialog, + MatDialogRef, + MAT_DIALOG_DATA, +} from '@angular/material/dialog'; +import { MatPaginator } from '@angular/material/paginator'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TicketService } from 'src/app/services/apps/ticket/ticket.service'; +import { TicketElement } from 'src/app/pages/apps/tickets/ticket'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +@Component({ + selector: 'app-ticket-list', + templateUrl: './tickets.component.html', + imports: [MaterialModule, CommonModule, TablerIconsModule], +}) +export class AppTicketlistComponent implements OnInit, AfterViewInit { + @ViewChild(MatTable, { static: true }) table: MatTable; + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; + + searchText: string = ''; + totalCount = 0; + Closed = 0; + Inprogress = 0; + Open = 0; + + displayedColumns: string[] = [ + 'id', + 'title', + 'assignee', + 'status', + 'date', + 'action', + ]; + + dataSource = new MatTableDataSource([]); + + constructor(private ticketService: TicketService, public dialog: MatDialog) {} + + ngOnInit(): void { + this.loadTickets(); // Load the initial tickets + } + + private loadTickets(): void { + const tickets = this.ticketService.tickets$; // Get tickets from the service + this.dataSource.data = tickets; // Set the dataSource to the tickets + + // Update counts based on the current tickets + this.updateCounts(); + } + + private updateCounts(): void { + this.totalCount = this.dataSource.data.length; + this.Open = this.countTicketsByStatus('open'); + this.Closed = this.countTicketsByStatus('closed'); + this.Inprogress = this.countTicketsByStatus('inprogress'); + } + + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + } + + onKeyup(event: KeyboardEvent): void { + const input = event.target as HTMLInputElement; + this.applyFilter(input.value); + } + applyFilter(filterValue: string): void { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + btnCategoryClick(val: string): number { + this.dataSource.filter = val.trim().toLowerCase(); + return this.dataSource.filteredData.length; + } + + openDialog(action: string, ticket: TicketElement | any): void { + const dialogRef = this.dialog.open(TicketDialogComponent, { + data: { action, ticket }, + autoFocus: false, + }); + + dialogRef.afterClosed().subscribe(() => { + this.loadTickets(); + }); + } + + countTicketsByStatus(status: string): number { + return this.dataSource.data.filter( + (ticket) => ticket.status.toLowerCase() === status.toLowerCase() + ).length; + } +} + +@Component({ + // tslint:disable-next-line - Disables all + selector: 'app-dialog-content', + templateUrl: 'ticket-dialog-content.html', + imports: [ + MaterialModule, + CommonModule, + TablerIconsModule, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ], +}) +export class TicketDialogComponent { + action: string; + local_data: TicketElement; + users: any[] = []; + dateControl = new FormControl(); + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + private ticketService: TicketService, + private snackBar: MatSnackBar + ) { + this.action = data.action; + this.local_data = { ...data.ticket }; + } + + ngOnInit(): void { + this.users = this.ticketService.getUsers(); // Get users from the service + + if (this.local_data.date) { + this.dateControl.setValue( + new Date(this.local_data.date).toISOString().split('T')[0] + ); // existing date + } else { + // Set to today's date if no existing date is available + this.dateControl.setValue(new Date().toISOString().split('T')[0]); + } + } + + doAction(): void { + this.local_data.date = this.dateControl.value; // Update local_data with the new date + + if (this.action === 'Update') { + this.ticketService.updateTicket(this.local_data); + this.openSnackBar('Ticket updated successfully!', 'Close'); + } else if (this.action === 'Add') { + this.ticketService.addTicket(this.local_data); + this.openSnackBar('Ticket added successfully!', 'Close'); + } else if (this.action === 'Delete') { + this.ticketService.deleteTicket(this.local_data.id); + this.openSnackBar('Ticket deleted successfully!', 'Close'); + } + this.dialogRef.close(); + } + + openSnackBar(message: string, action: string): void { + this.snackBar.open(message, action, { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } + closeDialog(): void { + this.dialogRef.close(); + } + + trackByUser(user: any): any { + return user.id; + } +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.html b/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.html new file mode 100644 index 0000000..0fef605 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.html @@ -0,0 +1,169 @@ +
+ + +
+
+

+ The hassle-free setup process +

+
+ @for(topcard of setupCards; track topcard.title) { +
+ + +
+ @if(topcard.id!==2){ + users + } + +
+ {{ topcard.title }} +
+

+ {{ topcard.subtitle }} +

+ @if(topcard.id===2){ + image + } +
+
+
+
+ } +
+
+
+ + + +
+
+
+
+
+

Key metric at a glance

+

+ From the year we were founded to the impressive customer base + we've built, and the growth percentages that reflect our + continuous improvement, these numbers tell our story at a glance. + Explore the data that drives our mission and underscores our + commitment to excellence. +

+
+
+
+
+ @for (stat of stats; track stat) { +
+
+

+ {{ stat.label }} +

+

+ {{ stat.value }} +

+

{{ stat.description }}

+
+
+ } +
+
+
+
+
+ +
+ +
+ +
+
+
+ +
+
+

+ What our clients
think logo + about us? +

+

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+
+
+
+ + + Features availability + +
+
+ +
+
{{ currentUser().name }}
+
+ +

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+ + + +
+ + + {{ displayCount() }} + + +
+
+
+
+
+
+
+ + + +
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.scss new file mode 100644 index 0000000..e5e27d5 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.scss @@ -0,0 +1,23 @@ +.contact-page { + + .setup-process { + + mat-card-content { + padding: 0px !important; + padding: 30px 16px !important; + } + } + + .key-metric { + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + } + + .features { + + .cardWithShadow { + mat-card-content { + padding: 0px !important; + } + } + } +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.spec.ts new file mode 100644 index 0000000..0d075ce --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AboutUsComponent } from './about-us.component'; + +describe('AboutUsComponent', () => { + let component: AboutUsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AboutUsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AboutUsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.ts new file mode 100644 index 0000000..497b22d --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/about-us/about-us.component.ts @@ -0,0 +1,48 @@ +import { Component, computed, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { ImageSliderComponent } from '../image-slider/image-slider.component'; +import { FooterComponent } from '../footer/footer.component'; +//import { PagePricingComponent } from '../page-pricing/page-pricing.component'; +import { + setupCards, + stats, + users, +} from '../front-pagesData'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-about-us', + imports: [IconModule,MaterialModule ,CommonModule,ImageSliderComponent,FooterComponent, + //PagePricingComponent + ], + templateUrl: './about-us.component.html', + styleUrl: './about-us.component.scss' +}) +export class AboutUsComponent { + setupCards=setupCards; + stats = stats; + currentIndex = signal(0); // Starting from 0 + users = users; + // Computed values to auto-update template + currentUser = computed(() => this.users[this.currentIndex()]); + displayCount = computed( + () => `${this.currentIndex() + 1}/${this.users.length}` + ); + goPrev() { + if (this.currentIndex() > 0) { + this.currentIndex.update((i) => i - 1); + } + } + + goNext() { + if (this.currentIndex() < this.users.length - 1) { + this.currentIndex.update((i) => i + 1); + } + + + } + + + +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.html b/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.html new file mode 100644 index 0000000..020f82c --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.html @@ -0,0 +1,116 @@ + + +
+
+ + + + @if(blogDetail()) { + + Photo of a Shiba Inu +
+ 2 mins Read +
+ +
+
+ +
+ {{ + blogDetail()?.category }} +
+ + {{ + blogDetail()?.title }} + +
+
+ {{ + blogDetail()?.views }} + 4 +
+ + + {{ blogDetail()?.date }} + +
+
+ +

Main Heading & Points

+

+ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the + industry's standard dummy text ever since + the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It + has survived not only five centuries, + but also the leap into electronic typesetting, + remaining essentially unchanged. It was popularised in the +

+
    +
  • Vivamus eu lacus scelerisque, placerat commodo lectus.
  • +
  • Etiam et ante at ex porta fringilla.
  • +
  • Nullam dignissim sem eu magna aliquet, sit amet volutpat tellus
  • +
+

+ Unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not + only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was + popularised in the +

+ +

+ We are a dedicated team of passionate product managers, developers, UX/UI designers, QA engineers experts + helping businesses from new startups +

+ +

+ There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in + some form, by injected humour, or randomised words which don't look even slightly believable making this the + first true generator on the Internet. It uses a dictionary +

+ +

Tags

+
    +
  • Trends
  • +
  • Design
  • +
  • Research
  • +
+ + +

Share

+ + + +

Join our newsletter

+

Email address : Subscribe

+
+
+ } + + + + + + @if (!blogDetail() || blogDetail().length === 0) { + + +

No blog post available.

+
+
+ } +
+
+ + \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts new file mode 100644 index 0000000..241ed7b --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlogDetailsComponent } from './blog-details.component'; + +describe('BlogDetailsComponent', () => { + let component: BlogDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BlogDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BlogDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.ts new file mode 100644 index 0000000..9633085 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/blog-details/blog-details.component.ts @@ -0,0 +1,40 @@ +import { CommonModule } from '@angular/common'; +import { Component, inject, OnInit, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; +import { FrontEndService } from 'src/app/services/apps/front-pages/front-end.service'; + +@Component({ + selector: 'app-blog-details', + imports: [IconModule, MaterialModule, CommonModule, + FooterComponent + ], + templateUrl: './blog-details.component.html', + styleUrl: './blog-details.component.scss' +}) +export class BlogDetailsComponent implements OnInit { + blogDetail = signal(null); + private frontendService = inject(FrontEndService); + ngOnInit(): void { + const selected = this.frontendService.getBlog()(); + + if (selected) { + this.blogDetail.set(selected); + } else { + // Fallback if accessed directly (e.g., from sidebar or refresh) + const defaultBlog = { + id: 1, + time: "2 mins Read", + imgSrc: "/assets/images/blog/blog-img1.jpg", + user: "/assets/images/profile/user-1.jpg", + title: "As yen tumbles, gadget-loving Japan goes for secondhand iPhones", + views: "9,125", + category: "Social", + comments: 3, + date: "Mon, Dec 23" + }; + this.blogDetail.set(defaultBlog); + } + } +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.html b/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.html new file mode 100644 index 0000000..e30ba7c --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.html @@ -0,0 +1,55 @@ + + +
+
+
+ @for(cardimg of cardimgs; track cardimg.imgSrc) { +
+ + Photo of a Shiba Inu +
+ {{ + cardimg.time + }} +
+ + +
+
+ +
+ {{ + cardimg.category + }} +
+ {{ cardimg.title }} +
+
+ {{ cardimg.views }} + {{ cardimg.comments }} +
+ + + {{ cardimg.date }} + +
+
+
+
+ } +
+
+
+ + \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.scss new file mode 100644 index 0000000..e5dce08 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.scss @@ -0,0 +1,24 @@ + + +.social-btns { + margin-top: 20px; + + .btn-icon { + width: 25px !important; + height: 25px !important; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + + tabler-icon { + width: 16px !important; + height: 16px !important; + } + } + + .btn-add-story { + font-size: 0.75rem; + padding: 0.35rem 0.75rem; + } +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.spec.ts new file mode 100644 index 0000000..7998b08 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlogComponent } from './blog.component'; + +describe('BlogComponent', () => { + let component: BlogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BlogComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BlogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.ts new file mode 100644 index 0000000..d25328e --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/blog/blog.component.ts @@ -0,0 +1,32 @@ +import { Component, inject, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { cardimgs } from '../front-pagesData'; +import { FooterComponent } from '../footer/footer.component'; +import { Router } from '@angular/router'; +import { FrontEndService } from 'src/app/services/apps/front-pages/front-end.service'; + +@Component({ + selector: 'app-blog', + imports: [IconModule, MaterialModule, FooterComponent,], + templateUrl: './blog.component.html', + styleUrl: './blog.component.scss' +}) +export class BlogComponent implements OnInit { + + private router = inject(Router); + private frontendService = inject(FrontEndService); + cardimgs = cardimgs; + + ngOnInit() { + console.log(cardimgs, 'cardimgs'); + } + + getNavigate(cardimg: any) { + console.log('cardimg--->', cardimg); + this.frontendService.setBlog(cardimg); + this.router.navigate(['front-pages/blog-details']) + + } + +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.html b/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.html new file mode 100644 index 0000000..f2cfc62 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.html @@ -0,0 +1,103 @@ +
+ + + +
+
+
+ +
+ +
+
+
+
+
+
+ + First Name* + + + + + Phone Number* + + + +
+
+ + Last Name* + + + + + Email* + + + +
+
+ +
+
+ Enquire related to* + + + + General Enquiry + General Enquiry 2 + + +
+
+
+
+ Message + + + +
+
+ +
+
+ + +
+
Reach Out Today
+

+ Have questions or need assistance? We're just a message + away. +

+
+ +
+
Our Location
+

+ Visit us in person or find our contact details to connect + with us directly. +

+
+
+
+
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.scss new file mode 100644 index 0000000..572fa27 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.scss @@ -0,0 +1,3 @@ +.map-container{ + margin-top: -200px; +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.spec.ts new file mode 100644 index 0000000..dae8ee6 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ContactComponent } from './contact.component'; + +describe('ContactComponent', () => { + let component: ContactComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ContactComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ContactComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.ts new file mode 100644 index 0000000..556ed9a --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/contact/contact.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; + +@Component({ + selector: 'app-contact', + imports: [MaterialModule,IconModule,FooterComponent], + templateUrl: './contact.component.html', + styleUrl: './contact.component.scss' +}) +export class ContactComponent { + +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.html b/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.html new file mode 100644 index 0000000..0177911 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.html @@ -0,0 +1,94 @@ + \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.scss new file mode 100644 index 0000000..6a425bb --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.scss @@ -0,0 +1,13 @@ + +.footer-content{ + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } +} + +.imgStyleDash { + position: absolute; +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.spec.ts new file mode 100644 index 0000000..3f93915 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FooterComponent } from './footer.component'; + +describe('FooterComponent', () => { + let component: FooterComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FooterComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FooterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.ts new file mode 100644 index 0000000..7864854 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/footer/footer.component.ts @@ -0,0 +1,95 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { RouterLink } from '@angular/router'; + +@Component({ + selector: 'app-footer', + imports: [MaterialModule, IconModule, RouterLink], + templateUrl: './footer.component.html', + styleUrl: './footer.component.scss' +}) +export class FooterComponent { + applicationsItems = [ + { + title: 'Kanban', + href: "/apps/kanban" + }, + { + title: 'Invoice List', + href: "/apps/invoice/list" + }, + { + title: 'eCommerce', + href: "/apps/product/shop" + }, + { + title: 'Chats', + href: "/apps/chat" + }, + { + title: 'Tickets', + href: "/apps/tickets" + }, + { + title: 'Blog', + href: "/apps/blog/post" + }, + ]; + + formsItems = [ + { + title: 'Form Layout', + href: "/forms/form-layouts" + }, + { + title: 'Form Horizontal', + href: "/forms/form-horizontal" + }, + { + title: 'Form Wizard', + href: "/forms/form-wizard" + }, + { + title: 'Form Vertical', + href: "/forms/form-vertical" + }, + { + title: 'Form Toastr', + href: "/forms/form-toastr" + }, + ]; + + tablesItems = [ + { + title: 'Basic Table', + href: "/tables/basic-table" + }, + { + title: 'Multi Header Footer Table', + href: "/tables/multi-header-footer-table" + }, + { + title: 'Pagination Table', + href: "/tables/pagination-table" + }, + { + title: 'Dynamic Table', + href: "/tables/dynamic-table" + }, + { + title: 'HTTP Table', + href: "/tables/http-table" + }, + { + title: 'Sortable Table', + href: "/tables/sortable-table" + }, + ]; + + socialIcons = [ + { src: 'assets/images/front-pages/icon-facebook.svg', tooltip: 'Facebook' }, + { src: 'assets/images/front-pages/icon-twitter.svg', tooltip: 'Twitter' }, + { src: 'assets/images/front-pages/icon-instagram.svg', tooltip: 'Instagram' }, + ]; +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/front-pages.routes.ts b/theme/packages/horizontal/src/app/pages/front-pages/front-pages.routes.ts new file mode 100644 index 0000000..bf9375c --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/front-pages.routes.ts @@ -0,0 +1,28 @@ +import { Routes } from '@angular/router'; +import { HomepageComponent } from './homepage/homepage.component'; +import { AboutUsComponent } from './about-us/about-us.component'; +import { HomepageDetailsComponent } from './homepage-details/homepage-details.component'; +import { BlogComponent } from './blog/blog.component'; +import { PortfolioComponent } from './portfolio/portfolio.component'; +import { PricingComponent } from './pricing/pricing.component'; +import { ContactComponent } from './contact/contact.component'; +import { BlogDetailsComponent } from './blog-details/blog-details.component'; + + +export const FrontPagesRoutes: Routes = [ + + { + path: '', + component: HomepageComponent, // acts as layout shell + children: [ + { path: '', redirectTo: 'homepage', pathMatch: 'full' }, + { path: 'homepage', component: HomepageDetailsComponent }, // real homepage content + { path: 'about', component: AboutUsComponent }, + {path:'blog',component:BlogComponent }, + { path: 'portfolio', component: PortfolioComponent }, + { path: 'pricing', component: PricingComponent }, + { path: 'contact', component: ContactComponent }, + { path: 'blog-details', component: BlogDetailsComponent }, + ], + }, +]; \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/front-pagesData.ts b/theme/packages/horizontal/src/app/pages/front-pages/front-pagesData.ts new file mode 100644 index 0000000..0e870f4 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/front-pagesData.ts @@ -0,0 +1,768 @@ +interface cardimgs { + id: number; + time: string; + imgSrc: string; + user: string; + title: string; + views: string; + category: string; + comments: number; + date: string; +} + +interface productcards { + id: number; + imgSrc: string; + title: string; + price: string; + rprice: string; + date: string; +} + +interface Framework { + src: string; + alt: string; + tooltip: string; +} + +interface followercards { + id: number; + imgSrc: string; + title: string; +} + +interface setupCards { + id: number; + img: string; + color: string; + title: string; + subtitle: string; + imgMain?:string; +} + +export const cardimgs: cardimgs[] = [ + { + id: 1, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img1.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 2, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img2.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 3, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img3.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + { + id: 4, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img4.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 5, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img5.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 6, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img6.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + { + id: 7, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img10.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 8, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img8.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 9, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img9.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, +]; + +export const productcards: productcards[] = [ + { + id: 1, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Headphone', + price: '285', + rprice: '375', + date: 'Tue, Apr 03, 2025', + }, + { + id: 2, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Air Pro', + price: '285', + rprice: '375', + date: 'Tue, Apr 10, 2025', + }, + { + id: 3, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Red Velvet Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 15, 2025', + }, + { + id: 4, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Soft Plush Teddy', + price: '285', + rprice: '375', + date: 'Tue, Apr 12, 2025', + }, + { + id: 5, + imgSrc: 'assets/images/products/s2.jpg', + title: 'Boat Bass Booster', + price: '285', + rprice: '375', + date: 'Tue, Apr 14, 2025', + }, + { + id: 6, + imgSrc: 'assets/images/products/s6.jpg', + title: 'MacBook Ultra Slim', + price: '285', + rprice: '375', + date: 'Tue, Apr 18, 2025', + }, + { + id: 7, + imgSrc: 'assets/images/products/s8.jpg', + title: 'Crimson Party Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 20, 2025', + }, + { + id: 8, + imgSrc: 'assets/images/products/s12.jpg', + title: 'Cuddly Teddy Gift', + price: '285', + rprice: '375', + date: 'Tue, Apr 22, 2025', + }, + { + id: 9, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Sonic Headset', + price: '285', + rprice: '375', + date: 'Tue, Apr 25, 2025', + }, + { + id: 10, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Pro 2025', + price: '285', + rprice: '375', + date: 'Tue, Apr 27, 2025', + }, + { + id: 11, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Evening Gown - Red', + price: '285', + rprice: '375', + date: 'Tue, Apr 29, 2025', + }, + { + id: 12, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Fluffy Bear Surprise', + price: '285', + rprice: '375', + date: 'Tue, Apr 30, 2025', + }, +]; + +export const frameworks: Framework[] = [ + { + src: 'assets/images/landingpage/frameworks/angular.svg', + alt: 'Angular', + tooltip: 'Angular', + }, + { + src: 'assets/images/landingpage/frameworks/material.svg', + alt: 'Angular Material', + tooltip: 'Angular Material', + }, + { + src: 'assets/images/landingpage/frameworks/logo-ts.svg', + alt: 'Typescript', + tooltip: 'Typescript', + }, + { + src: 'assets/images/landingpage/frameworks/icon-tabler.svg', + alt: 'Tabler Icon', + tooltip: 'Tabler Icon', + }, +]; + +export const tiles = [ + { + id: 1, + text: 'Light & Dark Color Schemes', + cols: 1, + rows: 1, + color: '#FFF6E5', + icon: 'svgs/icon-briefcase.svg', + subtitle: 'Choose your preferred visual style effortlessly.', + }, + { + id: 2, + text: 'New Demos', + cols: 2, + rows: 2, + color: '#E9F1FF', + icon: 'logos/logoIcon.svg', + img: 'landingpage/background/screen1.png', + subtitle: + 'Brand new demos to help you build the perfect dashboard:
Dark and Right-to-Left.', + }, + { + id: 3, + text: 'Code Improvements', + cols: 1, + rows: 1, + color: '#E7FFF2', + icon: 'logos/icon-speech-bubble.svg', + subtitle: 'Benefit from continuous improvements and optimizations.', + }, + { + id: 4, + text: '12+ Ready to Use Application Designs', + cols: 1, + rows: 1, + color: '#E4F4FF', + icon: 'icon-layer.svg', + img: 'landingpage/background/feature-apps.png', + subtitle: 'Instantly deployable designs for your applications.', + }, + { + id: 5, + text: '50+ UI Components', + cols: 1, + rows: 1, + color: '#FFECEC', + icon: 'logos/icon-favorites.svg', + subtitle: 'A rich collection for seamless user experiences.', + }, +]; + +export const users = [ + { name: 'Jenny Wilson', img: '/assets/images/profile/user-1.jpg' }, + { name: 'Robert Fox', img: '/assets/images/profile/user-2.jpg' }, + { name: 'Kristin Watson', img: '/assets/images/profile/user-3.jpg' }, + { name: 'Darlene Robertson', img: '/assets/images/profile/user-4.jpg' }, + { name: 'Jacob Jones', img: '/assets/images/profile/user-5.jpg' }, +]; + +export const plans = [ + { + title: 'Single Use', + description: + 'Use for single end product which end users can’t be charged for.', + price: 49, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: false }, + { text: 'One Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Multiple Use', + description: + 'Use for unlimited end products end users can’t be charged for.', + price: 89, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: false }, + { text: 'Unlimited Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Extended Use', + description: + 'Use for single end product which end users can be charged for.', + price: 299, + period: 'one time pay', + popular: true, + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: true }, + { text: 'One Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Unlimited Use', + description: + 'Use in unlimited end products end users can be charged for.', + price: 499, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: true }, + { text: 'Unlimited Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, +]; + +export const paymentLogos = [ + { src: 'assets/images/front-pages/icon-visa.svg', alt: 'visa', tooltip: 'Visa' }, + { + src: 'assets/images/front-pages/icon-mastercard.svg', + alt: 'mastercard', + tooltip: 'Master Card', + }, + { + src: 'assets/images/front-pages/icon-american-express.svg', + alt: 'american express', + tooltip: 'American Express', + }, + { + src: 'assets/images/front-pages/icon-discover.svg', + alt: 'discover', + tooltip: 'Discover', + }, + { + src: 'assets/images/front-pages/icon-paypal.svg', + alt: 'paypal', + tooltip: 'Paypal', + }, + { + src: 'assets/images/front-pages/icon-masetro.svg', + alt: 'maestro', + tooltip: 'Maestro', + }, + { src: 'assets/images/front-pages/icon-jcb.svg', alt: 'jcb', tooltip: 'JCB' }, + { + src: 'assets/images/front-pages/icon-diners.svg', + alt: 'diners', + tooltip: 'Diners', + }, +]; + +export const faqList = [ + { + question: 'What is included with my purchase?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Are there any recurring fees?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Can i use template on multiple projects? ', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: + 'Can i use customize the admin dashboard template to match my brand?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Are any restrictions on using the template?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'How can i get support after purchase? ', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, +]; + +export const followercardsFirst: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, +]; + +export const followercardSecond: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, +]; +export const followercardThird: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-customize.svg', + title: 'Easy to Customize', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-chart.svg', + title: 'Lots of Chart Options', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-table.svg', + title: 'Lots of Table Examples', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-update.svg', + title: 'Regular Updates', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-support.svg', + title: 'Dedicated Support', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Easy to Customize', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: 'Lots of Chart Options', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Lots of Table Examples', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Regular Updates', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Dedicated Support', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Easy to Customize', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: 'Lots of Chart Options', + }, + +]; + +export const topcardsGrid = [ + { title: 'Light & Dark Color Schemes', subtitle: 'Choose your preferred visual style effortlessly.', + img: '/assets/images/svgs/icon-briefcase.svg', color: 'warning' }, + { title: '12+ Ready to Use Application Designs', subtitle: 'Instantly deployable designs for your applications.', + img: 'assets/icons/icon2.png', color: 'secondary',imgMain: '/assets/images/landingpage/background/feature-apps.png', }, + { title: 'New Demos', subtitle: 'Brand new demos to help you build the perfect dashboard: Dark and Right-to-Left.', + img: '/assets/images/front-pages/logoIcon.svg', color: 'primary',imgMain: '/assets/images/landingpage/background/screen1.png' }, + { title: 'Code Improvements', subtitle: 'Benefit from continuous improvements and optimizations.', + img: '/assets/images/front-pages/icon-speech-bubble.svg', color: 'success' }, + { title: '50+ UI Components', subtitle: 'A rich collection for seamless user experiences.', + img: '/assets/images/front-pages/icon-favorites.svg', color: 'error' }, +]; + +export const setupCards:setupCards[] = [ + { + id: 1, + color: 'warning', + img: '/assets/images/svgs/icon-briefcase.svg', + title: 'Light & Dark Color Schemes', + subtitle: 'Choose your preferred visual style effortlessly.', + }, + { + id: 2, + color: 'secondary', + img: '/assets/images/svgs/icon-connect.svg', + title: '12+ Ready to Use Application Designs', + subtitle: 'Instantly deployable designs for your applications.', + imgMain: '/assets/images/landingpage/background/feature-apps.png' + }, + + { + id: 3, + color: 'success', + img: '/assets/images/svgs/icon-speech-bubble.svg', + title: 'Code Improvements', + subtitle: 'Benefit from continuous improvements and optimizations.', + }, + { + id: 4, + color: 'error', + img: '/assets/images/svgs/icon-favorites.svg', + title: '50+ UI Components', + subtitle: 'A rich collection for seamless user experiences.', + }, + +]; + +export const stats = [ + { + label: 'Founded', + value: '2019', + description: 'When we founded Modernize', + }, + { + label: 'Growth', + value: '1,400%', + description: 'Revenue growth in 2024', + }, + { + label: 'Customers', + value: '300k+', + description: 'Customers on Modernize', + }, + { + label: 'Dashboards', + value: '25k+', + description: 'Dashboards built using Modernize', + }, +]; + +export const team = [ + {id: 1, + name: 'Alex Martinez', + position: 'CEO & Co-Founder', + image: 'assets/images/front-pages/user1.jpg' + }, + { + id: 2, + name: 'Jordan Nguyen', + position: 'CTO & Co-Founder', + image: 'assets/images/front-pages/user2.jpg' + }, + { + id: 3, + name: 'Taylor Roberts', + position: 'Product Manager', + image: 'assets/images/front-pages/user3.jpg' + }, + {id: 4, + name: 'Morgan Patel', + position: 'Lead Developer', + image: 'assets/images/front-pages/user4.jpg' + }, + { + id: 5, + name: 'Andrew Grant', + position: 'Product Manager', + image: 'assets/images/front-pages/user5.jpg' + }, + { + id: 6, + name: 'Leo Pratt', + position: 'Lead Developer', + image: 'assets/images/front-pages/user3.jpg' + }, + { + id: 7, + name: 'C. A. Nunez', + position: 'CEO & Co-Founder', + image: 'assets/images/front-pages/user2.jpg' + }, + { + id: 8, + name: 'Leo Maxwell', + position: 'Lead Developer', + image: 'assets/images/front-pages/user1.jpg' + } +]; \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.html b/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.html new file mode 100644 index 0000000..b50b52c --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.html @@ -0,0 +1,603 @@ +
+
+
+
+
+

+ Most powerful & + developer friendly + dashboard +

+
+
+
+ @if(!isMobileView){ + +
+ banner-top-left +
+ } + +
+
+
+ +
+ 52,589+ developers & agencies using our templates +
+
+
+
+ Login +
+ + See how it works +
+
+
+ @for (framework of frameworks; track framework.tooltip) { + + + + } +
+
+ @if(!isMobileView){ +
+ banner-top-right +
+ + } +
+ @if (!isMobileView) { +
+
+ bottom-part +
+
+ } +
+
+ +
+
+
+
+

+ Introducing Modernize's Light & Dark Skins, Exceptional Dashboards, + and Dynamic Pages - Stay Updated on What's New! +

+
+
+ + + + + @if (!isMobileView) { +
+ +
+
+ @for (topcard of topcards; track topcard.title) { + @if (topcard.title === 'Light & Dark Color Schemes' || topcard.title.includes('12+')) { + + + @if (topcard.title === 'Light & Dark Color Schemes') { + icon + } +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+ @if (topcard.title.includes('12+')) { + image + } +
+
+ } + } +
+
+
+
+ @for (topcard of topcards; track topcard.title) + { + @if + (topcard.title.includes('New Demos')) { + + + icon +

{{ topcard.title }}

+

+ demo +
+
+ } } +
+
+ + +
+
+ @for (topcard of topcards; track topcard.title) { + @if (topcard.title.includes('Code Improvements') || topcard.title.includes('UI Components')) { + + + icon +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+
+
+ } + } +
+
+ +
+ } + + + @else { +
+ @for (topcard of topcards; track topcard.title) { + @if (!topcard.title.includes('New Demos')) { + + + @if (!topcard.title.includes('12+')) { + icon + } +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+ + @if (topcard.title.includes('12+')) { + image + } +
+
+ } + } +
+ + +
+ @for (topcard of topcards; track topcard.title) + { + @if + (topcard.title.includes('New Demos')) { + + + icon +
{{ topcard.title }}
+

+ demo +
+
+ } } +
+ } + + +
+
+ +
+ +
+ + + + + Team Scheduling + + + + + + Payments + + + + + + Embedding + + + + + + Workflows + + + + + + +
+
+
+ slider-group +
+
+ +
+
+

Defend your focus

+
+ + + + +
+ Factor in outside colleagues + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+ + + + +
+ Combine teammate schedules + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+ + + + +
+ Round robin pooling + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+
+
+ + Learn More +
+ + +
+
+
+
+ +
+ +
+ +
+
+
+ + + Save valuable time and effort spent searching for a solution. + Contact us now + +
+
+
+ +
+
+
+
+

+ Discover Powerful Dozens of
Purpose-Fit Templates +

+
+
+
+
+ + slide + +
+
+
+
+ + slide + +
+
+
+
+ + slide + +
+
+
+
+ slide +
+
+
+
+ + slide + +
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+
+
+

High Customizability

+

+ Tailor the dashboard to your exact needs. Customize layouts, color + schemes, and widgets effortlessly for a personalized user + experience. +

+
+
+

Powerful Data Analytics

+

+ Unlock the true potential of your data with our advanced analytics + tools. Gain valuable insights and make data-driven decisions with + ease. +

+
+ +
+

Interactive Charts

+

+ Visualize complex data sets beautifully with our interactive + graphs and charts. Quickly grasp trends and patterns for smarter + analysis. +

+
+
+
+
+
+
+ +
+
+
+ +
+
+

+ What our clients
think logo + about us? +

+

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+
+
+
+ + + Features availability + +
+
+ +
+
{{ currentUser().name }}
+
+ +

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+ + + +
+ + + {{ displayCount() }} + + +
+
+
+
+
+
+
+ +
+
+
+
+
+

+ Enjoy unparalleled features & exceptional flexibility. +

+
+
+ +
+
+
+ @for (followercard of followercardsfirst; track followercard.title) + { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+ @for (followercard of followercardsecond; track followercard.title) + { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+ @for (followercard of followercardthird; track followercard.title) { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+
+
+ +
+
+

Frequently Asked Questions

+
+
+ + @for (item of faqList; track item) { + + + {{ + item.question + }} + + + + + +

{{ item.answer }}

+
+ } +
+
+
+
+
+ Still have a question? + Ask on discord + or + Submit a ticket +
+
+
+
+ + + +
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.scss new file mode 100644 index 0000000..e6e0f4b --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.scss @@ -0,0 +1,189 @@ +.home-page { + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } + + .home-page-header { + + .header-container-content { + + .cardPosition { + .float-image { + animation: floatUpDown 6s ease-in-out infinite; + } + } + + .cardPositionTwo { + + .float-image { + animation: floatUpDown 6s ease-in-out infinite; + } + } + + .loginBtn { + .play-button { + background-color: transparent; + border: 2px solid var(--mat-sys-primary); // or use your theme color + color: var(--mat-sys-primary); + box-shadow: none; + } + + .textSee { + cursor: pointer; + + &:hover { + color: var(--mat-sys-primary); + } + } + } + } + } + + .dashboardCards { + + .card-container { + + mat-card-content { + padding: 0px !important; + } + } + } + + .tab-header { + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + + .profileTabs { + background-color: var(--mdc-elevated-card-container-color) !important; + + .mat-mdc-tab.mdc-tab-indicator--active { + .mdc-tab__text-label { + color: var(--mat-sys-primary); + } + } + } + + } + + .template-slider { + .template-slider-content { + .demo-slider { + .demo-slide { + animation: slide3d 15s linear infinite; + } + } + } + } + + .features { + + .cardWithShadow { + mat-card-content { + padding: 0px !important; + } + } + } + + .exceptional { + .exceptional-content { + .demo-slider { + .demo-slide { + animation: slide3d 20s linear infinite; + } + + .demo-slide-two { + animation: slide3dTwo 20s linear infinite; + } + } + } + } + + .expansion-panel { + box-shadow: none; + background: transparent; + border-radius: 0 !important; + border-bottom: 1px solid var(--mat-sys-outline); + + .mat-expansion-panel-header { + padding: 18px 0 !important; + height: auto; + } + } + + .sliderImg { + max-width: 380px; + height: 300px; + } + + .img-border { + border: 2px solid var(--mat-sys-secondary); + /* Blue border, change color as needed */ + cursor: pointer; + } + + .img-border:hover { + border-color: var(--mat-sys-secondary); + } + + .border-dash { + border: 1px dashed var(--mat-sys-outline); // Initial border color (Bootstrap primary) + transition: border-color 0.3s ease; + flex-wrap: wrap; + + &:hover { + border-color: var(--mat-sys-primary); // Use your Angular Material primary variable or a custom color + } + } + + .faq-accordion { + .mat-expansion-panel { + border-radius: 8px !important; + + .mat-expansion-panel-header { + padding: 20px 21px !important; + } + } + } +} + +@keyframes floatUpDown { + + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(-6px); // smaller bounce + } +} + +@keyframes slide3d { + from { + transform: translate3d(0, 0, 0); + } + + to { + transform: translate3d(-2028px, 0, 0); // adjust based on actual slide width + } +} + +@keyframes slide3dTwo { + from { + transform: translate3d(-2028px, 0, 0); // Rightward (starts left) + } + + to { + transform: translate3d(0, 0, 0); + } +} + + + +@media (max-width: 1199px) { + .home-page-header { + padding-bottom: 48px; + } +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts new file mode 100644 index 0000000..52b6227 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HomepageDetailsComponent } from './homepage-details.component'; + +describe('HomepageDetailsComponent', () => { + let component: HomepageDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HomepageDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HomepageDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.ts new file mode 100644 index 0000000..46f68e1 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/homepage-details/homepage-details.component.ts @@ -0,0 +1,131 @@ +import { Component, computed, DestroyRef, inject, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { + faqList, + followercardsFirst, + followercardSecond, + followercardThird, + frameworks, + tiles, + users, + topcardsGrid, +} from '../front-pagesData'; +import { CommonModule } from '@angular/common'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { ImageSliderComponent } from '../image-slider/image-slider.component'; +import { FooterComponent } from '../footer/footer.component'; +import { MatDialog } from '@angular/material/dialog'; +import { TemplateVideoComponent } from '../template-video/template-video.component'; +import { Router, RouterModule } from '@angular/router'; + + +@Component({ + selector: 'app-homepage-details', + imports: [ + MaterialModule, + IconModule, + CommonModule, + ImageSliderComponent, + FooterComponent, + RouterModule + ], + templateUrl: './homepage-details.component.html', + styleUrl: './homepage-details.component.scss', +}) +export class HomepageDetailsComponent { + + topcards=topcardsGrid; + + + centered = false; + disabled = false; + unbounded = false; + radius: number; + color: string; + showBackground: boolean = false; + frameworks = frameworks; + selectedIndex = 1; + + readonly dialog = inject(MatDialog); + private router = inject(Router); + private destroyRef = inject(DestroyRef); // ✅ For automatic cleanup + private mediaMatcher = inject(MediaMatcher); // ✅ Proper MediaMatcher injection + + mobileQuery: MediaQueryList; + isMobileView = false; + + readonly panelOpenState = signal(false); + tiles = tiles; + hideCloserBtn: boolean = true; + users = users; + expandedIndex: number | null = null; + currentIndex = signal(0); // Starting from 0 + faqList = faqList; + selectedPath: string | null = null; + clicked = false; + + followercardsfirst = followercardsFirst; + followercardsecond = followercardSecond; + followercardthird = followercardThird; + + currentUser = computed(() => this.users[this.currentIndex()]); + displayCount = computed(() => `${this.currentIndex() + 1}/${this.users.length}`); + + constructor() { + const isSmallScreen = this.mediaMatcher.matchMedia('(max-width: 599px)'); + // ✅ Setup media query for max-width: 1199px + this.mobileQuery = this.mediaMatcher.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + const listener = (e: MediaQueryListEvent) => { + this.isMobileView = e.matches; + }; + + // ✅ Listen to viewport changes + this.mobileQuery.addEventListener('change', listener); + + // ✅ Clean up listener on component destroy + this.destroyRef.onDestroy(() => { + this.mobileQuery.removeEventListener('change', listener); + }); + } + isOver(): boolean { + return this.mediaMatcher.matchMedia('(max-width: 1199px)').matches; + } + + goPrev() { + if (this.currentIndex() > 0) { + this.currentIndex.update((i) => i - 1); + } + } + + goNext() { + if (this.currentIndex() < this.users.length - 1) { + this.currentIndex.update((i) => i + 1); + } + } + openDialog(showBackground:boolean){ + this.showBackground = showBackground; + + const dialogRef = this.dialog.open(TemplateVideoComponent, { + data: {}, + width: '1000px', + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result === false) { + this.showBackground = false; // Reset or take any action + } + }); + } + + + onImageClick(path: string) { + this.selectedPath = path; + + setTimeout(() => { + this.router.navigate([path]); + }, 100); // brief delay to show border + } +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/homepage/homepage.component.html b/theme/packages/horizontal/src/app/pages/front-pages/homepage/homepage.component.html new file mode 100644 index 0000000..532acf0 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/homepage/homepage.component.html @@ -0,0 +1,137 @@ +
+ + + @if(hideCloserBtn){ + + + + +
+ New + Frontend Pages Included! +
+ + + + +
+ + } + +
+
+
+ +
+ + @if(!isMobileView){ +
+ + + + + + + + +
+ Login + } @if(isMobileView){ + + } +
+
+
+ +
+ +
+
+ + + +
+
+ +
+
+ + + + + + + + + + + + + + + + + Get + Started + +
+
+
+
+ @if(showBackToTop){ +
+ +
+ } +
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/homepage/homepage.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/homepage/homepage.component.scss new file mode 100644 index 0000000..3cee318 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/homepage/homepage.component.scss @@ -0,0 +1,32 @@ +.landing-page { + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } + + .heightToolbar { + height: 46px; + background-size: cover; + background-repeat: no-repeat; + background-image: url(../../../../assets/images/front-pages/topbar-bg.png); + } + + .toolBarContent { + .nav-item { + &.selected { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); // optional for visibility + transition: background-color 0.3s ease; + } + + &:hover { + color: var(--mat-sys-primary); + transition: color 0.3s ease; + } + } + + } + +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/homepage/homepage.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/homepage/homepage.component.ts new file mode 100644 index 0000000..ca1a34a --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/homepage/homepage.component.ts @@ -0,0 +1,65 @@ +import { MediaMatcher } from '@angular/cdk/layout'; +import { CommonModule } from '@angular/common'; +import { Component, HostListener, inject, ViewChild } from '@angular/core'; +import { MatSidenav } from '@angular/material/sidenav'; +import { ActivatedRoute, Router, RouterLink, RouterOutlet } from '@angular/router'; +import { IconModule } from 'src/app/icon/icon.module'; +import { BrandingComponent } from 'src/app/layouts/full/vertical/sidebar/branding.component'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-homepage', + imports: [MaterialModule, BrandingComponent, RouterLink, + IconModule, RouterOutlet, CommonModule], + templateUrl: './homepage.component.html', + styleUrl: './homepage.component.scss' +}) +export class HomepageComponent { + @ViewChild('customizerRight') customizerRight!: MatSidenav; + selected: string = ''; // default selected + mobileQuery: MediaQueryList; + isMobileView = false; + hideCloserBtn: boolean = true; + private router = inject(Router) + private mediaMatcher: MediaQueryList = matchMedia(`(max-width: 1199px)`); + showBackToTop: boolean; + isTopbarFixed: boolean; + constructor(private route: ActivatedRoute) { + const media = inject(MediaMatcher); + this.mobileQuery = media.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + this.mobileQuery.addEventListener('change', (e) => { + + this.isMobileView = e.matches; + this.closeSidenavIfNeeded(); + }); + } + closeSidenavIfNeeded() { + if (!this.isMobileView && this.customizerRight?.opened) { + this.customizerRight.close(); + } + } + isOver(): boolean { + return this.mediaMatcher.matches; + } + + isActiveRoute(route: string): boolean { + return this.router.url.includes(`/front-pages/${route}`); + } + hideCloser() { + this.hideCloserBtn = false; + } + getNavigate() { + this.router.navigate(['/dashboards/dashboard1']) + } + + scrollToTop(): void { + window.scrollTo({ top: 0, behavior: 'smooth' }); + } + @HostListener('window:scroll', []) + onWindowScroll() { + this.showBackToTop = window.scrollY > 300; + this.isTopbarFixed = scrollY > 45; + } +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.html b/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.html new file mode 100644 index 0000000..f4c4b31 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.html @@ -0,0 +1,44 @@ +
+
+
+
+
+

Our leadership

+
+

+ Our robust analytics offer rich insights into the information + buyers want, informing where teams +

+
+
+ +
+
+ + +
+
+
+ +
+ @for (member of visibleTeamMembers(); track member.id){ +
+ + + imgSrc + + +

{{ member.name }}

+

{{ member.position }}

+
+
+
+ } +
+
+
+
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.scss new file mode 100644 index 0000000..0832285 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.scss @@ -0,0 +1,22 @@ +.img-slider-content { + .img-slider { + + .mat-mdc-card { + margin-bottom: 0px !important; + } + + .productcard { + position: relative; + + .info-card { + bottom: 42px; // controls overlap depth + left: 50%; + transform: translateX(-50%); + width: 90%; + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + z-index: 2; + } + } + + } +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts new file mode 100644 index 0000000..c933f20 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ImageSliderComponent } from './image-slider.component'; + +describe('ImageSliderComponent', () => { + let component: ImageSliderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ImageSliderComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ImageSliderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.ts new file mode 100644 index 0000000..d5db5ee --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/image-slider/image-slider.component.ts @@ -0,0 +1,39 @@ +import { Component, computed, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { team } from '../front-pagesData'; + +@Component({ + selector: 'app-image-slider', + imports: [MaterialModule,IconModule], + templateUrl: './image-slider.component.html', + styleUrl: './image-slider.component.scss' +}) +export class ImageSliderComponent { + team = team; + // Signals + currentPage = signal(0); + pageSize = 4; + + visibleTeamMembers = computed(() => { + const start = this.currentPage() * this.pageSize; + const end = start + this.pageSize; + return this.team.slice(start, end); + }); + + next() { + console.log('next--->',this.visibleTeamMembers().map(m => m.id)); + const totalPages = Math.ceil(this.team.length / this.pageSize); + if (this.currentPage() < totalPages - 1) { + this.currentPage.update((p) => p + 1); + } + } + + prev() { + console.log(this.visibleTeamMembers().map(m => m.id)); + if (this.currentPage() > 0) { + this.currentPage.update((p) => p - 1); + } + } + +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.html b/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.html new file mode 100644 index 0000000..32bdd60 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.html @@ -0,0 +1,68 @@ +
+
+

+ 111,476+ Trusted developers & many tech giants as well +

+
+
+
+ @for(plan of plans;track plan){ +
+ + + +
+
+ {{ plan.title }} + @if (plan.popular) { + + Popular + + } +
+
+

{{ plan.description }}

+ + +
+ ${{ plan.price }} + /{{ plan.period }} +
+
+ @for(feature of plan.features; track feature) { +
+ icon-facebook-dark + + + {{ feature.text }} + +
+ } +
+ + +
+
+ +
+ } + + +
+
+

Secured payment with PayPal & Razorpay

+
+ @for( logo of paymentLogos;track logo){ + + } +
+
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts new file mode 100644 index 0000000..fb0a9c8 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PagePricingComponent } from './page-pricing.component'; + +describe('PagePricingComponent', () => { + let component: PagePricingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PagePricingComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PagePricingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.ts new file mode 100644 index 0000000..7a435ae --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/page-pricing/page-pricing.component.ts @@ -0,0 +1,17 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { paymentLogos, plans } from '../front-pagesData'; + +@Component({ + selector: 'app-page-pricing', + imports: [MaterialModule, IconModule, CommonModule], + templateUrl: './page-pricing.component.html', + styleUrl: './page-pricing.component.scss', +}) +export class PagePricingComponent { + plans = plans; + + paymentLogos = paymentLogos; +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.html b/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.html new file mode 100644 index 0000000..f64670b --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.html @@ -0,0 +1,57 @@ + + +
+
+
+
+
Portfolio
+
+
{{ filteredCount }}
+
+
+ + + + search + + +
+
+ @for(productcard of filteredCardImgs; track productcard.id) { +
+ + + imgSrc + + + +
+ +
+
{{ productcard.title }}
+

{{ productcard.date }}

+
+ + + +
+
+
+
+
+ } +
+
+
+ \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts new file mode 100644 index 0000000..073ce35 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PortfolioComponent } from './portfolio.component'; + +describe('PortfolioComponent', () => { + let component: PortfolioComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PortfolioComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PortfolioComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.ts new file mode 100644 index 0000000..702ebee --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/portfolio/portfolio.component.ts @@ -0,0 +1,37 @@ + + +import { Component, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { productcards } from '../front-pagesData'; +import { FooterComponent } from '../footer/footer.component'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-portfolio', + imports: [MaterialModule, IconModule, FooterComponent, CommonModule, FormsModule], + templateUrl: './portfolio.component.html', + styleUrl: './portfolio.component.scss' +}) +export class PortfolioComponent implements OnInit { + + filteredCards = productcards; + + searchText: string = ''; + + filteredCardImgs = [...this.filteredCards]; // Initialize with full data + filteredCount: number = this.filteredCardImgs.length; + ngOnInit(): void { + console.log('filteredCards', this.filteredCards) + } + onSearchChange() { + const query = this.searchText.toLowerCase().trim(); + this.filteredCardImgs = this.filteredCards.filter(item => + item.title.toLowerCase().includes(query) || + item.date.toLowerCase().includes(query) + ); + this.filteredCount = this.filteredCardImgs.length; // ✅ update the count here + } +} + diff --git a/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.html b/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.html new file mode 100644 index 0000000..6c42e4a --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.html @@ -0,0 +1,18 @@ + + +
+
+ +
+
+ + \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.spec.ts new file mode 100644 index 0000000..147f94e --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PricingComponent } from './pricing.component'; + +describe('PricingComponent', () => { + let component: PricingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PricingComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PricingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.ts new file mode 100644 index 0000000..0684d59 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/pricing/pricing.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; +import { PagePricingComponent } from '../page-pricing/page-pricing.component'; + +@Component({ + selector: 'app-pricing', + imports: [MaterialModule,IconModule,FooterComponent,PagePricingComponent], + templateUrl: './pricing.component.html', + styleUrl: './pricing.component.scss' +}) +export class PricingComponent { + +} diff --git a/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.html b/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.html new file mode 100644 index 0000000..9b7d777 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.html @@ -0,0 +1,11 @@ + + + +
+ + +
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.scss b/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.spec.ts b/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.spec.ts new file mode 100644 index 0000000..46d7589 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TemplateVideoComponent } from './template-video.component'; + +describe('TemplateVideoComponent', () => { + let component: TemplateVideoComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TemplateVideoComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TemplateVideoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.ts b/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.ts new file mode 100644 index 0000000..b239adb --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/front-pages/template-video/template-video.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { MatDialogRef } from '@angular/material/dialog'; +@Component({ + selector: 'app-template-video', + imports: [MaterialModule, + IconModule,], + templateUrl: './template-video.component.html', + styleUrl: './template-video.component.scss' +}) +export class TemplateVideoComponent { +constructor(private dialogRef: MatDialogRef){ + +} +closeDialog(): void { + this.dialogRef.close(false); // Pass false back to parent +} +} diff --git a/theme/packages/horizontal/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts b/theme/packages/horizontal/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts new file mode 100644 index 0000000..de7ba0c --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts @@ -0,0 +1,69 @@ +export const BASIC_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + + /** + * @title slide-toggle + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatSlideToggleModule], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + } +`; + +export const FORM_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component, inject} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {FormBuilder, FormGroup, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {MatButtonModule} from '@angular/material/button'; + import { MatSlideToggleModule} from '@angular/material/slide-toggle'; + + /** + * @title Slide-toggle with forms + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatSlideToggleModule, FormsModule, MatButtonModule, ReactiveFormsModule,], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + + private _formBuilder = inject(FormBuilder); + + isChecked = true; + formGroup = this._formBuilder.group({ + enableWifi: '', + acceptTerms: ['', Validators.requiredTrue], + }); + + alertFormValues(formGroup: FormGroup) { + alert(JSON.stringify(formGroup.value, null, 2)); + } + } +`; + +export const CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {MatCheckboxModule} from '@angular/material/checkbox'; + import {FormsModule} from '@angular/forms'; + import {MatRadioModule} from '@angular/material/radio'; + import {MatCardModule} from '@angular/material/card'; + + /** + * @title Configurable slide-toggle + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatCardModule, MatRadioModule, FormsModule, MatCheckboxModule, MatSlideToggleModule], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + + checked = false; + disabled = false; + } +`; \ No newline at end of file diff --git a/theme/packages/horizontal/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts b/theme/packages/horizontal/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts new file mode 100644 index 0000000..804e79f --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts @@ -0,0 +1,63 @@ +import { Component, OnInit, inject } from '@angular/core'; +import {FormBuilder, FormGroup, Validators, ReactiveFormsModule} from '@angular/forms'; +import { + MatSlideToggleModule, + // _MatSlideToggleRequiredValidatorModule, +} from '@angular/material/slide-toggle'; +import {MatCheckboxModule} from '@angular/material/checkbox'; +import {FormsModule} from '@angular/forms'; +import {MatRadioModule} from '@angular/material/radio'; +import {MatCardModule} from '@angular/material/card'; +import {MatButtonModule} from '@angular/material/button'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_SLIDE_TOGGLE_HTML_SNIPPET, CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET, FORM_SLIDE_TOGGLE_HTML_SNIPPET } from './code/slide-toggle-html-snippet'; +import { BASIC_SLIDE_TOGGLE_TS_SNIPPET, CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET, FORM_SLIDE_TOGGLE_TS_SNIPPET } from './code/slide-toggle-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-slide-toggle', + imports: [MatCardModule, MatRadioModule, FormsModule, MatCheckboxModule, MatSlideToggleModule, ReactiveFormsModule, MatButtonModule, + // _MatSlideToggleRequiredValidatorModule + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './slide-toggle.component.html' +}) +export class AppSlideToggleComponent implements OnInit { + + // 1 [Basic with Slide Toggle] + codeForSlideToggleBasic = BASIC_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleBasicTs = BASIC_SLIDE_TOGGLE_TS_SNIPPET; + + // 2 [Form with Slide Toggle] + codeForSlideToggleForm = FORM_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleFormTs = FORM_SLIDE_TOGGLE_TS_SNIPPET; + + // 3 [Configuration with Slide Toggle] + codeForSlideToggleConfiguration = CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleConfigurationTs = CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET; + + // configuration + checked = false; + disabled = false; + + private _formBuilder = inject(FormBuilder); + + isChecked = true; + formGroup = this._formBuilder.group({ + enableWifi: '', + acceptTerms: ['', Validators.requiredTrue], + }); + + alertFormValues(formGroup: FormGroup) { + alert(JSON.stringify(formGroup.value, null, 2)); + } + + ngOnInit(): void {} +} diff --git a/theme/packages/horizontal/src/app/pages/widgets/cards/cards.component.html b/theme/packages/horizontal/src/app/pages/widgets/cards/cards.component.html new file mode 100644 index 0000000..051c1c9 --- /dev/null +++ b/theme/packages/horizontal/src/app/pages/widgets/cards/cards.component.html @@ -0,0 +1,348 @@ + + + + +
+ @for(topcard of topcards; track topcard) { +
+ + + users +

+ {{ topcard.title }} +

+
+ {{ topcard.subtitle }} +
+
+
+
+ } +
+ + + + +
+ @for(cardimg of cardimgs; track cardimg.imgSrc) { +
+ + Photo of a Shiba Inu +
+ {{ + cardimg.time + }} +
+ + +
+
+ +
+ {{ + cardimg.category + }} +
+ {{ cardimg.title }} +
+
+ {{ cardimg.views }} + {{ cardimg.comments }} +
+ + + {{ cardimg.date }} + +
+
+
+
+ } +
+ + + + +
+ @for(productcard of productcards; track productcard.title) { +
+ + + imgSrc + + + + {{ + productcard.title + }} +
+
+
${{ productcard.price }}
+ ${{ productcard.rprice }} +
+
+ + + + + +
+
+
+
+
+ } +
+ + + + +
+ @for(musiccard of musiccards; track musiccard.title) { +
+ +
+
+
{{ musiccard.title }}
+ {{ musiccard.subtext }} + +
+ + + +
+
+
+ blog +
+
+
+
+ } +
+ + + + +
+ @for(followercard of followercards; track followercard.title) { +
+ + +
+
+ user +
+
{{ followercard.title }}
+ {{ followercard.subtext }} +
+
+ +
+
+
+
+ } +
+ + + + +
+ @for(friendcard of friendcards; track friendcard.title) { +
+ + + user + {{ friendcard.title }} +
+
+ user + user + user +
+ 3 mutual friends +
+ + +
+
+
+ } +
+ + + + +
+ @for(socialcard of socialcards; track socialcard.username) { +
+ + + + {{ + socialcard.username + }} + {{ + socialcard.post + }} + +
+ + + + +
+
+
+ } +
+ + + + +
+ @for(giftcard of giftcards; track giftcard.username) { +
+ + +
+ {{ + giftcard.username + }} + +
+ + user + + +
+
+
+ } +
+ +
+ +
+ + + Payment Gateways + Platform For Income + + @for(stat of stats; track stat.title) { +
+
+ + icon + + +
+
{{ stat.title }}
+ {{ stat.subtitle }} +
+ +${{ stat.percent }} +
+
+ } + + +
+
+
+ + +
+ + + Upcoming Activity + In New year + + @for(activity of activities; track activity.title) { +
+
+ + + + +
+
{{ activity.title }}
+ {{ activity.subtitle }} +
+ {{ activity.time }} +
+
+ } +
+
+
+ + +
+ + + Recent Transactions + +
+ @for(stat of stats2; track stat.subtext) { +
+
{{ stat.time }}
+
+ + +
+
+ @if(stat.subtext) { + {{ stat.subtext }} + } + + @if(stat.title) { + {{ + stat.title + }} + } + + @if(stat.link) { + #ML-3467 + } +
+
+ } +
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/horizontal/src/app/services/apps/front-pages/front-end.service.spec.ts b/theme/packages/horizontal/src/app/services/apps/front-pages/front-end.service.spec.ts new file mode 100644 index 0000000..950ecc8 --- /dev/null +++ b/theme/packages/horizontal/src/app/services/apps/front-pages/front-end.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { FrontEndService } from './front-end.service'; + +describe('FrontEndService', () => { + let service: FrontEndService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(FrontEndService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/theme/packages/horizontal/src/app/services/apps/front-pages/front-end.service.ts b/theme/packages/horizontal/src/app/services/apps/front-pages/front-end.service.ts new file mode 100644 index 0000000..a736e66 --- /dev/null +++ b/theme/packages/horizontal/src/app/services/apps/front-pages/front-end.service.ts @@ -0,0 +1,21 @@ +import { Injectable, signal } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class FrontEndService { + + private blog = signal(null); + + constructor() { } + + + + setBlog(blogData: any) { + this.blog.set(blogData); + } + + getBlog() { + return this.blog; + } +} diff --git a/theme/packages/horizontal/src/assets/images/front-pages/app-chat.jpg b/theme/packages/horizontal/src/assets/images/front-pages/app-chat.jpg new file mode 100644 index 0000000..cffde47 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/app-chat.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/app-email.jpg b/theme/packages/horizontal/src/assets/images/front-pages/app-email.jpg new file mode 100644 index 0000000..5da2d90 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/app-email.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/banner-top-left.svg b/theme/packages/horizontal/src/assets/images/front-pages/banner-top-left.svg new file mode 100644 index 0000000..0b5d123 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/banner-top-left.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/banner-top-right.svg b/theme/packages/horizontal/src/assets/images/front-pages/banner-top-right.svg new file mode 100644 index 0000000..ce2deff --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/banner-top-right.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/bottom-part.svg b/theme/packages/horizontal/src/assets/images/front-pages/bottom-part.svg new file mode 100644 index 0000000..0a9f8f9 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/bottom-part.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/demo-dark.jpg b/theme/packages/horizontal/src/assets/images/front-pages/demo-dark.jpg new file mode 100644 index 0000000..1181c96 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/demo-dark.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/demo-horizontal.jpg b/theme/packages/horizontal/src/assets/images/front-pages/demo-horizontal.jpg new file mode 100644 index 0000000..a384d56 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/demo-horizontal.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/demo-main.jpg b/theme/packages/horizontal/src/assets/images/front-pages/demo-main.jpg new file mode 100644 index 0000000..895551e Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/demo-main.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/demo-rtl.jpg b/theme/packages/horizontal/src/assets/images/front-pages/demo-rtl.jpg new file mode 100644 index 0000000..a8011a3 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/demo-rtl.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/design-collection.png b/theme/packages/horizontal/src/assets/images/front-pages/design-collection.png new file mode 100644 index 0000000..08a4a50 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/design-collection.png differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-american-express.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-american-express.svg new file mode 100644 index 0000000..0cc1e3c --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-american-express.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-chart.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-chart.svg new file mode 100644 index 0000000..fa45961 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-chart.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-circle-check.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-circle-check.svg new file mode 100644 index 0000000..458ffdb --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-circle-check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-circle-x.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-circle-x.svg new file mode 100644 index 0000000..41b5593 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-circle-x.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-color.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-color.svg new file mode 100644 index 0000000..14d5f1a --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-color.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-components.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-components.svg new file mode 100644 index 0000000..a14b4e4 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-components.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-customize.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-customize.svg new file mode 100644 index 0000000..300ee35 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-customize.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-diners.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-diners.svg new file mode 100644 index 0000000..4ea5609 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-diners.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-discover.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-discover.svg new file mode 100644 index 0000000..12eebd5 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-discover.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-facebook.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-facebook.svg new file mode 100644 index 0000000..d0cfd8a --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-facebook.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-favorites.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-favorites.svg new file mode 100644 index 0000000..84fedaa --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-favorites.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-framework.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-framework.svg new file mode 100644 index 0000000..2718d0c --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-framework.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-icons.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-icons.svg new file mode 100644 index 0000000..87d1ae4 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-icons.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-instagram.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-instagram.svg new file mode 100644 index 0000000..6a73bf9 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-instagram.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-jcb.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-jcb.svg new file mode 100644 index 0000000..b71e935 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-jcb.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-masetro.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-masetro.svg new file mode 100644 index 0000000..5a84358 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-masetro.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-mastercard.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-mastercard.svg new file mode 100644 index 0000000..da591ae --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-mastercard.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-pages.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-pages.svg new file mode 100644 index 0000000..ac7ca4b --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-pages.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-paypal.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-paypal.svg new file mode 100644 index 0000000..7f8de85 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-paypal.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-responsive.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-responsive.svg new file mode 100644 index 0000000..fc57366 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-responsive.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-sass.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-sass.svg new file mode 100644 index 0000000..5751e1a --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-sass.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-sidebar.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-sidebar.svg new file mode 100644 index 0000000..1a0ca63 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-sidebar.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-speech-bubble.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-speech-bubble.svg new file mode 100644 index 0000000..2e1f2bd --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-speech-bubble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-support.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-support.svg new file mode 100644 index 0000000..6aa77a3 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-support.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-table.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-table.svg new file mode 100644 index 0000000..3fd98d7 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-table.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-twitter.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-twitter.svg new file mode 100644 index 0000000..e0b7780 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-twitter.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-update.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-update.svg new file mode 100644 index 0000000..94b5ed9 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-update.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/icon-visa.svg b/theme/packages/horizontal/src/assets/images/front-pages/icon-visa.svg new file mode 100644 index 0000000..7a06b63 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/icon-visa.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/front-pages/logoIcon.svg b/theme/packages/horizontal/src/assets/images/front-pages/logoIcon.svg new file mode 100644 index 0000000..90fdce0 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/front-pages/logoIcon.svg @@ -0,0 +1,11 @@ + + logoIcon + + + + + + \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/images/front-pages/topbar-bg.png b/theme/packages/horizontal/src/assets/images/front-pages/topbar-bg.png new file mode 100644 index 0000000..e11b4a5 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/topbar-bg.png differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/user1.jpg b/theme/packages/horizontal/src/assets/images/front-pages/user1.jpg new file mode 100644 index 0000000..eb505b5 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/user1.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/user2.jpg b/theme/packages/horizontal/src/assets/images/front-pages/user2.jpg new file mode 100644 index 0000000..f8aa6af Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/user2.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/user3.jpg b/theme/packages/horizontal/src/assets/images/front-pages/user3.jpg new file mode 100644 index 0000000..6478013 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/user3.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/user4.jpg b/theme/packages/horizontal/src/assets/images/front-pages/user4.jpg new file mode 100644 index 0000000..e599b2a Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/user4.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/front-pages/user5.jpg b/theme/packages/horizontal/src/assets/images/front-pages/user5.jpg new file mode 100644 index 0000000..494e402 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/front-pages/user5.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/landingpage/background/accordian1.jpg b/theme/packages/horizontal/src/assets/images/landingpage/background/accordian1.jpg new file mode 100644 index 0000000..d13def2 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/landingpage/background/accordian1.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/landingpage/background/design-collection.png b/theme/packages/horizontal/src/assets/images/landingpage/background/design-collection.png new file mode 100644 index 0000000..2886a14 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/landingpage/background/design-collection.png differ diff --git a/theme/packages/horizontal/src/assets/images/landingpage/background/feature-apps.png b/theme/packages/horizontal/src/assets/images/landingpage/background/feature-apps.png new file mode 100644 index 0000000..fef18c5 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/landingpage/background/feature-apps.png differ diff --git a/theme/packages/horizontal/src/assets/images/landingpage/background/screen1.png b/theme/packages/horizontal/src/assets/images/landingpage/background/screen1.png new file mode 100644 index 0000000..afd642a Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/landingpage/background/screen1.png differ diff --git a/theme/packages/horizontal/src/assets/images/landingpage/frameworks/angular.svg b/theme/packages/horizontal/src/assets/images/landingpage/frameworks/angular.svg new file mode 100644 index 0000000..bf081ac --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/landingpage/frameworks/angular.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/theme/packages/horizontal/src/assets/images/landingpage/frameworks/icon-tabler.svg b/theme/packages/horizontal/src/assets/images/landingpage/frameworks/icon-tabler.svg new file mode 100644 index 0000000..6e6810e --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/landingpage/frameworks/icon-tabler.svg @@ -0,0 +1,3 @@ + + + diff --git a/theme/packages/horizontal/src/assets/images/landingpage/frameworks/material.svg b/theme/packages/horizontal/src/assets/images/landingpage/frameworks/material.svg new file mode 100644 index 0000000..9ac2836 --- /dev/null +++ b/theme/packages/horizontal/src/assets/images/landingpage/frameworks/material.svg @@ -0,0 +1 @@ +material \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/images/profile/user-11.jpg b/theme/packages/horizontal/src/assets/images/profile/user-11.jpg new file mode 100644 index 0000000..8d54dc0 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/profile/user-11.jpg differ diff --git a/theme/packages/horizontal/src/assets/images/profile/user-12.jpg b/theme/packages/horizontal/src/assets/images/profile/user-12.jpg new file mode 100644 index 0000000..adbbde4 Binary files /dev/null and b/theme/packages/horizontal/src/assets/images/profile/user-12.jpg differ diff --git a/theme/packages/horizontal/src/assets/scss/_container.scss b/theme/packages/horizontal/src/assets/scss/_container.scss new file mode 100644 index 0000000..730c06f --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/_container.scss @@ -0,0 +1,154 @@ +@use "variables" as *; + +*, +:after, +:before { + box-sizing: border-box; +} + +body { + font-family: $font-family; + line-height: 1.334rem; + overflow-x: hidden; + color: var(--mat-sys-on-background); +} + +.mainWrapper { + display: flex; + min-height: 100vh; + width: 100%; + flex: 1; + height: 100%; +} + +.container { + max-width: 1200px; + padding-left: 24px; + padding-right: 24px; + margin: 0 auto; + + &.full-width { + display: flex; + align-items: center; + width: 100%; + } +} + +.pageWrapper { + padding: 24px; + min-height: calc(100vh - 70px); + + margin: 0 auto; + + &.maxWidth { + max-width: $boxedWidth; + } +} + +.w-100 { + width: 100%; +} + +.h-100 { + height: 100%; +} + +.shadow-none { + box-shadow: none !important; +} + +.rounded { + border-radius: $border-radius !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 25px !important; +} + +.overflow-hidden { + overflow: hidden; +} + +.text-decoration-none { + text-decoration: none; +} + +.position-relative { + position: relative; +} + +.table-responsive { + overflow-x: auto; + + td, + mat-cell { + white-space: nowrap; + padding: 16px; + } +} + +.op-5 { + opacity: 0.5; +} + +.cursor-pointer { + cursor: pointer; +} + +.avatar-group { + img { + border: 2px solid $white; + margin-right: -5px; + + &:last-child { + margin-right: 0; + } + } +} + +a { + color: var(--mat-sys-on-background); + + &:hover { + color: $primary; + } +} + +.filter-sidebar { + width: 290px; + position: fixed; + right: -290px; + top: 0; + z-index: 10; + height: 100%; + transition: all 0.3s ease-in-out; + box-shadow: var(--mat-sys-level3); + background-color: var(--mat-sys-background); + + &.open { + right: 0; + } +} + +pre { + margin: 0; + white-space: nowrap; +} + +td.hljs-ln-line.hljs-ln-numbers { + padding-right: 10px; +} + +@media (min-width: 768px) { + html .flex-sm-row { + flex-direction: row !important; + } +} + +.mat-drawer[style*="visibility: hidden"] { + display: none; +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/scss/apps/_contact-list.scss b/theme/packages/horizontal/src/assets/scss/apps/_contact-list.scss new file mode 100644 index 0000000..9cf1b85 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/apps/_contact-list.scss @@ -0,0 +1,59 @@ +@use "../variables" as *; + +@media (max-width: 1279px) { + .detail-part.movetodetail { + display: block; + position: absolute; + z-index: 9; + left: 0; + background: var(--mat-card-elevated-container-color); + } +} + +@media (max-width: 1279px) { + .welcome-app { + display: none; + } +} + +@media (max-width: 959px) { + .contact-detail-part { + display: none; + } + + .contact-detail-part.activeContact { + position: absolute !important; + top: 0; + left: 0; + display: block; + width: 100%; + height: 100%; + z-index: 999; + background-color: var(--mat-card-elevated-container-color); + } +} + +// contact app +.uploader { + .upload-image { + width: 100px; + height: auto; + cursor: pointer; + } + + input[type="file"] { + position: absolute; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + } +} + +.contact-listing { + .mdc-list-item__primary-text { + margin-bottom: -11px !important; + margin-top: 10px !important; + } +} diff --git a/theme/packages/horizontal/src/assets/scss/apps/_ecommerce.scss b/theme/packages/horizontal/src/assets/scss/apps/_ecommerce.scss new file mode 100644 index 0000000..467169d --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/apps/_ecommerce.scss @@ -0,0 +1,94 @@ +body { + + // Add Product + + .NgxEditor__Wrapper { + border: 1px solid var(--mat-sys-outline-variant); + } + + .NgxEditor__Seperator { + border-left: 1px solid var(--mat-sys-outline-variant); + } + + .NgxEditor__MenuBar { + background-color: var(--mat-card-elevated-container-color); + border-bottom: 1px solid var(--mat-sys-outline-variant) !important; + } + + .NgxEditor { + background: var(--mat-card-elevated-container-color); + color: var(--mat-sys-on-background); + } + + .NgxEditor__MenuItem .NgxEditor__MenuItem--Icon:hover { + background-color: var(--mat-sys-primary); + color: var(--mat-sys-background); + } + + .NgxEditor__Dropdown:hover { + background-color: var(--mat-sys-primary); + + .NgxEditor__Dropdown--Text { + color: var(--mat-sys-background); + } + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--Selected, + .NgxEditor__Dropdown .NgxEditor__Dropdown--Open { + color: var(--mat-sys-background); + background-color: var(--mat-sys-primary); + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--Item:hover { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--DropdownMenu { + background-color: var(--mat-card-elevated-container-color); + } + + + .dropzone-box { + border: 1px dashed var(--mat-sys-primary); + background-color: var(--mat-sys-primary-fixed-dim); + + .dropzone-content { + .preview-image { + width: 100px; + height: 70px; + object-fit: cover; + border-radius: 6px; + margin-bottom: 0.5rem; + } + } + + .headline { + margin: 0; + } + } + + .cards-circle { + width: 15px; + height: 15px; + border-radius: var(--mat-sys-corner-full); + display: flex; + align-items: center; + justify-content: center; + background-color: var(--mat-sys-primary); + + .theme-icon { + display: none; + } + + &.selected { + .theme-icon { + display: block; + color: white; + width: 18px; + height: 25px; + } + } + } + +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/scss/helpers/_custom-flex.scss b/theme/packages/horizontal/src/assets/scss/helpers/_custom-flex.scss new file mode 100644 index 0000000..fb36a29 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/helpers/_custom-flex.scss @@ -0,0 +1,59 @@ +@media (min-width: 1200px) { + body { + .d-lg-flex { + display: flex !important; + } + + .d-lg-none { + display: none !important; + } + + .d-lg-block { + display: block !important; + } + + .align-items-lg-center { + align-items: center !important; + } + } +} + +@media (min-width: 960px) { + .d-md-none { + display: none !important; + } +} + +@media (min-width: 768px) { + body { + .d-sm-flex { + display: flex !important; + } + } +} + +@media (max-width: 767px) { + .p-xs-6 { + padding: 0 6px !important; + } +} + +.flex-shrink-0 { + flex-shrink: 0; +} + +.flex-1-auto { + flex: 1 1 0%; +} + +.hstack { + display: flex; + flex-direction: row; + gap: 20px; +} + +@media (max-width: 767px) { + .hstack { + flex-direction: column; + } +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/scss/helpers/_icon-size.scss b/theme/packages/horizontal/src/assets/scss/helpers/_icon-size.scss new file mode 100644 index 0000000..ac526ef --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/helpers/_icon-size.scss @@ -0,0 +1,15 @@ +@use "sass:meta"; + +$columns: 54; + +@mixin icon_size { + @for $i from 1 through $columns { + .icon-#{$i} { + height: #{$i}px !important; + width: #{$i}px !important; + line-height: #{$i + 8}px !important; + } + } +} + +@include icon_size; diff --git a/theme/packages/horizontal/src/assets/scss/helpers/_text.scss b/theme/packages/horizontal/src/assets/scss/helpers/_text.scss new file mode 100644 index 0000000..1c2636e --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/helpers/_text.scss @@ -0,0 +1,84 @@ +@use "sass:map"; +@use "variables"; + +$utilities: ( + "font-size": ( + property: font-size, + class: f-s, + values: variables.$font-sizes, + ), + "font-weight": ( + property: font-weight, + class: f-w, + values: variables.$font-wieghts, + ), + "font-style": ( + property: font-style, + class: font, + values: italic normal, + ), + "text-align": ( + property: text-align, + class: text, + values: center right left, + ), + "text-decoration": ( + property: text-decoration, + class: text, + values: none underline line-through, + ), + "text-transform": ( + property: text-transform, + class: text, + values: capitalize uppercase lowercase, + ), + "white-space": ( + property: white-space, + class: text, + values: ( + wrap: normal, + nowrap: nowrap, + ), + ), + "word-wrap": ( + property: word-wrap word-break, + class: text, + values: ( + break: break-word, + ), + ), + "text-overflow": ( + property: text-overflow, + class: text, + values: ellipsis, + ), + "text-color": ( + property: color, + class: text, + values: ( + reset: inherit, + current: currentColor, + ), + ), +); + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0px; +} + +.lh-lg { + line-height: 36px !important; +} + +.lh-sm { + line-height: 20px !important; +} + +.lh-normal { + line-height: normal !important; +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/scss/helpers/_variables.scss b/theme/packages/horizontal/src/assets/scss/helpers/_variables.scss new file mode 100644 index 0000000..844ddf4 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/helpers/_variables.scss @@ -0,0 +1,102 @@ +@use "functions" as *; + +// Utility Map + +$utilities: () !default; + +// Spacing + +$spacer: 16px !default; +$spacers: ( + 0: 0, + 2: $spacer * 0.125, + 4: $spacer * 0.25, + 5: 5px, + 6: 7px, + 8: $spacer * 0.5, + 10: 10px, + 12: $spacer * 0.75, + 14: 14px, + 15: 15px, + 16: $spacer, + 20: 20px, + 24: $spacer * 1.5, + 30: 30px, + 32: $spacer * 2, + 44: 44px, + 48: $spacer * 3, + 60: 60px, + 66: 66px, + 80: 80px, +) !default; +$negative-spacers: negativify-map($spacers) !default; + +// Border + +$border-color: var(--mat-sys-outline-variant) !default; +$borders: ( + 0: 0, + 1: 1px solid $border-color, + 2: 2px solid $border-color, + 4: 4px solid $border-color, + 8: 8px solid $border-color, +) !default; + +// Border radius + +$radius-base: 7px !default; +$radius: ( + 0: 0, + 7: $radius-base, + 8: $radius-base * 2, + 12: $radius-base * 3, + 16: $radius-base * 4, + full: 9999px, +) !default; + +// Text + +$font-wieghts: ( + 100: 100, + 200: 200, + 300: 300, + 400: 400, + 500: 500, + 600: 600, + 700: 700, + 800: 800, + 900: 900, +) !default; + +$font-sizes: ( + 0: 0, + 10: 10px, + 12: 12px, + 14: 14px, + 15: 15px, + 16: 16px, + 18: 18px, + 20: 20px, + 21: 21px, + 24: 24px, + 28: 28px, + 30: 30px, + 36: 36px, + 40: 40px, + 48: 48px, +) !default; + +// Sizing + +$sizes: ( + 0: 0, + 20: 20%, + 25: 25%, + 40: 40%, + 50: 50%, + 60: 60%, + 75: 75%, + 80: 80%, + full: 100%, + auto: auto, +) !default; diff --git a/theme/packages/horizontal/src/assets/scss/layouts/_header.scss b/theme/packages/horizontal/src/assets/scss/layouts/_header.scss new file mode 100644 index 0000000..d24e1f8 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/layouts/_header.scss @@ -0,0 +1,64 @@ +@use "../variables" as *; + +html .topbar { + position: sticky; + top: 0; + z-index: 9; + height: $header-height; + + .notification-badge{ + .mat-badge-content{ + left: 80%; + bottom: 85%; + width: 16px; + height: 16px; + } + } +} + +.topbar-dd { + min-width: 360px !important; +} + +.apps-dd { + min-width: 830px !important; + overflow: unset !important; + + .mat-mdc-menu-content { + padding: 0; + } +} + +.text-hover-primary:hover { + .hover-text { + color: $primary; + } +} + +.upgrade-bg { + position: absolute; + top: 0px; + right: 0px; + height: 100%; +} + +.object-cover { + object-fit: cover; +} + +.profile-dd { + margin-top: -5px; + margin-left: -5px; +} + +.dark-theme { + .topbar { + .mat-mdc-icon-button { + color: $dark-text-secondary !important; + } + + .mdc-button { + --mat-button-text-label-text-color: $dark-text-secondary !important; + } + } +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/scss/override-component/_checkbox.scss b/theme/packages/horizontal/src/assets/scss/override-component/_checkbox.scss new file mode 100644 index 0000000..eba7679 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/override-component/_checkbox.scss @@ -0,0 +1,23 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.checkbox-overrides( + ( + unselected-focus-icon-color: + var(--mat-checkbox-unselected-hover-state-layer-color), + ) +); + +// styles +html { + .mdc-checkbox__background { + border-radius: 4px; + width: 21px; + height: 21px; + border: 1px solid var(--mat-sys-outline); + } + + .mdc-checkbox .mdc-checkbox__native-control:focus ~ .mdc-checkbox__ripple { + background-color: var(--mat-checkbox-unselected-hover-state-layer-color); + } +} diff --git a/theme/packages/horizontal/src/assets/scss/override-component/_datepicker.scss b/theme/packages/horizontal/src/assets/scss/override-component/_datepicker.scss new file mode 100644 index 0000000..2686873 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/override-component/_datepicker.scss @@ -0,0 +1,11 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.datepicker-overrides( + ( + calendar-container-background-color: + var(--mat-card-elevated-container-color), + calendar-container-touch-elevation-shadow: var(--mat-sys-level1), + calendar-container-elevation-shadow: var(--mat-sys-level1), + ) +); diff --git a/theme/packages/horizontal/src/assets/scss/override-component/_expansion.scss b/theme/packages/horizontal/src/assets/scss/override-component/_expansion.scss new file mode 100644 index 0000000..0c5f781 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/override-component/_expansion.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.expansion-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/horizontal/src/assets/scss/override-component/_paginator.scss b/theme/packages/horizontal/src/assets/scss/override-component/_paginator.scss new file mode 100644 index 0000000..35479e7 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/override-component/_paginator.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.paginator-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/horizontal/src/assets/scss/override-component/_stepper.scss b/theme/packages/horizontal/src/assets/scss/override-component/_stepper.scss new file mode 100644 index 0000000..6a21bd4 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/override-component/_stepper.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.stepper-overrides( + ( + container-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/horizontal/src/assets/scss/override-component/_table.scss b/theme/packages/horizontal/src/assets/scss/override-component/_table.scss new file mode 100644 index 0000000..379ddcd --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/override-component/_table.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.table-overrides( + ( + background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/horizontal/src/assets/scss/override-component/_tree.scss b/theme/packages/horizontal/src/assets/scss/override-component/_tree.scss new file mode 100644 index 0000000..e755adc --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/override-component/_tree.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.tree-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/horizontal/src/assets/scss/pages/_dashboards.scss b/theme/packages/horizontal/src/assets/scss/pages/_dashboards.scss new file mode 100644 index 0000000..796c344 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/pages/_dashboards.scss @@ -0,0 +1,126 @@ +@use "../variables" as *; + +.social-chips { + img { + margin-left: -9px; + border: 2px solid $white; + + &:first-child { + margin-left: 0; + } + } +} + +.minus-img { + margin-bottom: -65px !important; +} + +// theme select +.theme-select { + width: 145px; +} + +// dashboard 2 +.welcome-img { + margin-bottom: -82px; + margin-top: -9px; +} + +.timeline { + position: relative; + + .timeline-item { + position: relative; + height: 70px; + + .time { + padding: 6px 16px 6px 0; + min-width: 90px; + flex-shrink: 0; + } + + .desc { + padding: 6px 16px; + } + + .timline-border { + width: 1px; + height: 100%; + background-color: $borderColor; + flex-shrink: 0; + } + + .point { + flex-direction: column; + + .timeline-badge { + width: 12px; + height: 12px; + border-radius: 50px; + background-color: transparent; + flex-shrink: 0; + + &.border-primary { + border: 2px solid $primary; + } + + &.border-accent { + border: 2px solid $accent; + } + + &.border-success { + border: 2px solid $success; + } + + &.border-warning { + border: 2px solid $warning; + } + + &.border-error { + border: 2px solid $error; + } + } + + .timeline-border { + width: 1px; + height: 100%; + background-color: $borderColor; + flex-shrink: 0; + } + } + + &:last-child { + .timeline-border { + display: none !important; + } + } + } +} + +// expansion panel + +html .mat-expansion-panel:not([class*="mat-elevation-z"]) { + box-shadow: var(--mat-sys-level2); +} + +.most-visit-chart { + .apexcharts-bar-series.apexcharts-plot-series .apexcharts-series path { + clip-path: inset(0 0 5% 0 round 20px); + } +} + + +// User Profile Tab +.profileTabs { + background-color: var(--mat-sys-surface-bright); + + .mat-mdc-tab-label-container{ + border-bottom-width: 0; + } + + .mat-mdc-tab.mdc-tab-indicator--active{ + .mdc-tab__text-label{ + color: var(--mat-sys-primary) !important; + } + } +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/scss/pages/_frontend.scss b/theme/packages/horizontal/src/assets/scss/pages/_frontend.scss new file mode 100644 index 0000000..db45c10 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/pages/_frontend.scss @@ -0,0 +1,143 @@ +.front-topbar { + &.fixed-topbar { + position: fixed; + top: 0; + width: 100%; + background-color: var(--mat-sys-background) !important; + z-index: 9; + } +} + +.back-to-top { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 999; + transition: opacity 0.3s ease; +} + +.tab-header { + + .profileTabs { + + .mat-mdc-tab { + padding: 30px 16px; + height: auto; + border-right: 1px solid var(--mat-sys-outline); + + &:last-child { + border-right: 0; + } + } + + .mat-mdc-tab-label-container { + border-top-width: 0; + } + } + +} + +.home-page .expansion-panel .mat-expansion-panel-body { + padding: 16px 0; +} + +.faq-accordion { + .mat-expansion-panel-body { + padding: 16px 24px !important; + } +} + +.mobile-sidebar { + .mdc-list { + .mdc-list-item { + .mat-mdc-button { + color: var(--mat-sys-on-background); + min-width: 100%; + justify-content: flex-start; + + &.selected { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); + transition: background-color 0.3s ease; + } + } + } + } +} + + +.spacing-top-bottom { + padding: 80px 0; +} + +.spacing-left-right { + padding: 0 80px; +} + +.spacing-left { + padding-left: 80px; +} + +.spacing-top { + padding-top: 80px; +} + +.spacing-bottom { + padding-bottom: 80px; +} + +@media (max-width: 959px) { + .section-sub-title { + font-size: 30px !important; + } + + .spacing-top-bottom { + padding: 60px 0; + } + + .spacing-left-right { + padding: 0 60px; + } + + .spacing-left { + padding-left: 60px; + } + + .spacing-top { + padding-top: 60px; + } + + .spacing-bottom { + padding-bottom: 60px; + } +} + +@media (max-width: 767px) { + .section-sub-title { + font-size: 24px !important; + } + + .spacing-top-bottom { + padding: 30px 0; + } + + .spacing-left-right { + padding: 0 30px; + } + + .spacing-left { + padding-left: 30px; + } + + .spacing-top { + padding-top: 30px; + } + + .spacing-bottom { + padding-bottom: 30px; + } + + .footer-content .left-side-content { + padding: 30px !important; + } +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/scss/style.scss b/theme/packages/horizontal/src/assets/scss/style.scss new file mode 100644 index 0000000..177d3f7 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/style.scss @@ -0,0 +1,51 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@use "themecolors/blue_theme"; +@use "themecolors/orange_theme"; +@use "themecolors/aqua_theme"; +@use "themecolors/cyan_theme"; +@use "themecolors/green_theme"; +@use "themecolors/purple_theme"; + +@use "variables" as *; +@use "override-component"; +@use "theme-variables/default-variables"; +@use "theme-variables/light-theme-variables"; +@use "theme-variables/dark-theme-variables"; + +//container layout +@use "layouts/transitions"; +@use "helpers/color"; +@use "helpers/border-color"; +@use "helpers/icon-size"; +@use "container"; +@use "layouts/layouts"; +@use "grid/grid"; +@use "helpers/custom-flex"; +@use "helpers"; + +// horizontal +@use "horizontal/horizontal"; +@use "dark/dark"; + +// apps +@use "apps/calendar"; +@use "apps/email"; +@use "apps/blogs"; +@use "apps/chat"; +@use "apps/contact-list"; +@use "apps/kanban"; +@use "apps/courses"; +@use "apps/todo"; +@use "apps/ecommerce"; + +@use "pages/auth"; +@use "pages/dashboards"; +@use "pages/landingpage"; +@use "pages/toast"; +@use "pages/pricing"; +@use "pages/frontend"; + +// RTL Theme +@use "rtl/rtl"; \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/scss/theme-variables/_dark-theme-variables.scss b/theme/packages/horizontal/src/assets/scss/theme-variables/_dark-theme-variables.scss new file mode 100644 index 0000000..0375fc4 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/theme-variables/_dark-theme-variables.scss @@ -0,0 +1,32 @@ +@use "@angular/material" as mat; + +html.dark-theme { + color-scheme: dark; + --mat-sys-background: #141a21; + --mat-sys-on-background: rgba(255, 255, 255, 0.9); + --mat-sys-on-primary: #fff; + --mat-sys-surface-bright: #ffffff05; + --mat-sys-surface: #141a21; + --mat-sys-surface-container: #141a21; + --mat-sys-surface-container-low: #141a21; + --mat-sys-outline-variant: #2e3f50; + --mat-sys-outline: #2e3f50; + --mat-form-field-outlined-hover-outline-color: #465670; + --mat-checkbox-unselected-hover-state-layer-color: #19212a; + --mat-menu-item-hover-state-layer-color: #19212a; + --mat-button-toggle-state-layer-color: #19212a; + --mat-option-focus-state-layer-color: #19212a; + --mat-option-hover-state-layer-color: #19212a; + --mat-slide-toggle-unselected-track-color: #19212a; + --mat-stepper-header-focus-state-layer-color: #19212a; + --mat-stepper-header-hover-state-layer-color: #19212a; + --mat-expansion-header-hover-state-layer-color: #19212a; + @include mat.card-overrides((elevated-container-color: #1c252e, + elevated-container-elevation: rgba(0, 0, 0, 0.2) 0px 0px 2px 0px, + subtitle-text-color: rgba(255, 255, 255, 0.67), + )); + @include mat.theme-overrides((level1: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level2: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level3: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + )); +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/scss/theme-variables/_default-variables.scss b/theme/packages/horizontal/src/assets/scss/theme-variables/_default-variables.scss new file mode 100644 index 0000000..e3adeb2 --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/theme-variables/_default-variables.scss @@ -0,0 +1,12 @@ +html { + --mat-sys-error-fixed-dim: rgba(247, 68, 86, 0.15); + --mat-select-container-elevation-shadow: var(--mat-sys-level3); + --mat-list-list-item-label-text-tracking: 0; + --mat-slide-toggle-track-height: 28px; + --mat-sidenav-container-divider-color: var(--mat-sys-outline-variant); + --mat-dialog-with-actions-content-padding: 20px 24px; + --mat-form-field-container-text-tracking: unset; + --mat-slide-toggle-with-icon-handle-size: 21px; + --mat-badge-text-color: white; + --mat-slide-toggle-selected-with-icon-handle-horizontal-margin: 0 26px; +} \ No newline at end of file diff --git a/theme/packages/horizontal/src/assets/scss/theme-variables/_light-theme-variables.scss b/theme/packages/horizontal/src/assets/scss/theme-variables/_light-theme-variables.scss new file mode 100644 index 0000000..735309e --- /dev/null +++ b/theme/packages/horizontal/src/assets/scss/theme-variables/_light-theme-variables.scss @@ -0,0 +1,23 @@ +html.light-theme { + color-scheme: light; + --mat-sys-corner-small: 7px; + --mat-sys-background: #fff; + --mat-sys-surface-bright: #f2f6fa; + --mat-sys-surface: #fff; + --mat-sys-surface-container: #fff; + --mat-sys-surface-container-low: #fff; + --mat-sys-on-background: #2a3547; + --mat-sys-outline: #d7dde2; + --mat-sys-outline-variant: #d7dde2; + --mat-form-field-outlined-hover-outline-color: #d7dde2; + --mat-checkbox-unselected-hover-state-layer-color: #d7dde2; + --mat-menu-item-hover-state-layer-color: #f6f9fc; + --mat-button-toggle-state-layer-color: #f6f9fc; + --mat-option-focus-state-layer-color: #f6f9fc; + --mat-option-hover-state-layer-color: #f6f9fc; + --mat-slide-toggle-unselected-track-color: #f6f9fc; + --mat-stepper-header-focus-state-layer-color: #f6f9fc; + --mat-stepper-header-hover-state-layer-color: #f6f9fc; + --mat-dialog-supporting-text-color: var(--mat-sys-on-background); + --mat-expansion-header-hover-state-layer-color: #f6f9fc; + } \ No newline at end of file diff --git a/theme/packages/horizontal/src/index.html b/theme/packages/horizontal/src/index.html new file mode 100644 index 0000000..344a5f2 --- /dev/null +++ b/theme/packages/horizontal/src/index.html @@ -0,0 +1,17 @@ + + + + + Modernize Angular 20 Admin Template + + + + + + + + + + + \ No newline at end of file diff --git a/theme/packages/horizontal/tsconfig.json b/theme/packages/horizontal/tsconfig.json new file mode 100644 index 0000000..c3587c1 --- /dev/null +++ b/theme/packages/horizontal/tsconfig.json @@ -0,0 +1,34 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "strictPropertyInitialization": false, + "lib": [ + "ES2022", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true, + } +} diff --git a/theme/packages/main/.editorconfig b/theme/packages/main/.editorconfig new file mode 100644 index 0000000..59d9a3a --- /dev/null +++ b/theme/packages/main/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/theme/packages/main/.gitignore b/theme/packages/main/.gitignore new file mode 100644 index 0000000..0711527 --- /dev/null +++ b/theme/packages/main/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/theme/packages/main/.npmrc b/theme/packages/main/.npmrc new file mode 100644 index 0000000..e9ee3cb --- /dev/null +++ b/theme/packages/main/.npmrc @@ -0,0 +1 @@ +legacy-peer-deps=true \ No newline at end of file diff --git a/theme/packages/main/README.md b/theme/packages/main/README.md new file mode 100644 index 0000000..4e00817 --- /dev/null +++ b/theme/packages/main/README.md @@ -0,0 +1,2 @@ +# Modernize-Angular-pro +Modernize Angular Admin Dashboard diff --git a/theme/packages/main/angular.json b/theme/packages/main/angular.json new file mode 100644 index 0000000..0f19c10 --- /dev/null +++ b/theme/packages/main/angular.json @@ -0,0 +1,126 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "Modernize": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "allowedCommonJsDependencies": ["apexcharts", "bezier-easing", "chance"], + "outputPath": { + "base": "dist/Modernize" + }, + "index": "src/index.html", + "polyfills": ["zone.js"], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": [ + + "src/styles.scss", + "src/assets/scss/style.scss", + "node_modules/ngx-toastr/toastr.css", + "node_modules/angular-calendar/css/angular-calendar.css", + "node_modules/highlight.js/styles/atom-one-dark.min.css" + ], + "scripts": [], + "browser": "src/main.ts" + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "12mb", + "maximumError": "12mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "12mb", + "maximumError": "12mb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "Modernize:build:production" + }, + "development": { + "buildTarget": "Modernize:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular/build:extract-i18n", + "options": { + "buildTarget": "Modernize:build" + } + }, + "test": { + "builder": "@angular/build:karma", + "options": { + "polyfills": ["zone.js", "zone.js/testing"], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], + "scripts": [] + } + } + } + } + }, + "cli": { + "analytics": false + }, + "schematics": { + "@schematics/angular:component": { + "type": "component" + }, + "@schematics/angular:directive": { + "type": "directive" + }, + "@schematics/angular:service": { + "type": "service" + }, + "@schematics/angular:guard": { + "typeSeparator": "." + }, + "@schematics/angular:interceptor": { + "typeSeparator": "." + }, + "@schematics/angular:module": { + "typeSeparator": "." + }, + "@schematics/angular:pipe": { + "typeSeparator": "." + }, + "@schematics/angular:resolver": { + "typeSeparator": "." + } + } +} diff --git a/theme/packages/main/netlify.toml b/theme/packages/main/netlify.toml new file mode 100644 index 0000000..ff1c050 --- /dev/null +++ b/theme/packages/main/netlify.toml @@ -0,0 +1,4 @@ +[[redirects]] + from = "/*" + to = "/index.html" + status = 200 \ No newline at end of file diff --git a/theme/packages/main/package.json b/theme/packages/main/package.json new file mode 100644 index 0000000..51d6f74 --- /dev/null +++ b/theme/packages/main/package.json @@ -0,0 +1,62 @@ +{ + "name": "modernize", + "version": "3.1.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^20.0.4", + "@angular/cdk": "^20.0.3", + "@angular/common": "^20.0.4", + "@angular/compiler": "^20.0.4", + "@angular/core": "^20.0.4", + "@angular/forms": "^20.0.4", + "@angular/material": "^20.0.3", + "@angular/platform-browser": "^20.0.4", + "@angular/platform-browser-dynamic": "^20.0.4", + "@angular/router": "^20.0.4", + "@ng-matero/extensions": "^20.1.0", + "@ngx-translate/core": "^16.0.4", + "@ngx-translate/http-loader": "^16.0.1", + "angular-calendar": "^0.31.1", + "angular-tabler-icons": "^3.26.0", + "apexcharts": "^4.7.0", + "chance": "^1.1.13", + "date-fns": "^4.1.0", + "highlight.js": "^11.11.1", + "ng-apexcharts": "^1.16.0", + "ng2-search-filter": "^0.5.1", + "ngx-dropzone": "^3.1.0", + "ngx-editor": "^19.0.0-beta.1", + "ngx-highlightjs": "^14.0.1", + "ngx-owl-carousel-o": "^20.0.0", + "ngx-pagination": "^6.0.3", + "ngx-permissions": "^19.0.0", + "ngx-scrollbar": "^18.0.0", + "ngx-toastr": "^19.0.0", + "rxjs": "~7.8.2", + "sass": "^1.89.2", + "tslib": "^2.8.1", + "zone.js": "~0.15.1" + }, + "devDependencies": { + "@angular/build": "^20.0.3", + "@angular/cli": "~20.0.3", + "@angular/compiler-cli": "^20.0.4", + "@types/chance": "^1.1.6", + "@types/date-fns": "^2.6.3", + "@types/jasmine": "~5.1.8", + "jasmine-core": "~5.8.0", + "karma": "~6.4.4", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.1", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.8.3" + } +} diff --git a/theme/packages/main/src/app/app.component.html b/theme/packages/main/src/app/app.component.html new file mode 100644 index 0000000..0680b43 --- /dev/null +++ b/theme/packages/main/src/app/app.component.html @@ -0,0 +1 @@ + diff --git a/theme/packages/main/src/app/app.component.spec.ts b/theme/packages/main/src/app/app.component.spec.ts new file mode 100644 index 0000000..71cb3e3 --- /dev/null +++ b/theme/packages/main/src/app/app.component.spec.ts @@ -0,0 +1,35 @@ +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + RouterTestingModule + ], + declarations: [ + AppComponent + ], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title 'Angular15'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('Angular15'); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('.content span')?.textContent).toContain('Angular15 app is running!'); + }); +}); diff --git a/theme/packages/main/src/app/app.component.ts b/theme/packages/main/src/app/app.component.ts new file mode 100644 index 0000000..0f5c842 --- /dev/null +++ b/theme/packages/main/src/app/app.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + selector: 'app-root', + imports: [RouterOutlet], + templateUrl: './app.component.html' +}) +export class AppComponent { + title = 'Modernize Angular Admin Tempplate'; +} diff --git a/theme/packages/main/src/app/app.config.ts b/theme/packages/main/src/app/app.config.ts new file mode 100644 index 0000000..16815e4 --- /dev/null +++ b/theme/packages/main/src/app/app.config.ts @@ -0,0 +1,92 @@ +import { + ApplicationConfig, + provideZoneChangeDetection, + importProvidersFrom, +} from '@angular/core'; +import { + HttpClient, + provideHttpClient, + withInterceptorsFromDi, +} from '@angular/common/http'; +import { routes } from './app.routes'; +import { + provideRouter, + withComponentInputBinding, + withInMemoryScrolling, +} from '@angular/router'; +import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; +import { provideClientHydration } from '@angular/platform-browser'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateHttpLoader } from '@ngx-translate/http-loader'; + +import { ToastrModule } from 'ngx-toastr'; +import { provideToastr } from 'ngx-toastr'; + +// icons +import { TablerIconsModule } from 'angular-tabler-icons'; +import * as TablerIcons from 'angular-tabler-icons/icons'; + +// perfect scrollbar +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { NgxPermissionsModule } from 'ngx-permissions'; +//Import all material modules +import { MaterialModule } from './material.module'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { CalendarModule, DateAdapter } from 'angular-calendar'; +import { adapterFactory } from 'angular-calendar/date-adapters/date-fns'; + +// code view +import { provideHighlightOptions } from 'ngx-highlightjs'; +import 'highlight.js/styles/atom-one-dark.min.css'; + +export function HttpLoaderFactory(http: HttpClient): any { + return new TranslateHttpLoader(http, './assets/i18n/', '.json'); +} + +export const appConfig: ApplicationConfig = { + providers: [ + provideAnimationsAsync(), // required animations providers + provideToastr(), // Toastr providers + provideZoneChangeDetection({ eventCoalescing: true }), + provideHighlightOptions({ + coreLibraryLoader: () => import('highlight.js/lib/core'), + lineNumbersLoader: () => import('ngx-highlightjs/line-numbers'), // Optional, add line numbers if needed + languages: { + typescript: () => import('highlight.js/lib/languages/typescript'), + css: () => import('highlight.js/lib/languages/css'), + xml: () => import('highlight.js/lib/languages/xml'), + }, + }), + provideRouter( + routes, + withInMemoryScrolling({ + scrollPositionRestoration: 'enabled', + anchorScrolling: 'enabled', + }), + withComponentInputBinding() + ), + provideHttpClient(withInterceptorsFromDi()), + provideClientHydration(), + provideAnimationsAsync(), + importProvidersFrom( + FormsModule, + ToastrModule.forRoot(), + ReactiveFormsModule, + MaterialModule, + NgxPermissionsModule.forRoot(), + TablerIconsModule.pick(TablerIcons), + NgScrollbarModule, + CalendarModule.forRoot({ + provide: DateAdapter, + useFactory: adapterFactory, + }), + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: HttpLoaderFactory, + deps: [HttpClient], + }, + }) + ), + ], +}; diff --git a/theme/packages/main/src/app/app.routes.ts b/theme/packages/main/src/app/app.routes.ts new file mode 100644 index 0000000..f1bf19f --- /dev/null +++ b/theme/packages/main/src/app/app.routes.ts @@ -0,0 +1,107 @@ +import { Routes } from '@angular/router'; +import { BlankComponent } from './layouts/blank/blank.component'; +import { FullComponent } from './layouts/full/full.component'; + +export const routes: Routes = [ + { + path: '', + component: FullComponent, + children: [ + { + path: '', + redirectTo: '/dashboards/dashboard1', + pathMatch: 'full', + }, + { + path: 'starter', + loadChildren: () => + import('./pages/pages.routes').then((m) => m.PagesRoutes), + }, + { + path: 'dashboards', + loadChildren: () => + import('./pages/dashboards/dashboards.routes').then( + (m) => m.DashboardsRoutes + ), + }, + + { + path: 'forms', + loadChildren: () => + import('./pages/forms/forms.routes').then((m) => m.FormsRoutes), + }, + { + path: 'charts', + loadChildren: () => + import('./pages/charts/charts.routes').then((m) => m.ChartsRoutes), + }, + { + path: 'apps', + loadChildren: () => + import('./pages/apps/apps.routes').then((m) => m.AppsRoutes), + }, + { + path: 'widgets', + loadChildren: () => + import('./pages/widgets/widgets.routes').then((m) => m.WidgetsRoutes), + }, + { + path: 'tables', + loadChildren: () => + import('./pages/tables/tables.routes').then((m) => m.TablesRoutes), + }, + { + path: 'datatable', + loadChildren: () => + import('./pages/datatable/datatable.routes').then( + (m) => m.DatatablesRoutes + ), + }, + { + path: 'theme-pages', + loadChildren: () => + import('./pages/theme-pages/theme-pages.routes').then( + (m) => m.ThemePagesRoutes + ), + }, + { + path: 'ui-components', + loadChildren: () => + import('./pages/ui-components/ui-components.routes').then( + (m) => m.UiComponentsRoutes + ), + }, + ], + }, + { + path: '', + component: BlankComponent, + children: [ + { + path: 'authentication', + loadChildren: () => + import('./pages/authentication/authentication.routes').then( + (m) => m.AuthenticationRoutes + ), + }, + { + path: 'landingpage', + loadChildren: () => + import('./pages/theme-pages/landingpage/landingpage.routes').then( + (m) => m.LandingPageRoutes + ), + }, + { + path: 'front-pages', + loadChildren: () => + import('./pages/front-pages/front-pages.routes').then( + (m) => m.FrontPagesRoutes + ), + }, + ], + }, + { + path: '**', + redirectTo: 'authentication/error', + }, +]; diff --git a/theme/packages/main/src/app/components/code-view/code-view.component.html b/theme/packages/main/src/app/components/code-view/code-view.component.html new file mode 100644 index 0000000..90a2716 --- /dev/null +++ b/theme/packages/main/src/app/components/code-view/code-view.component.html @@ -0,0 +1,23 @@ + +
+ @if (isTitle) { +
+ +
+ } +
+ + + +
+ +
+
+ + + + + + +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/components/code-view/code-view.component.ts b/theme/packages/main/src/app/components/code-view/code-view.component.ts new file mode 100644 index 0000000..846d186 --- /dev/null +++ b/theme/packages/main/src/app/components/code-view/code-view.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; +import { MatTabsModule } from '@angular/material/tabs'; + +@Component({ + selector: 'app-code-view', + templateUrl: './code-view.component.html', + imports: [MatTabsModule, MatCardModule], +}) +export class AppCodeViewComponent implements OnInit { + constructor() {} + @Input() isTitle!: boolean; + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/components/dashboard1/customers/customers.component.html b/theme/packages/main/src/app/components/dashboard1/customers/customers.component.html new file mode 100644 index 0000000..b47d39a --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/customers/customers.component.html @@ -0,0 +1,31 @@ + + + + Customers +
36,358
+ +
+ +
+9%
+
+
+ + + + +
diff --git a/theme/packages/main/src/app/components/dashboard1/customers/customers.component.ts b/theme/packages/main/src/app/components/dashboard1/customers/customers.component.ts new file mode 100644 index 0000000..f4d93c1 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/customers/customers.component.ts @@ -0,0 +1,79 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexDataLabels, + ApexLegend, + ApexStroke, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexResponsive, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +export interface customerChart { + series: ApexAxisChartSeries; + chart: ApexChart; + dataLabels: ApexDataLabels; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + stroke: ApexStroke; + legend: ApexLegend; + responsive: ApexResponsive; +} +@Component({ + selector: 'app-customers', + imports: [NgApexchartsModule, MaterialModule, TablerIconsModule], + templateUrl: './customers.component.html', +}) +export class AppCustomersComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public customerChart!: Partial | any; + + constructor() { + this.customerChart = { + series: [ + { + name: '', + color: '#49BEFF', + data: [30, 25, 35, 20, 30, 40], + }, + ], + + chart: { + type: 'area', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 80, + sparkline: { + enabled: true, + }, + group: 'sparklines', + }, + stroke: { + curve: 'smooth', + width: 2, + }, + fill: { + colors: ['#E8F7FF'], + type: 'solid', + opacity: 0.05, + }, + markers: { + size: 0, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard1/employee-salary/employee-salary.component.html b/theme/packages/main/src/app/components/dashboard1/employee-salary/employee-salary.component.html new file mode 100644 index 0000000..58f675f --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/employee-salary/employee-salary.component.html @@ -0,0 +1,50 @@ + + + Employee Salary + Every month + + + + + + + +
+
+ + + + +
+ Salary +
$36,358
+
+
+
+ + + + +
+ Profit +
$5,296
+
+
+
+
+
diff --git a/theme/packages/main/src/app/components/dashboard1/employee-salary/employee-salary.component.ts b/theme/packages/main/src/app/components/dashboard1/employee-salary/employee-salary.component.ts new file mode 100644 index 0000000..4305e8c --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/employee-salary/employee-salary.component.ts @@ -0,0 +1,102 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexDataLabels, + ApexLegend, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexGrid, + ApexXAxis, + ApexYAxis, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +export interface employeeChart { + series: ApexAxisChartSeries; + chart: ApexChart; + dataLabels: ApexDataLabels; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + legend: ApexLegend; + grid: ApexGrid; + xaxis: ApexXAxis; + yaxis: ApexYAxis; +} + +@Component({ + selector: 'app-employee-salary', + imports: [NgApexchartsModule, MaterialModule, TablerIconsModule], + templateUrl: './employee-salary.component.html', +}) +export class AppEmployeeSalaryComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public employeeChart!: Partial | any; + + constructor() { + this.employeeChart = { + series: [ + { + name: '', + data: [20, 15, 30, 25, 10, 15], + }, + ], + + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 270, + }, + colors: [ + '#ECF2FF', + '#ECF2FF', + '#5D87FF', + '#ECF2FF', + '#ECF2FF', + '#ECF2FF', + ], + plotOptions: { + bar: { + borderRadius: 4, + columnWidth: '45%', + distributed: true, + endingShape: 'rounded', + }, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + yaxis: { + lines: { + show: false, + }, + }, + }, + xaxis: { + categories: [['Apr'], ['May'], ['June'], ['July'], ['Aug'], ['Sept']], + axisBorder: { + show: false, + }, + }, + yaxis: { + labels: { + show: false, + }, + }, + tooltip: { + theme: 'dark', + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard1/monthly-earnings/monthly-earnings.component.html b/theme/packages/main/src/app/components/dashboard1/monthly-earnings/monthly-earnings.component.html new file mode 100644 index 0000000..d9ea2e0 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/monthly-earnings/monthly-earnings.component.html @@ -0,0 +1,38 @@ + + + Monthly Earnings +
+ +
+
+ +

$6,820

+
+ +
+9%
+
last year
+
+
+ + + + + +
diff --git a/theme/packages/main/src/app/components/dashboard1/monthly-earnings/monthly-earnings.component.ts b/theme/packages/main/src/app/components/dashboard1/monthly-earnings/monthly-earnings.component.ts new file mode 100644 index 0000000..da2cbfe --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/monthly-earnings/monthly-earnings.component.ts @@ -0,0 +1,80 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexDataLabels, + ApexLegend, + ApexStroke, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexResponsive, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +export interface monthlyChart { + series: ApexAxisChartSeries; + chart: ApexChart; + dataLabels: ApexDataLabels; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + stroke: ApexStroke; + legend: ApexLegend; + responsive: ApexResponsive; +} + +@Component({ + selector: 'app-monthly-earnings', + imports: [NgApexchartsModule, MaterialModule, TablerIconsModule], + templateUrl: './monthly-earnings.component.html', +}) +export class AppMonthlyEarningsComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public monthlyChart!: Partial | any; + + constructor() { + this.monthlyChart = { + series: [ + { + name: '', + color: '#49BEFF', + data: [25, 66, 20, 40, 12, 58, 20], + }, + ], + + chart: { + type: 'area', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 60, + sparkline: { + enabled: true, + }, + group: 'sparklines', + }, + stroke: { + curve: 'smooth', + width: 2, + }, + fill: { + colors: ['#E8F7FF'], + type: 'solid', + opacity: 0.05, + }, + markers: { + size: 0, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard1/projects/projects.component.html b/theme/packages/main/src/app/components/dashboard1/projects/projects.component.html new file mode 100644 index 0000000..879b826 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/projects/projects.component.html @@ -0,0 +1,31 @@ + + + Projects +
78,298
+ +
+ +
+9%
+
+ + + + + +
+
diff --git a/theme/packages/main/src/app/components/dashboard1/projects/projects.component.ts b/theme/packages/main/src/app/components/dashboard1/projects/projects.component.ts new file mode 100644 index 0000000..9b7538a --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/projects/projects.component.ts @@ -0,0 +1,109 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexStroke, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexGrid, + ApexXAxis, + ApexYAxis, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +export interface projectsChart { + series: ApexAxisChartSeries; + chart: ApexChart; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + stroke: ApexStroke; + grid: ApexGrid; + xaxis: ApexXAxis; + yaxis: ApexYAxis; +} + +@Component({ + selector: 'app-projects', + imports: [NgApexchartsModule, MaterialModule, TablerIconsModule], + templateUrl: './projects.component.html', +}) +export class AppProjectsComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public projectsChart!: Partial | any; + + constructor() { + this.projectsChart = { + series: [ + { + name: '', + data: [4, 10, 9, 7, 9, 10, 11, 8, 10], + }, + ], + + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 80, + resize: true, + barColor: '#fff', + sparkline: { + enabled: true, + }, + }, + colors: ['#5D87FF'], + grid: { + show: false, + }, + plotOptions: { + bar: { + horizontal: false, + startingShape: 'flat', + endingShape: 'flat', + columnWidth: '60%', + barHeight: '20%', + borderRadius: 3, + }, + }, + stroke: { + show: true, + width: 2.5, + colors: ['rgba(0,0,0,0.01)'], + }, + xaxis: { + axisBorder: { + show: false, + }, + axisTicks: { + show: false, + }, + labels: { + show: false, + }, + }, + yaxis: { + labels: { + show: false, + }, + }, + axisBorder: { + show: false, + }, + fill: { + opacity: 1, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard1/revenue-updates/revenue-updates.component.html b/theme/packages/main/src/app/components/dashboard1/revenue-updates/revenue-updates.component.html new file mode 100644 index 0000000..efbfad8 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/revenue-updates/revenue-updates.component.html @@ -0,0 +1,80 @@ + + +
+
+ Revenue Updates + Overview of Profit +
+
+ + + @for(month of months; track month.viewValue ) { + + {{ month.viewValue }} + + } + + +
+
+
+ +
+
+ + + + +
+
+
+ + + + +
+
$63,489.50
+ Total Earnings +
+
+ +
+ +
+ Earnings this month +

$48,820

+
+
+ +
+ +
+ Expense this month +

$26,498

+
+
+ + +
+
+
+
diff --git a/theme/packages/main/src/app/components/dashboard1/revenue-updates/revenue-updates.component.ts b/theme/packages/main/src/app/components/dashboard1/revenue-updates/revenue-updates.component.ts new file mode 100644 index 0000000..7199493 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/revenue-updates/revenue-updates.component.ts @@ -0,0 +1,136 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexDataLabels, + ApexLegend, + ApexStroke, + ApexTooltip, + ApexAxisChartSeries, + ApexXAxis, + ApexYAxis, + ApexGrid, + ApexPlotOptions, + ApexFill, + ApexMarkers, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +interface month { + value: string; + viewValue: string; +} + +export interface revenueChart { + series: ApexAxisChartSeries; + chart: ApexChart; + dataLabels: ApexDataLabels; + plotOptions: ApexPlotOptions; + yaxis: ApexYAxis; + xaxis: ApexXAxis; + fill: ApexFill; + tooltip: ApexTooltip; + stroke: ApexStroke; + legend: ApexLegend; + grid: ApexGrid; + marker: ApexMarkers; +} + +@Component({ + selector: 'app-revenue-updates', + imports: [NgApexchartsModule, MaterialModule, TablerIconsModule], + templateUrl: './revenue-updates.component.html', +}) +export class AppRevenueUpdatesComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + + public revenueChart!: Partial | any; + + months: month[] = [ + { value: 'mar', viewValue: 'March 2025' }, + { value: 'apr', viewValue: 'April 2025' }, + { value: 'june', viewValue: 'June 2025' }, + ]; + + constructor() { + this.revenueChart = { + series: [ + { + name: 'Eanings this month', + data: [1.5, 2.7, 2.2, 3.6, 1.5, 1.0], + color: '#5D87FF', + }, + { + name: 'Expense this month', + data: [-1.8, -1.1, -2.5, -1.5, -0.6, -1.8], + color: '#49BEFF', + }, + ], + + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 340, + stacked: true, + }, + + plotOptions: { + bar: { + horizontal: false, + columnWidth: '20%', + borderRadius: [6], + borderRadiusApplication: 'end', + borderRadiusWhenStacked: 'all', + }, + }, + + stroke: { + show: false, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + borderColor: 'rgba(0,0,0,0.1)', + strokeDashArray: 3, + xaxis: { + lines: { + show: false, + }, + }, + }, + yaxis: { + min: -5, + max: 5, + tickAmount: 4, + }, + xaxis: { + categories: [ + '16/08', + '17/08', + '18/08', + '19/08', + '20/08', + '21/08', + '22/08', + ], + axisBorder: { + show: false, + }, + }, + tooltip: { + theme: 'dark', + fillSeriesColor: false, + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard1/selling-product/selling-product.component.html b/theme/packages/main/src/app/components/dashboard1/selling-product/selling-product.component.html new file mode 100644 index 0000000..d9743bb --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/selling-product/selling-product.component.html @@ -0,0 +1,50 @@ + + + Best selling products + Overview 2025 +
+ image +
+
+ + +
+
+
MaterialPro
+ $23,568 +
+ + 55% + +
+ +
+
+
Flexy Admin
+ $23,568 +
+ + 20% + +
+ +
+
+
diff --git a/theme/packages/main/src/app/components/dashboard1/selling-product/selling-product.component.ts b/theme/packages/main/src/app/components/dashboard1/selling-product/selling-product.component.ts new file mode 100644 index 0000000..9825bfc --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/selling-product/selling-product.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; + +@Component({ + selector: 'app-selling-product', + imports: [MaterialModule], + templateUrl: './selling-product.component.html', +}) +export class AppSellingProductComponent {} diff --git a/theme/packages/main/src/app/components/dashboard1/social-card/social-card.component.html b/theme/packages/main/src/app/components/dashboard1/social-card/social-card.component.html new file mode 100644 index 0000000..a8a1753 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/social-card/social-card.component.html @@ -0,0 +1,54 @@ + + +
+ social +
+ Super awesome, Vue coming soon! + 22 March, 2025 +
+
+
+ + +
+
+
diff --git a/theme/packages/main/src/app/components/dashboard1/social-card/social-card.component.ts b/theme/packages/main/src/app/components/dashboard1/social-card/social-card.component.ts new file mode 100644 index 0000000..69855e7 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/social-card/social-card.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-social-card', + imports: [MaterialModule, TablerIconsModule], + templateUrl: './social-card.component.html', +}) +export class AppSocialCardComponent {} diff --git a/theme/packages/main/src/app/components/dashboard1/top-cards/top-cards.component.html b/theme/packages/main/src/app/components/dashboard1/top-cards/top-cards.component.html new file mode 100644 index 0000000..f80c51b --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/top-cards/top-cards.component.html @@ -0,0 +1,22 @@ +
+ @for(topcard of topcards; track topcard.title) { +
+ + + users +

+ {{ topcard.title }} +

+
+ {{ topcard.subtitle }} +
+
+
+
+ } +
diff --git a/theme/packages/main/src/app/components/dashboard1/top-cards/top-cards.component.ts b/theme/packages/main/src/app/components/dashboard1/top-cards/top-cards.component.ts new file mode 100644 index 0000000..51c4fe1 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/top-cards/top-cards.component.ts @@ -0,0 +1,62 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; + +interface topcards { + id: number; + img: string; + color: string; + title: string; + subtitle: string; +} + +@Component({ + selector: 'app-top-cards', + imports: [MaterialModule], + templateUrl: './top-cards.component.html', +}) +export class AppTopCardsComponent { + topcards: topcards[] = [ + { + id: 1, + color: 'primary', + img: '/assets/images/svgs/icon-user-male.svg', + title: 'Employees', + subtitle: '96', + }, + { + id: 2, + color: 'warning', + img: '/assets/images/svgs/icon-briefcase.svg', + title: 'Clients', + subtitle: '3,650', + }, + { + id: 3, + color: 'secondary', + img: '/assets/images/svgs/icon-mailbox.svg', + title: 'Projects', + subtitle: '356', + }, + { + id: 4, + color: 'error', + img: '/assets/images/svgs/icon-favorites.svg', + title: 'Events', + subtitle: '696', + }, + { + id: 5, + color: 'success', + img: '/assets/images/svgs/icon-speech-bubble.svg', + title: 'Payroll', + subtitle: '$96k', + }, + { + id: 6, + color: 'secondary', + img: '/assets/images/svgs/icon-connect.svg', + title: 'Reports', + subtitle: '59', + }, + ]; +} diff --git a/theme/packages/main/src/app/components/dashboard1/top-projects/top-projects.component.html b/theme/packages/main/src/app/components/dashboard1/top-projects/top-projects.component.html new file mode 100644 index 0000000..3c364a3 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/top-projects/top-projects.component.html @@ -0,0 +1,109 @@ + + +
+ Top Projects + Best Products +
+ + + @for(month of months; track month.viewValue) { + + {{ month.viewValue }} + + } + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
Name + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + + } @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + Budget + + ${{ element.budget }}k +
+
+
+
diff --git a/theme/packages/main/src/app/components/dashboard1/top-projects/top-projects.component.ts b/theme/packages/main/src/app/components/dashboard1/top-projects/top-projects.component.ts new file mode 100644 index 0000000..90c9033 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/top-projects/top-projects.component.ts @@ -0,0 +1,73 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { CommonModule } from '@angular/common'; + +export interface productsData { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; +} + +const ELEMENT_DATA: productsData[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, +]; + +interface month { + value: string; + viewValue: string; +} + +@Component({ + selector: 'app-top-projects', + imports: [MaterialModule, CommonModule], + templateUrl: './top-projects.component.html', +}) +export class AppTopProjectsComponent { + displayedColumns: string[] = ['assigned', 'name', 'priority', 'budget']; + dataSource = ELEMENT_DATA; + + months: month[] = [ + { value: 'mar', viewValue: 'March 2025' }, + { value: 'apr', viewValue: 'April 2025' }, + { value: 'june', viewValue: 'June 2025' }, + ]; +} diff --git a/theme/packages/main/src/app/components/dashboard1/weekly-stats/weekly-stats.component.html b/theme/packages/main/src/app/components/dashboard1/weekly-stats/weekly-stats.component.html new file mode 100644 index 0000000..d8860dd --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/weekly-stats/weekly-stats.component.html @@ -0,0 +1,44 @@ + + + Weekly Stats + Average sales + + + + + + + @for(stat of stats; track stat.color) { +
+
+ + + + +
+
{{ stat.title }}
+ {{ stat.subtitle }} +
+ + +{{ stat.percent }} + +
+
+ } +
+
diff --git a/theme/packages/main/src/app/components/dashboard1/weekly-stats/weekly-stats.component.ts b/theme/packages/main/src/app/components/dashboard1/weekly-stats/weekly-stats.component.ts new file mode 100644 index 0000000..dfbe683 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/weekly-stats/weekly-stats.component.ts @@ -0,0 +1,110 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexFill, + ApexStroke, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +export interface weeklyCart { + series: ApexAxisChartSeries; + chart: ApexChart; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + fill: ApexFill; + stroke: ApexStroke; +} + +interface stats { + id: number; + color: string; + title: string; + subtitle: string; + percent: string; +} + +@Component({ + selector: 'app-weekly-stats', + imports: [NgApexchartsModule, MaterialModule, TablerIconsModule], + templateUrl: './weekly-stats.component.html', +}) +export class AppWeeklyStatsComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public weeklyCart!: Partial | any; + + constructor() { + this.weeklyCart = { + series: [ + { + name: 'Weekly Stats', + color: '#5D87FF', + data: [5, 15, 5, 10, 5], + }, + ], + + chart: { + type: 'area', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 130, + sparkline: { + enabled: true, + }, + group: 'sparklines', + }, + stroke: { + curve: 'smooth', + width: 2, + }, + fill: { + type: 'gradient', + gradient: { + shadeIntensity: 0, + inverseColors: false, + opacityFrom: 0.45, + opacityTo: 0, + stops: [20, 180], + }, + }, + markers: { + size: 0, + }, + tooltip: { + theme: 'dark', + }, + }; + } + + stats: stats[] = [ + { + id: 1, + color: 'primary', + title: 'Top Sales', + subtitle: 'Johnathan Doe', + percent: '68', + }, + { + id: 2, + color: 'success', + title: 'Best Seller', + subtitle: 'Footware', + percent: '45', + }, + { + id: 3, + color: 'error', + title: 'Most Commented', + subtitle: 'Fashionware', + percent: '14', + }, + ]; +} diff --git a/theme/packages/main/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html b/theme/packages/main/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html new file mode 100644 index 0000000..fa78891 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html @@ -0,0 +1,55 @@ + + + Yearly Breakup + + +
+
+

$36,358

+
+ +
+9%
+
last year
+
+ +
+
+ +
2025
+
+
+ +
2024
+
+
+
+
+ + + + +
+
+
+
diff --git a/theme/packages/main/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.ts b/theme/packages/main/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.ts new file mode 100644 index 0000000..1fcbf74 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.ts @@ -0,0 +1,85 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexDataLabels, + ApexLegend, + ApexStroke, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexResponsive, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +export interface yearlyChart { + series: ApexAxisChartSeries; + chart: ApexChart; + dataLabels: ApexDataLabels; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + stroke: ApexStroke; + legend: ApexLegend; + responsive: ApexResponsive; +} + +@Component({ + selector: 'app-yearly-breakup', + imports: [MaterialModule, NgApexchartsModule, TablerIconsModule], + templateUrl: './yearly-breakup.component.html', +}) +export class AppYearlyBreakupComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public yearlyChart!: Partial | any; + + constructor() { + this.yearlyChart = { + series: [38, 40, 25], + + chart: { + type: 'donut', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 130, + }, + colors: ['#5D87FF', '#ECF2FF', '#F9F9FD'], + plotOptions: { + pie: { + startAngle: 0, + endAngle: 360, + donut: { + size: '75%', + background: 'transparent', + }, + }, + }, + stroke: { + show: false, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + responsive: [ + { + breakpoint: 991, + options: { + chart: { + width: 120, + }, + }, + }, + ], + tooltip: { + enabled: false, + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard2/monthly-earnings/monthly-earnings.component.html b/theme/packages/main/src/app/components/dashboard2/monthly-earnings/monthly-earnings.component.html new file mode 100644 index 0000000..c0d8fee --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/monthly-earnings/monthly-earnings.component.html @@ -0,0 +1,41 @@ + + + Monthly Earnings +
+ + icon + +
+
+ +
+

$6,820

+
+ +
+9%
+
+
+
+ + + + + +
diff --git a/theme/packages/main/src/app/components/dashboard2/monthly-earnings/monthly-earnings.component.ts b/theme/packages/main/src/app/components/dashboard2/monthly-earnings/monthly-earnings.component.ts new file mode 100644 index 0000000..d4ed6a7 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/monthly-earnings/monthly-earnings.component.ts @@ -0,0 +1,79 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexDataLabels, + ApexLegend, + ApexStroke, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexResponsive, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +export interface monthlytwoChart { + series: ApexAxisChartSeries; + chart: ApexChart; + dataLabels: ApexDataLabels; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + stroke: ApexStroke; + legend: ApexLegend; + responsive: ApexResponsive; +} + +@Component({ + selector: 'app-monthly-earnings-two', + imports: [NgApexchartsModule, MaterialModule, TablerIconsModule], + templateUrl: './monthly-earnings.component.html', +}) +export class AppMonthlyEarningsTwoComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public monthlytwoChart!: Partial | any; + + constructor() { + this.monthlytwoChart = { + series: [ + { + name: '', + color: '#5D87FF', + data: [25, 66, 20, 40, 12, 58, 20], + }, + ], + + chart: { + type: 'area', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 80, + sparkline: { + enabled: true, + }, + group: 'sparklines', + }, + stroke: { + curve: 'smooth', + width: 2, + }, + fill: { + colors: ['#E8F7FF'], + type: 'solid', + }, + markers: { + size: 0, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard2/payment-gateways/payment-gateways.component.html b/theme/packages/main/src/app/components/dashboard2/payment-gateways/payment-gateways.component.html new file mode 100644 index 0000000..b29cf52 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/payment-gateways/payment-gateways.component.html @@ -0,0 +1,32 @@ + + + Payment Gateways + Platform For Income + + @for(stat of stats; track stat.color) { +
+
+ + icon + + +
+
{{ stat.title }}
+ {{ stat.subtitle }} +
+ +${{ stat.percent }} +
+
+ } + + +
+
diff --git a/theme/packages/main/src/app/components/dashboard2/payment-gateways/payment-gateways.component.ts b/theme/packages/main/src/app/components/dashboard2/payment-gateways/payment-gateways.component.ts new file mode 100644 index 0000000..aa13f3f --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/payment-gateways/payment-gateways.component.ts @@ -0,0 +1,53 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; + +interface stats { + id: number; + color: string; + title: string; + subtitle: string; + img: string; + percent: string; +} + +@Component({ + selector: 'app-payment-gateways', + imports: [MaterialModule], + templateUrl: './payment-gateways.component.html', +}) +export class AppPaymentGatewaysComponent { + stats: stats[] = [ + { + id: 1, + color: 'primary', + title: 'Paypal', + subtitle: 'Big Brands', + img: 'assets/images/svgs/icon-paypal.svg', + percent: '6235', + }, + { + id: 2, + color: 'success', + title: 'Wallet', + subtitle: 'Bill payment', + img: 'assets/images/svgs/icon-office-bag.svg', + percent: '345', + }, + { + id: 3, + color: 'warning', + title: 'Credit Card', + subtitle: 'Money reversed', + img: 'assets/images/svgs/icon-master-card.svg', + percent: '2235', + }, + { + id: 4, + color: 'error', + title: 'Refund', + subtitle: 'Bill Payment', + img: 'assets/images/svgs/icon-pie.svg', + percent: '32', + }, + ]; +} diff --git a/theme/packages/main/src/app/components/dashboard2/payments/payments.component.html b/theme/packages/main/src/app/components/dashboard2/payments/payments.component.html new file mode 100644 index 0000000..e77626a --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/payments/payments.component.html @@ -0,0 +1,24 @@ + + + + paypal + + + Payments +
$678,298
+ +
+ +
+9%
+
+
+
diff --git a/theme/packages/main/src/app/components/dashboard2/payments/payments.component.ts b/theme/packages/main/src/app/components/dashboard2/payments/payments.component.ts new file mode 100644 index 0000000..fb919a5 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/payments/payments.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-payments', + imports: [MaterialModule, TablerIconsModule], + templateUrl: './payments.component.html', +}) +export class AppPaymentsComponent {} diff --git a/theme/packages/main/src/app/components/dashboard2/products/products.component.html b/theme/packages/main/src/app/components/dashboard2/products/products.component.html new file mode 100644 index 0000000..d3f0243 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/products/products.component.html @@ -0,0 +1,18 @@ + + + Projects +
78,298
+
+ + + + +
diff --git a/theme/packages/main/src/app/components/dashboard2/products/products.component.ts b/theme/packages/main/src/app/components/dashboard2/products/products.component.ts new file mode 100644 index 0000000..4fcf57a --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/products/products.component.ts @@ -0,0 +1,77 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexStroke, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexFill, + ApexMarkers, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; + +export interface productChart { + series: ApexAxisChartSeries; + chart: ApexChart; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + stroke: ApexStroke; + fill: ApexFill; + markers: ApexMarkers; +} + +@Component({ + selector: 'app-products', + imports: [NgApexchartsModule, MaterialModule], + templateUrl: './products.component.html', +}) +export class AppProductsComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public productChart!: Partial | any; + + constructor() { + this.productChart = { + series: [ + { + name: '', + color: '#13DEB9', + data: [30, 25, 35, 20, 30, 40], + }, + ], + + chart: { + type: 'area', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 85, + sparkline: { + enabled: true, + }, + group: 'sparklines', + }, + stroke: { + curve: 'smooth', + width: 2, + }, + fill: { + colors: ['#E6FFFA'], + type: 'solid', + opacity: 0.05, + }, + markers: { + size: 0, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard2/recent-transactions/recent-transactions.component.html b/theme/packages/main/src/app/components/dashboard2/recent-transactions/recent-transactions.component.html new file mode 100644 index 0000000..1cc3eb3 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/recent-transactions/recent-transactions.component.html @@ -0,0 +1,28 @@ + + + Recent Transactions + +
+ @for(stat of stats; track stat.title) { +
+
{{ stat.time }}
+
+ + +
+
+ @if(stat.subtext) { + {{ stat.subtext }} + } @if(stat.title) { + {{ stat.title }} + } @if(stat.link) { + #ML-3467 + } +
+
+ } +
+
+
diff --git a/theme/packages/main/src/app/components/dashboard2/recent-transactions/recent-transactions.component.ts b/theme/packages/main/src/app/components/dashboard2/recent-transactions/recent-transactions.component.ts new file mode 100644 index 0000000..3003621 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/recent-transactions/recent-transactions.component.ts @@ -0,0 +1,61 @@ +import { Component } from '@angular/core'; +import { NgApexchartsModule } from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; + +interface stats { + id: number; + time: string; + color: string; + title?: string; + subtext?: string; + link?: string; +} + +@Component({ + selector: 'app-recent-transactions', + imports: [NgApexchartsModule, MaterialModule], + templateUrl: './recent-transactions.component.html', +}) +export class AppRecentTransactionsComponent { + stats: stats[] = [ + { + id: 1, + time: '09.30 am', + color: 'primary', + subtext: 'Payment received from John Doe of $385.90', + }, + { + id: 2, + time: '10.30 am', + color: 'accent', + title: 'New sale recorded', + link: '#ML-3467', + }, + { + id: 3, + time: '12.30 pm', + color: 'success', + subtext: 'Payment was made of $64.95 to Michael', + }, + { + id: 4, + time: '12.30 pm', + color: 'warning', + title: 'New sale recorded', + link: '#ML-3467', + }, + { + id: 5, + time: '12.30 pm', + color: 'error', + title: 'New arrival recorded', + link: '#ML-3467', + }, + { + id: 6, + time: '12.30 pm', + color: 'success', + subtext: 'Payment Done', + }, + ]; +} diff --git a/theme/packages/main/src/app/components/dashboard2/revenue-updates/revenue-updates.component.html b/theme/packages/main/src/app/components/dashboard2/revenue-updates/revenue-updates.component.html new file mode 100644 index 0000000..c957113 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/revenue-updates/revenue-updates.component.html @@ -0,0 +1,46 @@ + + + Revenue Updates + Overview of Profit + + +
+
+ +
+ Footware +
+
+
+ +
+ Fashionware +
+
+
+ + + + + +
+
diff --git a/theme/packages/main/src/app/components/dashboard2/revenue-updates/revenue-updates.component.ts b/theme/packages/main/src/app/components/dashboard2/revenue-updates/revenue-updates.component.ts new file mode 100644 index 0000000..ed96569 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/revenue-updates/revenue-updates.component.ts @@ -0,0 +1,108 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexDataLabels, + ApexLegend, + ApexStroke, + ApexTooltip, + ApexAxisChartSeries, + ApexXAxis, + ApexYAxis, + ApexGrid, + ApexPlotOptions, + ApexFill, + ApexMarkers, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +export interface revenuetwoChart { + series: ApexAxisChartSeries; + chart: ApexChart; + dataLabels: ApexDataLabels; + plotOptions: ApexPlotOptions; + yaxis: ApexYAxis; + xaxis: ApexXAxis; + fill: ApexFill; + tooltip: ApexTooltip; + stroke: ApexStroke; + legend: ApexLegend; + grid: ApexGrid; + marker: ApexMarkers; +} + +@Component({ + selector: 'app-revenue-updates-two', + imports: [MaterialModule, NgApexchartsModule, TablerIconsModule], + templateUrl: './revenue-updates.component.html', +}) +export class AppRevenueUpdatesTwoComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public revenuetwoChart!: Partial | any; + + constructor() { + this.revenuetwoChart = { + series: [ + { + name: 'Footware', + data: [2.5, 3.7, 3.2, 2.6, 1.9], + color: '#5D87FF', + }, + { + name: 'Fashionware', + data: [-2.8, -1.1, -3.0, -1.5, -1.9], + color: '#49BEFF', + }, + ], + + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 320, + offsetX: -20, + stacked: true, + }, + + plotOptions: { + bar: { + horizontal: false, + columnWidth: '20%', + borderRadius: [6], + borderRadiusApplication: 'end', + borderRadiusWhenStacked: 'all', + }, + }, + + stroke: { + show: false, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + show: false, + }, + yaxis: { + min: -5, + max: 5, + tickAmount: 4, + }, + xaxis: { + categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May'], + }, + tooltip: { + theme: 'dark', + fillSeriesColor: false, + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard2/sales-overview/sales-overview.component.html b/theme/packages/main/src/app/components/dashboard2/sales-overview/sales-overview.component.html new file mode 100644 index 0000000..05b4aee --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/sales-overview/sales-overview.component.html @@ -0,0 +1,49 @@ + + + Sales Overview + Every month + + + + + + + +
+
+ + + + +
+
$23,450
+ Profit +
+
+
+ + + + +
+
$23,450
+ Expance +
+
+
+
+
diff --git a/theme/packages/main/src/app/components/dashboard2/sales-overview/sales-overview.component.ts b/theme/packages/main/src/app/components/dashboard2/sales-overview/sales-overview.component.ts new file mode 100644 index 0000000..4b86982 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/sales-overview/sales-overview.component.ts @@ -0,0 +1,90 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexDataLabels, + ApexLegend, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexStroke, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +export interface salesoverviewChart { + series: ApexAxisChartSeries; + chart: ApexChart; + dataLabels: ApexDataLabels; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + legend: ApexLegend; + stroke: ApexStroke; +} +@Component({ + selector: 'app-sales-overview', + imports: [MaterialModule, NgApexchartsModule, TablerIconsModule], + templateUrl: './sales-overview.component.html', +}) +export class AppSalesOverviewComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public salesoverviewChart!: Partial | any; + + constructor() { + this.salesoverviewChart = { + series: [55, 55, 55], + + chart: { + type: 'donut', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + + toolbar: { + show: false, + }, + height: 275, + }, + labels: ['Profit', 'Revenue', 'Expance'], + colors: ['#5D87FF', '#ECF2FF', '#49BEFF'], + plotOptions: { + pie: { + donut: { + size: '89%', + background: 'transparent', + + labels: { + show: true, + name: { + show: true, + offsetY: 7, + }, + value: { + show: false, + }, + total: { + show: true, + color: '#2A3547', + fontSize: '20px', + fontWeight: '600', + label: '$500,458', + }, + }, + }, + }, + }, + dataLabels: { + enabled: false, + }, + stroke: { + show: false, + }, + legend: { + show: false, + }, + tooltip: { + theme: 'dark', + fillSeriesColor: false, + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard2/sales-profit/sales-profit.component.html b/theme/packages/main/src/app/components/dashboard2/sales-profit/sales-profit.component.html new file mode 100644 index 0000000..3a1db90 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/sales-profit/sales-profit.component.html @@ -0,0 +1,24 @@ + + + + paypal + + + Sales Profit +
$456,120
+ +
+ +
+9%
+
+
+
diff --git a/theme/packages/main/src/app/components/dashboard2/sales-profit/sales-profit.component.ts b/theme/packages/main/src/app/components/dashboard2/sales-profit/sales-profit.component.ts new file mode 100644 index 0000000..ab4091c --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/sales-profit/sales-profit.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-sales-profit', + imports: [MaterialModule, TablerIconsModule], + templateUrl: './sales-profit.component.html', +}) +export class AppSalesProfitComponent {} diff --git a/theme/packages/main/src/app/components/dashboard2/top-projects/top-projects.component.html b/theme/packages/main/src/app/components/dashboard2/top-projects/top-projects.component.html new file mode 100644 index 0000000..9901883 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/top-projects/top-projects.component.html @@ -0,0 +1,104 @@ + + +
+ Top Projects + Best Products +
+ + + @for(month of months; track month.value) { + + {{ month.viewValue }} + + } + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Product + +
+ users +
+
+ {{ element.pname }} +
+ + {{ element.category }} + +
+
+
+ Progress + + {{ element.progress }}% + + Status + + @if(element.status == 'low') { + + {{ element.status | titlecase }} + + } @if(element.status == 'medium') { + + {{ element.status | titlecase }} + + } @if(element.status == 'high') { + + {{ element.status | titlecase }} + + } @if(element.status == 'critical') { + + {{ element.status | titlecase }} + + } + + Sales + + ${{ element.sales }}k +
+
+
+
diff --git a/theme/packages/main/src/app/components/dashboard2/top-projects/top-projects.component.ts b/theme/packages/main/src/app/components/dashboard2/top-projects/top-projects.component.ts new file mode 100644 index 0000000..46faf10 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/top-projects/top-projects.component.ts @@ -0,0 +1,80 @@ +import { Component } from '@angular/core'; +import { NgApexchartsModule } from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { CommonModule } from '@angular/common'; + +export interface performanceData { + id: number; + imagePath: string; + pname: string; + category: string; + progress: number; + sales: number; + status: string; +} + +const ELEMENT_DATA: performanceData[] = [ + { + id: 1, + imagePath: 'assets/images/products/s6.jpg', + pname: 'Gaming Console', + category: 'Electronics', + progress: 78.5, + sales: 3.9, + status: 'low', + }, + { + id: 2, + imagePath: 'assets/images/products/s9.jpg', + pname: 'Leather Purse', + category: 'Fashion', + progress: 58.6, + sales: 3.5, + status: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/products/s7.jpg', + pname: 'Red Velvate Dress', + category: 'Womens Fashion', + progress: 25, + sales: 3.8, + status: 'high', + }, + { + id: 4, + imagePath: 'assets/images/products/s4.jpg', + pname: 'Headphone Boat', + category: 'Electronics', + progress: 96.3, + sales: 3.54, + status: 'critical', + }, +]; + +interface month { + value: string; + viewValue: string; +} + +@Component({ + selector: 'app-top-projects', + imports: [ + NgApexchartsModule, + MaterialModule, + TablerIconsModule, + CommonModule, + ], + templateUrl: './top-projects.component.html', +}) +export class AppTopProjectsComponent { + displayedColumns: string[] = ['product', 'progress', 'status', 'sales']; + dataSource = ELEMENT_DATA; + + months: month[] = [ + { value: 'mar', viewValue: 'March 2025' }, + { value: 'apr', viewValue: 'April 2025' }, + { value: 'june', viewValue: 'June 2025' }, + ]; +} diff --git a/theme/packages/main/src/app/components/dashboard2/total-earnings/total-earnings.component.html b/theme/packages/main/src/app/components/dashboard2/total-earnings/total-earnings.component.html new file mode 100644 index 0000000..41840fe --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/total-earnings/total-earnings.component.html @@ -0,0 +1,22 @@ + + + Total Earning +
$78,298
+ + + + + +
+
diff --git a/theme/packages/main/src/app/components/dashboard2/total-earnings/total-earnings.component.ts b/theme/packages/main/src/app/components/dashboard2/total-earnings/total-earnings.component.ts new file mode 100644 index 0000000..c158281 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/total-earnings/total-earnings.component.ts @@ -0,0 +1,115 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexStroke, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexFill, + ApexGrid, + ApexDataLabels, + ApexXAxis, + ApexYAxis, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; + +export interface totalEarnChart { + series: ApexAxisChartSeries; + chart: ApexChart; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + stroke: ApexStroke; + fill: ApexFill; + grid: ApexGrid; + dataLabels: ApexDataLabels; + xaxis: ApexXAxis; + yaxis: ApexYAxis; +} + +@Component({ + selector: 'app-total-earnings', + imports: [NgApexchartsModule, MaterialModule], + templateUrl: './total-earnings.component.html', +}) +export class AppTotalEarningsComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public totalEarnChart!: Partial | any; + + constructor() { + this.totalEarnChart = { + series: [ + { + name: '', + data: [4, 10, 9, 7, 9, 10, 11, 8, 10], + }, + ], + + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 65, + resize: true, + barColor: '#fff', + sparkline: { + enabled: true, + }, + }, + colors: ['#49BEFF'], + grid: { + show: false, + }, + plotOptions: { + bar: { + horizontal: false, + startingShape: 'flat', + endingShape: 'flat', + columnWidth: '60%', + barHeight: '20%', + borderRadius: 3, + }, + }, + dataLabels: { + enabled: false, + }, + stroke: { + show: true, + width: 2.5, + colors: ['rgba(0,0,0,0.01)'], + }, + xaxis: { + axisBorder: { + show: false, + }, + axisTicks: { + show: false, + }, + labels: { + show: false, + }, + }, + yaxis: { + labels: { + show: false, + }, + }, + axisBorder: { + show: false, + }, + fill: { + opacity: 1, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + } +} diff --git a/theme/packages/main/src/app/components/dashboard2/welcome-card/welcome-card.component.html b/theme/packages/main/src/app/components/dashboard2/welcome-card/welcome-card.component.html new file mode 100644 index 0000000..ec527f6 --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/welcome-card/welcome-card.component.html @@ -0,0 +1,22 @@ + + +
+
+ Welcome back Mathew! + You have earned 54% more than last month which is great + thing. + +
+
+ welcome +
+
+
+
diff --git a/theme/packages/main/src/app/components/dashboard2/welcome-card/welcome-card.component.ts b/theme/packages/main/src/app/components/dashboard2/welcome-card/welcome-card.component.ts new file mode 100644 index 0000000..c5fe5ac --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/welcome-card/welcome-card.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; + +@Component({ + selector: 'app-welcome-card', + imports: [MaterialModule], + templateUrl: './welcome-card.component.html', +}) +export class AppWelcomeCardComponent {} diff --git a/theme/packages/main/src/app/components/dashboard2/yearly-sales/yearly-sales.component.html b/theme/packages/main/src/app/components/dashboard2/yearly-sales/yearly-sales.component.html new file mode 100644 index 0000000..182666d --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/yearly-sales/yearly-sales.component.html @@ -0,0 +1,50 @@ + + + Yearly Sales + Every month + + + + + + + +
+
+ + + + +
+ Salary +
$36,358
+
+
+
+ + + + +
+ Expance +
$5,296
+
+
+
+
+
diff --git a/theme/packages/main/src/app/components/dashboard2/yearly-sales/yearly-sales.component.ts b/theme/packages/main/src/app/components/dashboard2/yearly-sales/yearly-sales.component.ts new file mode 100644 index 0000000..a5db16e --- /dev/null +++ b/theme/packages/main/src/app/components/dashboard2/yearly-sales/yearly-sales.component.ts @@ -0,0 +1,102 @@ +import { Component, ViewChild } from '@angular/core'; +import { + ApexChart, + ChartComponent, + ApexDataLabels, + ApexLegend, + ApexTooltip, + ApexAxisChartSeries, + ApexPlotOptions, + ApexGrid, + ApexXAxis, + ApexYAxis, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +export interface yearlysaleChart { + series: ApexAxisChartSeries; + chart: ApexChart; + dataLabels: ApexDataLabels; + plotOptions: ApexPlotOptions; + tooltip: ApexTooltip; + legend: ApexLegend; + grid: ApexGrid; + xaxis: ApexXAxis; + yaxis: ApexYAxis; +} + +@Component({ + selector: 'app-yearly-sales', + imports: [NgApexchartsModule, MaterialModule, TablerIconsModule], + templateUrl: './yearly-sales.component.html', +}) +export class AppYearlySalesComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public yearlysaleChart!: Partial | any; + + constructor() { + this.yearlysaleChart = { + series: [ + { + name: '', + data: [20, 15, 30, 25, 10, 15], + }, + ], + + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 280, + }, + colors: [ + '#ECF2FF', + '#ECF2FF', + '#5D87FF', + '#ECF2FF', + '#ECF2FF', + '#ECF2FF', + ], + plotOptions: { + bar: { + borderRadius: 4, + columnWidth: '45%', + distributed: true, + endingShape: 'rounded', + }, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + yaxis: { + lines: { + show: false, + }, + }, + }, + xaxis: { + categories: [['Apr'], ['May'], ['June'], ['July'], ['Aug'], ['Sept']], + axisBorder: { + show: false, + }, + }, + yaxis: { + labels: { + show: false, + }, + }, + tooltip: { + theme: 'dark', + }, + }; + } +} diff --git a/theme/packages/main/src/app/config.ts b/theme/packages/main/src/app/config.ts new file mode 100644 index 0000000..d1bbdbd --- /dev/null +++ b/theme/packages/main/src/app/config.ts @@ -0,0 +1,25 @@ +export interface AppSettings { + dir: 'ltr' | 'rtl'; + theme: string; + sidenavOpened: boolean; + sidenavCollapsed: boolean; + boxed: boolean; + horizontal: boolean; + activeTheme: string; + language: string; + cardBorder: boolean; + navPos: 'side' | 'top'; +} + +export const defaults: AppSettings = { + dir: 'ltr', + theme: 'light', + sidenavOpened: false, + sidenavCollapsed: false, + boxed: true, + horizontal: false, + cardBorder: false, + activeTheme: 'blue_theme', + language: 'en-us', + navPos: 'side', +}; diff --git a/theme/packages/main/src/app/icon/icon.module.ts b/theme/packages/main/src/app/icon/icon.module.ts new file mode 100644 index 0000000..6c28fd0 --- /dev/null +++ b/theme/packages/main/src/app/icon/icon.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import * as TablerIcons from 'angular-tabler-icons/icons'; + + + +@NgModule({ + declarations: [], + imports: [ + TablerIconsModule.pick(TablerIcons), + CommonModule + ], + exports: [TablerIconsModule] +}) +export class IconModule { } diff --git a/theme/packages/main/src/app/layouts/blank/blank.component.html b/theme/packages/main/src/app/layouts/blank/blank.component.html new file mode 100644 index 0000000..4dd0d8a --- /dev/null +++ b/theme/packages/main/src/app/layouts/blank/blank.component.html @@ -0,0 +1,11 @@ + + + + + + diff --git a/theme/packages/main/src/app/layouts/blank/blank.component.ts b/theme/packages/main/src/app/layouts/blank/blank.component.ts new file mode 100644 index 0000000..b9291c1 --- /dev/null +++ b/theme/packages/main/src/app/layouts/blank/blank.component.ts @@ -0,0 +1,51 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { AppSettings } from 'src/app/config'; +import { CommonModule } from '@angular/common'; +import { RouterOutlet } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-blank', + templateUrl: './blank.component.html', + styleUrls: [], + imports: [RouterOutlet, MaterialModule, CommonModule], +}) +export class BlankComponent { + private htmlElement!: HTMLHtmlElement; + + options = this.settings.getOptions(); + + constructor(private settings: CoreService) { + this.htmlElement = document.querySelector('html')!; + // Initialize project theme with options + this.receiveOptions(this.options); + } + + receiveOptions(options: AppSettings): void { + this.toggleDarkTheme(options); + this.toggleColorsTheme(options); + } + + toggleDarkTheme(options: AppSettings) { + if (options.theme === 'dark') { + this.htmlElement.classList.add('dark-theme'); + this.htmlElement.classList.remove('light-theme'); + } else { + this.htmlElement.classList.remove('dark-theme'); + this.htmlElement.classList.add('light-theme'); + } + } + + toggleColorsTheme(options: AppSettings) { + // Remove any existing theme class dynamically + this.htmlElement.classList.forEach((className) => { + if (className.endsWith('_theme')) { + this.htmlElement.classList.remove(className); + } + }); + + // Add the selected theme class + this.htmlElement.classList.add(options.activeTheme); + } +} diff --git a/theme/packages/main/src/app/layouts/full/full.component.html b/theme/packages/main/src/app/layouts/full/full.component.html new file mode 100644 index 0000000..2ffaeb5 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/full.component.html @@ -0,0 +1,197 @@ + + + + + + @if (!options.horizontal) { + +
+ + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+
+ } + + + + + @if (resView) { + + + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+ } + + + + + + + + + @if (!options.horizontal) { + + } @else { + + + } @if(options.horizontal) { + + } + +
+ + + + + +
+ +
+
+ + +
+
+
+
+ @if(options.theme === 'light') { + + logo + + } @else { + + logo + + } +
+ +
+ + + + + Apps + +
+
+ @for(appdd of apps; track appdd.img) { + + } +
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+ + +
+
+
+ + +
+

Settings

+ +
+ + + +
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/layouts/full/full.component.ts b/theme/packages/main/src/app/layouts/full/full.component.ts new file mode 100644 index 0000000..459faac --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/full.component.ts @@ -0,0 +1,284 @@ +import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout'; +import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { MatSidenav, MatSidenavContent } from '@angular/material/sidenav'; +import { CoreService } from 'src/app/services/core.service'; +import { AppSettings } from 'src/app/config'; +import { filter } from 'rxjs/operators'; +import { NavigationEnd, Router } from '@angular/router'; +import { navItems } from './vertical/sidebar/sidebar-data'; +import { NavService } from '../../services/nav.service'; +import { AppNavItemComponent } from './vertical/sidebar/nav-item/nav-item.component'; +import { RouterModule } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { SidebarComponent } from './vertical/sidebar/sidebar.component'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { HeaderComponent } from './vertical/header/header.component'; +import { AppHorizontalHeaderComponent } from './horizontal/header/header.component'; +import { AppHorizontalSidebarComponent } from './horizontal/sidebar/sidebar.component'; +import { AppBreadcrumbComponent } from './shared/breadcrumb/breadcrumb.component'; +import { CustomizerComponent } from './shared/customizer/customizer.component'; + +const MOBILE_VIEW = 'screen and (max-width: 768px)'; +const TABLET_VIEW = 'screen and (min-width: 769px) and (max-width: 1024px)'; +const MONITOR_VIEW = 'screen and (min-width: 1024px)'; +const BELOWMONITOR = 'screen and (max-width: 1023px)'; + +// for mobile app sidebar +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +@Component({ + selector: 'app-full', + imports: [ + RouterModule, + AppNavItemComponent, + MaterialModule, + CommonModule, + SidebarComponent, + NgScrollbarModule, + TablerIconsModule, + HeaderComponent, + AppHorizontalHeaderComponent, + AppHorizontalSidebarComponent, + AppBreadcrumbComponent, + CustomizerComponent, + ], + templateUrl: './full.component.html', + + encapsulation: ViewEncapsulation.None +}) +export class FullComponent implements OnInit { + navItems = navItems; + + + + @ViewChild('leftsidenav') + public sidenav: MatSidenav; + resView = false; + @ViewChild('content', { static: true }) content!: MatSidenavContent; + //get options from service + options = this.settings.getOptions(); + private layoutChangesSubscription = Subscription.EMPTY; + private isMobileScreen = false; + private isContentWidthFixed = true; + private isCollapsedWidthFixed = false; + private htmlElement!: HTMLHtmlElement; + + get isOver(): boolean { + return this.isMobileScreen; + } + + get isTablet(): boolean { + return this.resView; + } + + // for mobile app sidebar + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/apps/chat', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'Todo App', + subtitle: 'Completed task', + link: '/apps/todo', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/apps/invoice', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/apps/calendar', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/apps/contacts', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/apps/tickets', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/apps/email/inbox', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Courses', + subtitle: 'Create new course', + link: '/apps/courses', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/theme-pages/pricing', + }, + { + id: 2, + title: 'Authentication Design', + link: '/authentication/login', + }, + { + id: 3, + title: 'Register Now', + link: '/authentication/side-register', + }, + { + id: 4, + title: '404 Error Page', + link: '/authentication/error', + }, + { + id: 5, + title: 'Notes App', + link: '/apps/notes', + }, + { + id: 6, + title: 'Employee App', + link: '/apps/employee', + }, + { + id: 7, + title: 'Todo Application', + link: '/apps/todo', + }, + { + id: 8, + title: 'Treeview', + link: '/theme-pages/treeview', + }, + ]; + + constructor( + private settings: CoreService, + private mediaMatcher: MediaMatcher, + private router: Router, + private breakpointObserver: BreakpointObserver, + private navService: NavService, private cdr: ChangeDetectorRef + ) { + this.htmlElement = document.querySelector('html')!; + this.layoutChangesSubscription = this.breakpointObserver + .observe([MOBILE_VIEW, TABLET_VIEW, MONITOR_VIEW, BELOWMONITOR]) + .subscribe((state) => { + // SidenavOpened must be reset true when layout changes + this.options.sidenavOpened = true; + this.isMobileScreen = state.breakpoints[BELOWMONITOR]; + if (this.options.sidenavCollapsed == false) { + this.options.sidenavCollapsed = state.breakpoints[TABLET_VIEW]; + } + this.isContentWidthFixed = state.breakpoints[MONITOR_VIEW]; + this.resView = state.breakpoints[BELOWMONITOR]; + }); + + // Initialize project theme with options + this.receiveOptions(this.options); + + // This is for scroll to top + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .subscribe((e) => { + this.content.scrollTo({ top: 0 }); + }); + } + + isFilterNavOpen = false; + + toggleFilterNav() { + this.isFilterNavOpen = !this.isFilterNavOpen; + console.log('Sidebar open:', this.isFilterNavOpen); + this.cdr.detectChanges(); // Ensures Angular updates the view + } + + ngOnInit(): void {} + + ngOnDestroy() { + this.layoutChangesSubscription.unsubscribe(); + } + + toggleCollapsed() { + this.isContentWidthFixed = false; + this.options.sidenavCollapsed = !this.options.sidenavCollapsed; + this.resetCollapsedState(); + } + + resetCollapsedState(timer = 400) { + setTimeout(() => this.settings.setOptions(this.options), timer); + } + + onSidenavClosedStart() { + this.isContentWidthFixed = false; + } + + onSidenavOpenedChange(isOpened: boolean) { + this.isCollapsedWidthFixed = !this.isOver; + this.options.sidenavOpened = isOpened; + this.settings.setOptions(this.options); + } + + receiveOptions(options: AppSettings): void { + this.toggleDarkTheme(options); + this.toggleColorsTheme(options); + } + + toggleDarkTheme(options: AppSettings) { + if (options.theme === 'dark') { + this.htmlElement.classList.add('dark-theme'); + this.htmlElement.classList.remove('light-theme'); + } else { + this.htmlElement.classList.remove('dark-theme'); + this.htmlElement.classList.add('light-theme'); + } + } + + toggleColorsTheme(options: AppSettings) { + // Remove any existing theme class dynamically + this.htmlElement.classList.forEach((className) => { + if (className.endsWith('_theme')) { + this.htmlElement.classList.remove(className); + } + }); + + // Add the selected theme class + this.htmlElement.classList.add(options.activeTheme); + } +} diff --git a/theme/packages/main/src/app/layouts/full/horizontal/header/header.component.html b/theme/packages/main/src/app/layouts/full/horizontal/header/header.component.html new file mode 100644 index 0000000..f076a2c --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/horizontal/header/header.component.html @@ -0,0 +1,296 @@ + +
+
+ +
+ + + + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/main/src/app/layouts/full/horizontal/header/header.component.ts b/theme/packages/main/src/app/layouts/full/horizontal/header/header.component.ts new file mode 100644 index 0000000..967c333 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/horizontal/header/header.component.ts @@ -0,0 +1,292 @@ +import { Component, Output, EventEmitter, Input } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { MatDialog } from '@angular/material/dialog'; +import { navItems } from '../../vertical/sidebar/sidebar-data'; +import { TranslateService } from '@ngx-translate/core'; +import { RouterModule } from '@angular/router'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { BrandingComponent } from '../../vertical/sidebar/branding.component'; +import { FormsModule } from '@angular/forms'; +import { AppSettings } from 'src/app/config'; + +interface notifications { + id: number; + img: string; + title: string; + subtitle: string; +} + +interface profiledd { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +@Component({ + selector: 'app-horizontal-header', + imports: [RouterModule, TablerIconsModule, MaterialModule, BrandingComponent], + templateUrl: './header.component.html' +}) +export class AppHorizontalHeaderComponent { + @Input() showToggle = true; + @Input() toggleChecked = false; + @Output() toggleMobileNav = new EventEmitter(); + @Output() toggleMobileFilterNav = new EventEmitter(); + @Output() toggleCollapsed = new EventEmitter(); + + showFiller = false; + + public selectedLanguage: any = { + language: 'English', + code: 'en', + type: 'US', + icon: '/assets/images/flag/icon-flag-en.svg', + }; + + public languages: any[] = [ + { + language: 'English', + code: 'en', + type: 'US', + icon: '/assets/images/flag/icon-flag-en.svg', + }, + { + language: 'Español', + code: 'es', + icon: '/assets/images/flag/icon-flag-es.svg', + }, + { + language: 'Français', + code: 'fr', + icon: '/assets/images/flag/icon-flag-fr.svg', + }, + { + language: 'German', + code: 'de', + icon: '/assets/images/flag/icon-flag-de.svg', + }, + ]; + + @Output() optionsChange = new EventEmitter(); + + constructor( + private settings: CoreService, + private vsidenav: CoreService, + public dialog: MatDialog, + private translate: TranslateService + ) { + translate.setDefaultLang('en'); + } + + options = this.settings.getOptions(); + + openDialog() { + const dialogRef = this.dialog.open(AppHorizontalSearchDialogComponent); + + dialogRef.afterClosed().subscribe((result) => { + console.log(`Dialog result: ${result}`); + }); + } + + private emitOptions() { + this.optionsChange.emit(this.options); + } + + setlightDark(theme: string) { + this.options.theme = theme; + this.emitOptions(); + } + + changeLanguage(lang: any): void { + this.translate.use(lang.code); + this.selectedLanguage = lang; + } + + notifications: notifications[] = [ + { + id: 1, + img: '/assets/images/profile/user-1.jpg', + title: 'Roman Joined thes Team!', + subtitle: 'Congratulate him', + }, + { + id: 2, + img: '/assets/images/profile/user-2.jpg', + title: 'New message received', + subtitle: 'Salma sent you new message', + }, + { + id: 3, + img: '/assets/images/profile/user-3.jpg', + title: 'New Payment received', + subtitle: 'Check your earnings', + }, + { + id: 4, + img: '/assets/images/profile/user-4.jpg', + title: 'Jolly completed tasks', + subtitle: 'Assign her new tasks', + }, + { + id: 5, + img: '/assets/images/profile/user-5.jpg', + title: 'Roman Joined the Team!', + subtitle: 'Congratulate him', + }, + ]; + + profiledd: profiledd[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-account.svg', + title: 'My Profile', + subtitle: 'Account Settings', + link: '/', + }, + { + id: 2, + img: '/assets/images/svgs/icon-inbox.svg', + title: 'My Inbox', + subtitle: 'Messages & Email', + link: '/apps/email/inbox', + }, + { + id: 3, + img: '/assets/images/svgs/icon-tasks.svg', + title: 'My Tasks', + subtitle: 'To-do and Daily Tasks', + link: '/apps/taskboard', + }, + ]; + + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/apps/chat', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'eCommerce App', + subtitle: 'Buy a Product', + link: '/apps/email/inbox', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/apps/invoice', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/apps/calendar', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/apps/contacts', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/apps/tickets', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/apps/email/inbox', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Courses', + subtitle: 'Create new course', + link: '/apps/courses', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/theme-pages/pricing', + }, + { + id: 2, + title: 'Authentication Design', + link: '/authentication/login', + }, + { + id: 3, + title: 'Register Now', + link: '/authentication/side-register', + }, + { + id: 4, + title: '404 Error Page', + link: '/authentication/error', + }, + { + id: 5, + title: 'Notes App', + link: '/apps/notes', + }, + { + id: 6, + title: 'Employee App', + link: '/apps/employee', + }, + { + id: 7, + title: 'Todo Application', + link: '/apps/todo', + }, + { + id: 8, + title: 'Treeview', + link: '/theme-pages/treeview', + }, + ]; +} + +@Component({ + selector: 'app-search-dialog', + imports: [RouterModule, MaterialModule, TablerIconsModule, FormsModule], + templateUrl: 'search-dialog.component.html' +}) +export class AppHorizontalSearchDialogComponent { + searchText: string = ''; + navItems = navItems; + + navItemsData = navItems.filter((navitem) => navitem.displayName); +} diff --git a/theme/packages/main/src/app/layouts/full/horizontal/header/search-dialog.component.html b/theme/packages/main/src/app/layouts/full/horizontal/header/search-dialog.component.html new file mode 100644 index 0000000..0789724 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/horizontal/header/search-dialog.component.html @@ -0,0 +1,39 @@ +
+
+
+ + + +
+
+ +
+
+
+ + +

Quick Page Links

+ + @for(item of navItemsData; track item.route) { + +
+ {{ item.displayName }} +
+ {{ item.route }} +
+ } +
diff --git a/theme/packages/main/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.html b/theme/packages/main/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.html new file mode 100644 index 0000000..f0fe3aa --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.html @@ -0,0 +1,24 @@ +@if(!item.navCap) { + + + {{ item.displayName }} + @if(item.children && item.children.length) { + + expand_more + + } + +} @if(item.children){ +
+ @for(child of item.children; track child) { + + + } +
+} diff --git a/theme/packages/main/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.ts b/theme/packages/main/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.ts new file mode 100644 index 0000000..12ece86 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.ts @@ -0,0 +1,33 @@ +import { + Component, + OnInit, + Input, +} from '@angular/core'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../../services/nav.service'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { CommonModule } from '@angular/common'; +import { MatIconModule } from '@angular/material/icon'; + +@Component({ + selector: 'app-horizontal-nav-item', + imports: [TablerIconsModule, CommonModule, MatIconModule], + templateUrl: './nav-item.component.html' +}) +export class AppHorizontalNavItemComponent implements OnInit { + @Input() depth: any; + @Input() item: any; + + constructor(public navService: NavService, public router: Router) { + if (this.depth === undefined) { + this.depth = 0; + } + } + + ngOnInit() { } + onItemSelected(item: any) { + if (!item.children || !item.children.length) { + this.router.navigate([item.route]); + } + } +} diff --git a/theme/packages/main/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts b/theme/packages/main/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts new file mode 100644 index 0000000..3bdf202 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts @@ -0,0 +1,633 @@ +import { NavItem } from '../../vertical/sidebar/nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Dashboards', + iconName: 'home', + route: 'dashboards', + children: [ + { + displayName: 'Analytical', + iconName: 'point', + route: 'dashboards/dashboard1', + }, + { + displayName: 'eCommerce', + iconName: 'point', + route: 'dashboards/dashboard2', + }, + ], + }, + { + displayName: 'Frontend pages', + iconName: 'app-window', + route: 'front-pages', + children: [ + { + displayName: 'Home Page', + iconName: 'point', + route: 'front-pages/homepage', + } , + { + displayName: 'About Us', + iconName: 'point', + route: 'front-pages/about', + } , + { + displayName: 'Blog', + iconName: 'point', + route: 'front-pages/blog', + } , + { + displayName: 'Blog Details', + iconName: 'point', + route: 'front-pages/blog-details', + } , + { + displayName: 'Portfolio', + iconName: 'point', + route: 'front-pages/portfolio', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'front-pages/pricing', + }, + { + displayName: 'Contact', + iconName: 'point', + route: 'front-pages/contact', + } + ] + }, + { + displayName: 'Apps', + iconName: 'apps', + route: 'apps', + ddType: '', + children: [ + { + displayName: 'Chat', + iconName: 'point', + route: 'apps/chat', + }, + { + displayName: 'Calendar', + iconName: 'point', + route: 'apps/calendar', + }, + { + displayName: 'Email', + iconName: 'point', + route: 'apps/email/inbox', + }, + { + displayName: 'Contacts', + iconName: 'point', + route: 'apps/contacts', + }, + { + displayName: 'Contact List', + iconName: 'point', + route: 'apps/contact-list', + }, + { + displayName: 'Courses', + iconName: 'point', + route: 'apps/courses', + }, + { + displayName: 'Employee', + iconName: 'point', + route: 'apps/employee', + }, + { + displayName: 'Notes', + iconName: 'point', + route: 'apps/notes', + }, + { + displayName: 'Tickets', + iconName: 'point', + route: 'apps/tickets', + }, + { + displayName: 'Invoice', + iconName: 'point', + route: 'apps/invoice', + }, + { + displayName: 'ToDo', + iconName: 'point', + route: 'apps/todo', + }, + { + displayName: 'Kanban', + iconName: 'point', + route: 'apps/kanban', + }, + { + displayName: 'Blog', + iconName: 'point', + route: 'apps/blog', + children: [ + { + displayName: 'Post', + iconName: 'point', + route: 'apps/blog/post', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + }, + ], + }, + { + displayName: 'User Profile', + iconName: 'point', + route: 'apps/profile-details', + children: [ + { + displayName: 'Profile', + iconName: 'point', + route: 'apps/profile-details/profile', + }, + { + displayName: 'Followers', + iconName: 'point', + route: 'apps/profile-details/followers', + }, + { + displayName: 'Friends', + iconName: 'point', + route: 'apps/profile-details/friends', + }, + { + displayName: 'Gellary', + iconName: 'point', + route: 'apps/profile-details/gallery', + }, + ], + }, + { + displayName: 'Ecommerce', + iconName: 'point', + route: 'apps/product', + children: [ + { + displayName: 'Product List', + iconName: 'point', + route: 'apps/product/product-list', + }, + { + displayName: 'Add Product', + iconName: 'point', + route: 'apps/product/add-product', + }, + { + displayName: 'Edit Product', + iconName: 'point', + route: 'apps/product/edit-product', + }, + { + displayName: 'Shop', + iconName: 'point', + route: 'apps/product/shop', + }, + ], + }, + ], + }, + { + displayName: 'Ui', + iconName: 'components', + route: 'ui-components', + ddType: '', + children: [ + { + displayName: 'Badge', + iconName: 'point', + route: 'ui-components/badge', + }, + { + displayName: 'Expansion Panel', + iconName: 'point', + route: 'ui-components/expansion', + }, + { + displayName: 'Chips', + iconName: 'point', + route: 'ui-components/chips', + }, + { + displayName: 'Dialog', + iconName: 'point', + route: 'ui-components/dialog', + }, + { + displayName: 'Lists', + iconName: 'point', + route: 'ui-components/lists', + }, + { + displayName: 'Divider', + iconName: 'point', + route: 'ui-components/divider', + }, + { + displayName: 'Menu', + iconName: 'point', + route: 'ui-components/menu', + }, + { + displayName: 'Paginator', + iconName: 'point', + route: 'ui-components/paginator', + }, + { + displayName: 'Progress Bar', + iconName: 'point', + route: 'ui-components/progress', + }, + { + displayName: 'Progress Spinner', + iconName: 'point', + route: 'ui-components/progress-spinner', + }, + { + displayName: 'Ripples', + iconName: 'point', + route: 'ui-components/ripples', + }, + { + displayName: 'Slide Toggle', + iconName: 'point', + route: 'ui-components/slide-toggle', + }, + { + displayName: 'Slider', + iconName: 'point', + route: 'ui-components/slider', + }, + { + displayName: 'Snackbar', + iconName: 'point', + route: 'ui-components/snackbar', + }, + { + displayName: 'Tabs', + iconName: 'point', + route: 'ui-components/tabs', + }, + { + displayName: 'Toolbar', + iconName: 'point', + route: 'ui-components/toolbar', + }, + { + displayName: 'Tooltips', + iconName: 'point', + route: 'ui-components/tooltips', + }, + ], + }, + { + displayName: 'Pages', + iconName: 'clipboard', + route: 'theme-pages', + ddType: '', + children: [ + { + displayName: 'Treeview', + iconName: 'point', + route: 'theme-pages/treeview', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'theme-pages/pricing', + }, + { + displayName: 'Account Setting', + iconName: 'point', + route: 'theme-pages/account-setting', + }, + { + displayName: 'FAQ', + iconName: 'point', + route: 'theme-pages/faq', + }, + { + displayName: 'Landingpage', + iconName: 'point', + route: 'landingpage', + }, + { + displayName: 'Widgets', + iconName: 'point', + route: 'widgets', + children: [ + { + displayName: 'Cards', + iconName: 'point', + route: 'widgets/cards', + }, + { + displayName: 'Banners', + iconName: 'point', + route: 'widgets/banners', + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'widgets/charts', + }, + ], + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'charts', + children: [ + { + displayName: 'Line', + iconName: 'point', + route: '/charts/line', + }, + { + displayName: 'Gredient', + iconName: 'point', + route: '/charts/gredient', + }, + { + displayName: 'Area', + iconName: 'point', + route: '/charts/area', + }, + { + displayName: 'Candlestick', + iconName: 'point', + route: '/charts/candlestick', + }, + { + displayName: 'Column', + iconName: 'point', + route: '/charts/column', + }, + { + displayName: 'Doughnut & Pie', + iconName: 'point', + route: '/charts/doughnut-pie', + }, + { + displayName: 'Radialbar & Radar', + iconName: 'point', + route: '/charts/radial-radar', + }, + ], + }, + { + displayName: 'Auth', + iconName: 'point', + route: '/', + children: [ + { + displayName: 'Login', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/login', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-login', + }, + ], + }, + { + displayName: 'Register', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/side-register', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-register', + }, + ], + }, + { + displayName: 'Forgot Password', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Side Forgot Password', + iconName: 'point', + route: '/authentication/side-forgot-pwd', + }, + { + displayName: 'Boxed Forgot Password', + iconName: 'point', + route: '/authentication/boxed-forgot-pwd', + }, + ], + }, + { + displayName: 'Two Steps', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Side Two Steps', + iconName: 'point', + route: '/authentication/side-two-steps', + }, + { + displayName: 'Boxed Two Steps', + iconName: 'point', + route: '/authentication/boxed-two-steps', + }, + ], + }, + { + displayName: 'Error', + iconName: 'point', + route: '/authentication/error', + }, + { + displayName: 'Maintenance', + iconName: 'point', + route: '/authentication/maintenance', + }, + ], + }, + ], + }, + { + displayName: 'Forms', + iconName: 'file-description', + route: 'forms', + ddType: '', + children: [ + { + displayName: 'Form elements', + iconName: 'point', + route: 'forms/forms-elements', + children: [ + { + displayName: 'Autocomplete', + iconName: 'point', + route: 'forms/forms-elements/autocomplete', + }, + { + displayName: 'Button', + iconName: 'point', + route: 'forms/forms-elements/button', + }, + { + displayName: 'Checkbox', + iconName: 'point', + route: 'forms/forms-elements/checkbox', + }, + { + displayName: 'Radio', + iconName: 'point', + route: 'forms/forms-elements/radio', + }, + { + displayName: 'Datepicker', + iconName: 'point', + route: 'forms/forms-elements/datepicker', + }, + ], + }, + { + displayName: 'Form Layouts', + iconName: 'point', + route: '/forms/form-layouts', + }, + { + displayName: 'Form Horizontal', + iconName: 'point', + route: '/forms/form-horizontal', + }, + { + displayName: 'Form Vertical', + iconName: 'point', + route: '/forms/form-vertical', + }, + { + displayName: 'Form Wizard', + iconName: 'point', + route: '/forms/form-wizard', + }, + { + displayName: 'Toastr', + iconName: 'point', + route: '/forms/form-toastr', + }, + { + displayName: 'Editor', + iconName: 'point', + route: '/forms/form-editor', + }, + ], + }, + { + displayName: 'Tables', + iconName: 'layout', + route: 'tables', + ddType: '', + children: [ + { + displayName: 'Basic Table', + iconName: 'point', + route: 'tables/basic-table', + }, + { + displayName: 'Dynamic Table', + iconName: 'point', + route: 'tables/dynamic-table', + }, + { + displayName: 'Expand Table', + iconName: 'point', + route: 'tables/expand-table', + }, + { + displayName: 'Filterable Table', + iconName: 'point', + route: 'tables/filterable-table', + }, + { + displayName: 'Footer Row Table', + iconName: 'point', + route: 'tables/footer-row-table', + }, + { + displayName: 'HTTP Table', + iconName: 'point', + route: 'tables/http-table', + }, + { + displayName: 'Mix Table', + iconName: 'point', + route: 'tables/mix-table', + }, + { + displayName: 'Multi Header Footer', + iconName: 'point', + route: 'tables/multi-header-footer-table', + }, + { + displayName: 'Pagination Table', + iconName: 'point', + route: 'tables/pagination-table', + }, + { + displayName: 'Row Context Table', + iconName: 'point', + route: 'tables/row-context-table', + }, + { + displayName: 'Selection Table', + iconName: 'point', + route: 'tables/selection-table', + }, + { + displayName: 'Sortable Table', + iconName: 'point', + route: 'tables/sortable-table', + }, + { + displayName: 'Sticky Column', + iconName: 'point', + route: 'tables/sticky-column-table', + }, + { + displayName: 'Sticky Header Footer', + iconName: 'point', + route: 'tables/sticky-header-footer-table', + }, + { + displayName: 'Data table', + iconName: 'point', + route: '/datatable/kichen-sink', + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/layouts/full/horizontal/sidebar/sidebar.component.html b/theme/packages/main/src/app/layouts/full/horizontal/sidebar/sidebar.component.html new file mode 100644 index 0000000..153f529 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/horizontal/sidebar/sidebar.component.html @@ -0,0 +1,16 @@ +@if(mobileQuery.matches) { +
+
+
+
+ @for(item of navItems; track item) { + + + } +
+
+
+
+} \ No newline at end of file diff --git a/theme/packages/main/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts b/theme/packages/main/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts new file mode 100644 index 0000000..f0e13f5 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts @@ -0,0 +1,48 @@ +import { + Component, + OnInit, + Input, + ChangeDetectorRef, + OnChanges, +} from '@angular/core'; +import { navItems } from './sidebar-data'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../services/nav.service'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { AppHorizontalNavItemComponent } from './nav-item/nav-item.component'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-horizontal-sidebar', + imports: [AppHorizontalNavItemComponent, CommonModule], + templateUrl: './sidebar.component.html', +}) +export class AppHorizontalSidebarComponent implements OnInit { + navItems = navItems; + parentActive = ''; + + mobileQuery: MediaQueryList; + private _mobileQueryListener: () => void; + + constructor( + public navService: NavService, + public router: Router, + media: MediaMatcher, + changeDetectorRef: ChangeDetectorRef + ) { + this.mobileQuery = media.matchMedia('(min-width: 1100px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + this.router.events.subscribe( + () => (this.parentActive = this.router.url.split('/')[1]) + ); + } + + ngOnInit(): void { + this.parentActive = this.router.url.split('/')[1]; + + this.router.events.subscribe(() => { + this.parentActive = this.router.url.split('/')[1]; + }); + } +} diff --git a/theme/packages/main/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.html b/theme/packages/main/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.html new file mode 100644 index 0000000..439a6f6 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.html @@ -0,0 +1,36 @@ +@if(pageInfo?.['title'] != 'Analytical' && pageInfo?.['title'] != 'eCommerce'){ +
+
+
+

+ {{ pageInfo?.['title'] }} +

+
+ +
+
+
+ +
+
+
+} diff --git a/theme/packages/main/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts b/theme/packages/main/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts new file mode 100644 index 0000000..3cf2292 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { Router, NavigationEnd, ActivatedRoute, Data } from '@angular/router'; +import { filter, map, mergeMap } from 'rxjs/operators'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-breadcrumb', + imports: [RouterModule, TablerIconsModule], + templateUrl: './breadcrumb.component.html', + styleUrls: [] +}) +export class AppBreadcrumbComponent { + // @Input() layout; + pageInfo: Data | any = Object.create(null); + myurl: any = this.router.url.slice(1).split('/'); + constructor( + private router: Router, + private activatedRoute: ActivatedRoute, + private titleService: Title + ) { + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .pipe(map(() => this.activatedRoute)) + .pipe( + map((route) => { + while (route.firstChild) { + route = route.firstChild; + } + return route; + }) + ) + .pipe(filter((route) => route.outlet === 'primary')) + .pipe(mergeMap((route) => route.data)) + // tslint:disable-next-line - Disables all + .subscribe((event) => { + // tslint:disable-next-line - Disables all + this.titleService.setTitle(event['title'] + ' - Angular 20'); + this.pageInfo = event; + }); + } +} diff --git a/theme/packages/main/src/app/layouts/full/shared/customizer/customizer.component.html b/theme/packages/main/src/app/layouts/full/shared/customizer/customizer.component.html new file mode 100644 index 0000000..f0e2d87 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/shared/customizer/customizer.component.html @@ -0,0 +1,173 @@ +
+ +
+
Theme Option
+ + +
+ + Light +
+
+ +
+ + Dark +
+
+
+ +
+
+ Theme Colors +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ Theme Direction +
+ + + +
+ + LTR +
+
+ +
+ + RTL +
+
+
+ + @if(!options.horizontal){ +
+
+ Sidebar type +
+ + + +
+ + Full +
+
+ +
+ + Minisidebar +
+
+
+
+ } +
+ Layout type +
+ + + +
+ + Vertical +
+
+ +
+ + Horizontal +
+
+
+ +
+ Card with +
+ + + +
+ + Shadow +
+
+ +
+ + Border +
+
+
+ +
+ Container Option +
+ + + +
+ + Full +
+
+ +
+ + Boxed +
+
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/layouts/full/shared/customizer/customizer.component.scss b/theme/packages/main/src/app/layouts/full/shared/customizer/customizer.component.scss new file mode 100644 index 0000000..0531d09 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/shared/customizer/customizer.component.scss @@ -0,0 +1,4 @@ +.customizerNav { + width: 320px; +} + diff --git a/theme/packages/main/src/app/layouts/full/shared/customizer/customizer.component.ts b/theme/packages/main/src/app/layouts/full/shared/customizer/customizer.component.ts new file mode 100644 index 0000000..22a03c8 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/shared/customizer/customizer.component.ts @@ -0,0 +1,61 @@ +import { + Component, + Output, + EventEmitter, + ViewEncapsulation, + signal, +} from '@angular/core'; +import { AppSettings } from 'src/app/config'; +import { CoreService } from 'src/app/services/core.service'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { FormsModule } from '@angular/forms'; +import { NgScrollbarModule } from 'ngx-scrollbar'; + +@Component({ + selector: 'app-customizer', + imports: [ + TablerIconsModule, + MaterialModule, + FormsModule, + NgScrollbarModule, + ], + templateUrl: './customizer.component.html', + styleUrls: ['./customizer.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class CustomizerComponent { + + options = this.settings.getOptions(); + + + + @Output() optionsChange = new EventEmitter(); + hideSingleSelectionIndicator = signal(true); + + constructor(private settings: CoreService) { } + setDark() { + this.settings.setOptions({ theme: 'dark' }); + this.emitOptions(); + } + + setColor(color: string) { + this.settings.setOptions({ activeTheme: color }); + this.emitOptions(); + } + + setDir(dir: 'ltr' | 'rtl') { + this.settings.setOptions({ dir: dir }); + this.emitOptions(); + } + + setSidebar(sidenavOpened: boolean) { + this.settings.setOptions({ sidenavOpened: sidenavOpened }); + this.emitOptions(); + } + + private emitOptions() { + this.optionsChange.emit(this.options); + } +} + diff --git a/theme/packages/main/src/app/layouts/full/vertical/header/header.component.html b/theme/packages/main/src/app/layouts/full/vertical/header/header.component.html new file mode 100644 index 0000000..3949a30 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/vertical/header/header.component.html @@ -0,0 +1,301 @@ + + + + @if(showToggle) { + + } + + + @if(!showToggle) { + + } + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently + Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ + @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/main/src/app/layouts/full/vertical/header/header.component.ts b/theme/packages/main/src/app/layouts/full/vertical/header/header.component.ts new file mode 100644 index 0000000..d72a6e8 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/vertical/header/header.component.ts @@ -0,0 +1,310 @@ +import { + Component, + Output, + EventEmitter, + Input, + ViewEncapsulation, +} from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { MatDialog } from '@angular/material/dialog'; +import { navItems } from '../sidebar/sidebar-data'; +import { TranslateService } from '@ngx-translate/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { RouterModule } from '@angular/router'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { AppSettings } from 'src/app/config'; + +interface notifications { + id: number; + img: string; + title: string; + subtitle: string; +} + +interface profiledd { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +@Component({ + selector: 'app-header', + imports: [ + RouterModule, + CommonModule, + NgScrollbarModule, + TablerIconsModule, + MaterialModule, + ], + templateUrl: './header.component.html', + encapsulation: ViewEncapsulation.None +}) +export class HeaderComponent { + @Input() showToggle = true; + @Input() toggleChecked = false; + @Output() toggleMobileNav = new EventEmitter(); + @Output() toggleMobileFilterNav = new EventEmitter(); + @Output() toggleCollapsed = new EventEmitter(); + + showFiller = false; + + public selectedLanguage: any = { + language: 'English', + code: 'en', + type: 'US', + icon: '/assets/images/flag/icon-flag-en.svg', + }; + + public languages: any[] = [ + { + language: 'English', + code: 'en', + type: 'US', + icon: '/assets/images/flag/icon-flag-en.svg', + }, + { + language: 'Español', + code: 'es', + icon: '/assets/images/flag/icon-flag-es.svg', + }, + { + language: 'Français', + code: 'fr', + icon: '/assets/images/flag/icon-flag-fr.svg', + }, + { + language: 'German', + code: 'de', + icon: '/assets/images/flag/icon-flag-de.svg', + }, + ]; + + @Output() optionsChange = new EventEmitter(); + + constructor( + private settings: CoreService, + private vsidenav: CoreService, + public dialog: MatDialog, + private translate: TranslateService + ) { + translate.setDefaultLang('en'); + } + + options = this.settings.getOptions(); + + openDialog() { + const dialogRef = this.dialog.open(AppSearchDialogComponent); + + dialogRef.afterClosed().subscribe((result) => { + console.log(`Dialog result: ${result}`); + }); + } + + private emitOptions() { + this.optionsChange.emit(this.options); + } + + setlightDark(theme: string) { + this.options.theme = theme; + this.emitOptions(); + } + + changeLanguage(lang: any): void { + this.translate.use(lang.code); + this.selectedLanguage = lang; + } + + notifications: notifications[] = [ + { + id: 1, + img: '/assets/images/profile/user-1.jpg', + title: 'Roman Joined thes Team!', + subtitle: 'Congratulate him', + }, + { + id: 2, + img: '/assets/images/profile/user-2.jpg', + title: 'New message received', + subtitle: 'Salma sent you new message', + }, + { + id: 3, + img: '/assets/images/profile/user-3.jpg', + title: 'New Payment received', + subtitle: 'Check your earnings', + }, + { + id: 4, + img: '/assets/images/profile/user-4.jpg', + title: 'Jolly completed tasks', + subtitle: 'Assign her new tasks', + }, + { + id: 5, + img: '/assets/images/profile/user-5.jpg', + title: 'Roman Joined the Team!', + subtitle: 'Congratulatse him', + }, + ]; + + profiledd: profiledd[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-account.svg', + title: 'My Profile', + subtitle: 'Account Settings', + link: '/', + }, + { + id: 2, + img: '/assets/images/svgs/icon-inbox.svg', + title: 'My Inbox', + subtitle: 'Messages & Email', + link: '/apps/email/inbox', + }, + { + id: 3, + img: '/assets/images/svgs/icon-tasks.svg', + title: 'My Tasks', + subtitle: 'To-do and Daily Tasks', + link: '/apps/taskboard', + }, + ]; + + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/apps/chat', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'Todo App', + subtitle: 'Completed task', + link: '/apps/todo', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/apps/invoice', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/apps/calendar', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/apps/contacts', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/apps/tickets', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/apps/email/inbox', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Conatct List', + subtitle: 'Create new contact', + link: '/apps/contact-list', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/theme-pages/pricing', + }, + { + id: 2, + title: 'Authentication Design', + link: '/authentication/login', + }, + { + id: 3, + title: 'Register Now', + link: '/authentication/side-register', + }, + { + id: 4, + title: '404 Error Page', + link: '/authentication/error', + }, + { + id: 5, + title: 'Notes App', + link: '/apps/notes', + }, + { + id: 6, + title: 'Employee App', + link: '/apps/employee', + }, + { + id: 7, + title: 'Todo Application', + link: '/apps/todo', + }, + { + id: 8, + title: 'Treeview', + link: '/theme-pages/treeview', + }, + ]; +} + +@Component({ + selector: 'search-dialog', + imports: [RouterModule, MaterialModule, TablerIconsModule, FormsModule], + templateUrl: 'search-dialog.component.html' +}) +export class AppSearchDialogComponent { + searchText: string = ''; + navItems = navItems; + + navItemsData = navItems.filter((navitem) => navitem.displayName); + + // filtered = this.navItemsData.find((obj) => { + // return obj.displayName == this.searchinput; + // }); +} diff --git a/theme/packages/main/src/app/layouts/full/vertical/header/search-dialog.component.html b/theme/packages/main/src/app/layouts/full/vertical/header/search-dialog.component.html new file mode 100644 index 0000000..6d2f6d2 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/vertical/header/search-dialog.component.html @@ -0,0 +1,39 @@ +
+
+
+ + + +
+
+ +
+
+
+ + +

Quick Page Links

+ + @for(item of navItemsData; track item.displayName) { + +
+ {{ item.displayName }} +
+ {{ item.route }} +
+ } +
diff --git a/theme/packages/main/src/app/layouts/full/vertical/sidebar/branding.component.ts b/theme/packages/main/src/app/layouts/full/vertical/sidebar/branding.component.ts new file mode 100644 index 0000000..c383e9f --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/vertical/sidebar/branding.component.ts @@ -0,0 +1,28 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; + +@Component({ + selector: 'app-branding', + imports: [], + template: ` + + logo + + + + logo + + `, +}) +export class BrandingComponent { + options = this.settings.getOptions(); + constructor(private settings: CoreService) {} +} diff --git a/theme/packages/main/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.html b/theme/packages/main/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.html new file mode 100644 index 0000000..3f9a6a8 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.html @@ -0,0 +1,51 @@ +@if(item.navCap){ + +} @if(!item.navCap && !item.external && !item.twoLines) { + + + {{ item.displayName | translate }} +
+ @if(item.children && item.children.length) { + @if(item.chip) { + + {{ item.chipContent }} + + } + + + + expand_more + + + } +
+ @if(item.chip && !item.children ) { + + {{ item.chipContent }} + + } +
+} + + + +@if(!item.navCap && item.external) { + + + {{ item.displayName | translate }} + +} + + +@if(expanded) { @for(child of item.children; track child) { + + +} } \ No newline at end of file diff --git a/theme/packages/main/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts b/theme/packages/main/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts new file mode 100644 index 0000000..3782536 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts @@ -0,0 +1,103 @@ +import { + Component, + HostBinding, + Input, + OnInit, + OnChanges, + Output, + EventEmitter, +} from '@angular/core'; +import { NavItem } from './nav-item'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../../services/nav.service'; +import { + animate, + state, + style, + transition, + trigger, +} from '@angular/animations'; +import { TranslateModule } from '@ngx-translate/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-nav-item', + imports: [TranslateModule, TablerIconsModule, MaterialModule, CommonModule], + templateUrl: './nav-item.component.html', + styleUrls: [], + animations: [ + trigger('indicatorRotate', [ + state('collapsed', style({ transform: 'rotate(0deg)' })), + state('expanded', style({ transform: 'rotate(180deg)' })), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4,0.0,0.2,1)')), + ]), + ] +}) +export class AppNavItemComponent implements OnChanges { + @Output() toggleMobileLink: any = new EventEmitter(); + @Output() notify: EventEmitter = new EventEmitter(); + + expanded: any = false; + disabled: any = false; + twoLines: any = false; + @HostBinding('attr.aria-expanded') ariaExpanded = this.expanded; + @Input() item: NavItem | any; + @Input() depth: any; + + constructor(public navService: NavService, public router: Router) { + if (this.depth === undefined) { + this.depth = 0; + } + } + + ngOnChanges() { + const url = this.navService.currentUrl(); + if (this.item.route && url) { + this.expanded = url.indexOf(`/${this.item.route}`) === 0; + this.ariaExpanded = this.expanded; + } + } + + onItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + this.router.navigate([item.route]); + + } + if (item.children && item.children.length) { + this.expanded = !this.expanded; + } + //scroll + window.scroll({ + top: 0, + left: 0, + behavior: 'smooth', + }); + if (!this.expanded) { + if (window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + onSubItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + if (this.expanded && window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + isDirectlyActive(item: NavItem): boolean { + return !!item.route && this.router.isActive(item.route, true); + } + + isChildActive(item: NavItem): boolean { + if (!item.children) return false; + return item.children.some( + (child) => this.isDirectlyActive(child) || this.isChildActive(child) + ); + } + +} diff --git a/theme/packages/main/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.ts b/theme/packages/main/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.ts new file mode 100644 index 0000000..a6274be --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.ts @@ -0,0 +1,15 @@ +export interface NavItem { + displayName?: string; + disabled?: boolean; + external?: boolean; + twoLines?: boolean; + chip?: boolean; + iconName?: string; + navCap?: string; + chipContent?: string; + chipClass?: string; + subtext?: string; + route?: string; + children?: NavItem[]; + ddType?: string; +} \ No newline at end of file diff --git a/theme/packages/main/src/app/layouts/full/vertical/sidebar/sidebar-data.ts b/theme/packages/main/src/app/layouts/full/vertical/sidebar/sidebar-data.ts new file mode 100644 index 0000000..e52b956 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/vertical/sidebar/sidebar-data.ts @@ -0,0 +1,705 @@ +import { NavItem } from './nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Analytical', + iconName: 'aperture', + route: '/dashboards/dashboard1', + }, + { + displayName: 'eCommerce', + iconName: 'shopping-cart', + route: '/dashboards/dashboard2', + }, + { + displayName: 'Frontend pages', + iconName: 'app-window', + route: 'front-pages', + children: [ + { + displayName: 'Home Page', + iconName: 'point', + route: 'front-pages/homepage', + } , + { + displayName: 'About Us', + iconName: 'point', + route: 'front-pages/about', + } , + { + displayName: 'Blog', + iconName: 'point', + route: 'front-pages/blog', + } , + { + displayName: 'Blog Details', + iconName: 'point', + route: 'front-pages/blog-details', + } , + { + displayName: 'Portfolio', + iconName: 'point', + route: 'front-pages/portfolio', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'front-pages/pricing', + }, + { + displayName: 'Contact', + iconName: 'point', + route: 'front-pages/contact', + } + ] + }, + { + navCap: 'Apps', + }, + { + displayName: 'Chat', + iconName: 'message-2', + route: 'apps/chat', + }, + { + displayName: 'Calendar', + iconName: 'calendar-event', + route: 'apps/calendar', + }, + { + displayName: 'Email', + iconName: 'mail', + route: 'apps/email/inbox', + }, + { + displayName: 'Kanban', + iconName: 'checklist', + route: 'apps/kanban', + }, + { + displayName: 'User Profile', + iconName: 'user-circle', + route: 'apps/profile-details', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'New', + children: [ + { + displayName: 'Profile', + iconName: 'point', + route: 'apps/profile-details/profile', + }, + { + displayName: 'Followers', + iconName: 'point', + route: 'apps/profile-details/followers', + }, + { + displayName: 'Friends', + iconName: 'point', + route: 'apps/profile-details/friends', + }, + { + displayName: 'Gellary', + iconName: 'point', + route: 'apps/profile-details/gallery', + }, + ], + }, + { + displayName: 'Ecommerce', + iconName: 'basket', + route: 'apps/product', + chip: true, + chipClass: 'border-error text-error', + chipContent: 'New', + children: [ + { + displayName: 'Product List', + iconName: 'point', + route: 'apps/product/product-list', + }, + { + displayName: 'Add Product', + iconName: 'point', + route: 'apps/product/add-product', + }, + { + displayName: 'Edit Product', + iconName: 'point', + route: 'apps/product/edit-product', + }, + { + displayName: 'Shop', + iconName: 'point', + route: 'apps/product/shop', + }, + ], + }, + { + displayName: 'Contacts', + iconName: 'phone', + route: 'apps/contacts', + }, + { + displayName: 'Courses', + iconName: 'certificate', + route: 'apps/courses', + }, + { + displayName: 'Employee', + iconName: 'brand-ctemplar', + route: 'apps/employee', + }, + { + displayName: 'Notes', + iconName: 'note', + route: 'apps/notes', + }, + { + displayName: 'Tickets', + iconName: 'ticket', + route: 'apps/tickets', + }, + { + displayName: 'Contact List', + iconName: 'phone', + route: 'apps/contact-list', + }, + { + displayName: 'Invoice', + iconName: 'file-invoice', + route: 'apps/invoice', + children: [ + { + displayName: 'List', + iconName: 'point', + route: 'apps/invoice/list', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/invoice/viewInvoice/101', + }, + { + displayName: 'Create', + iconName: 'point', + route: 'apps/invoice/addInvoice', + }, + { + displayName: 'Edit', + iconName: 'point', + route: 'apps/invoice/editinvoice/101', + }, + ], + }, + { + displayName: 'ToDo', + iconName: 'edit', + route: 'apps/todo', + }, + { + displayName: 'Blog', + iconName: 'chart-donut-3', + route: 'apps/blog', + children: [ + { + displayName: 'Post', + iconName: 'point', + route: 'apps/blog/post', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + }, + ], + }, + { + navCap: 'Pages', + }, + { + displayName: 'Roll Base Access', + iconName: 'lock-access', + route: 'apps/permission', + }, + { + displayName: 'Treeview', + iconName: 'git-merge', + route: 'theme-pages/treeview', + }, + { + displayName: 'Pricing', + iconName: 'currency-dollar', + route: 'theme-pages/pricing', + }, + { + displayName: 'Account Setting', + iconName: 'user-circle', + route: 'theme-pages/account-setting', + }, + { + displayName: 'FAQ', + iconName: 'help', + route: 'theme-pages/faq', + }, + { + displayName: 'Landingpage', + iconName: 'app-window', + route: 'landingpage', + }, + { + displayName: 'Widgets', + iconName: 'layout', + route: 'widgets', + children: [ + { + displayName: 'Cards', + iconName: 'point', + route: 'widgets/cards', + }, + { + displayName: 'Banners', + iconName: 'point', + route: 'widgets/banners', + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'widgets/charts', + }, + ], + }, + { + navCap: 'Forms', + }, + { + displayName: 'Form elements', + iconName: 'apps', + route: 'forms/forms-elements', + children: [ + { + displayName: 'Autocomplete', + iconName: 'point', + route: 'forms/forms-elements/autocomplete', + }, + { + displayName: 'Button', + iconName: 'point', + route: 'forms/forms-elements/button', + }, + { + displayName: 'Checkbox', + iconName: 'point', + route: 'forms/forms-elements/checkbox', + }, + { + displayName: 'Radio', + iconName: 'point', + route: 'forms/forms-elements/radio', + }, + { + displayName: 'Datepicker', + iconName: 'point', + route: 'forms/forms-elements/datepicker', + }, + ], + }, + { + displayName: 'Form Layouts', + iconName: 'file-description', + route: '/forms/form-layouts', + }, + { + displayName: 'Form Horizontal', + iconName: 'box-align-bottom', + route: '/forms/form-horizontal', + }, + { + displayName: 'Form Vertical', + iconName: 'box-align-left', + route: '/forms/form-vertical', + }, + { + displayName: 'Form Wizard', + iconName: 'files', + route: '/forms/form-wizard', + }, + { + displayName: 'Toastr', + iconName: 'notification', + route: '/forms/form-toastr', + }, + { + displayName: 'Editor', + iconName: 'edit', + route: '/forms/form-editor', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'New', + }, + { + navCap: 'Tables', + }, + { + displayName: 'Tables', + iconName: 'layout', + route: 'tables', + children: [ + { + displayName: 'Basic Table', + iconName: 'point', + route: 'tables/basic-table', + }, + { + displayName: 'Dynamic Table', + iconName: 'point', + route: 'tables/dynamic-table', + }, + { + displayName: 'Expand Table', + iconName: 'point', + route: 'tables/expand-table', + }, + { + displayName: 'Filterable Table', + iconName: 'point', + route: 'tables/filterable-table', + }, + { + displayName: 'Footer Row Table', + iconName: 'point', + route: 'tables/footer-row-table', + }, + { + displayName: 'HTTP Table', + iconName: 'point', + route: 'tables/http-table', + }, + { + displayName: 'Mix Table', + iconName: 'point', + route: 'tables/mix-table', + }, + { + displayName: 'Multi Header Footer', + iconName: 'point', + route: 'tables/multi-header-footer-table', + }, + { + displayName: 'Pagination Table', + iconName: 'point', + route: 'tables/pagination-table', + }, + { + displayName: 'Row Context Table', + iconName: 'point', + route: 'tables/row-context-table', + }, + { + displayName: 'Selection Table', + iconName: 'point', + route: 'tables/selection-table', + }, + { + displayName: 'Sortable Table', + iconName: 'point', + route: 'tables/sortable-table', + }, + { + displayName: 'Sticky Column', + iconName: 'point', + route: 'tables/sticky-column-table', + }, + { + displayName: 'Sticky Header Footer', + iconName: 'point', + route: 'tables/sticky-header-footer-table', + }, + ], + }, + { + displayName: 'Data table', + iconName: 'border-outer', + route: '/datatable/kichen-sink', + }, + { + navCap: 'Chart', + }, + { + displayName: 'Line', + iconName: 'chart-line', + route: '/charts/line', + }, + { + displayName: 'Gredient', + iconName: 'chart-arcs', + route: '/charts/gredient', + }, + { + displayName: 'Area', + iconName: 'chart-area', + route: '/charts/area', + }, + { + displayName: 'Candlestick', + iconName: 'chart-candle', + route: '/charts/candlestick', + }, + { + displayName: 'Column', + iconName: 'chart-dots', + route: '/charts/column', + }, + { + displayName: 'Doughnut & Pie', + iconName: 'chart-donut-3', + route: '/charts/doughnut-pie', + }, + { + displayName: 'Radialbar & Radar', + iconName: 'chart-radar', + route: '/charts/radial-radar', + }, + { + navCap: 'UI', + }, + { + displayName: 'Ui Components', + iconName: 'box', + route: 'ui-components', + children: [ + { + displayName: 'Badge', + iconName: 'point', + route: 'ui-components/badge', + }, + { + displayName: 'Expansion Panel', + iconName: 'point', + route: 'ui-components/expansion', + }, + { + displayName: 'Chips', + iconName: 'point', + route: 'ui-components/chips', + }, + { + displayName: 'Dialog', + iconName: 'point', + route: 'ui-components/dialog', + }, + { + displayName: 'Lists', + iconName: 'point', + route: 'ui-components/lists', + }, + { + displayName: 'Divider', + iconName: 'point', + route: 'ui-components/divider', + }, + { + displayName: 'Menu', + iconName: 'point', + route: 'ui-components/menu', + }, + { + displayName: 'Paginator', + iconName: 'point', + route: 'ui-components/paginator', + }, + { + displayName: 'Progress Bar', + iconName: 'point', + route: 'ui-components/progress', + }, + { + displayName: 'Progress Spinner', + iconName: 'point', + route: 'ui-components/progress-spinner', + }, + { + displayName: 'Ripples', + iconName: 'point', + route: 'ui-components/ripples', + }, + { + displayName: 'Slide Toggle', + iconName: 'point', + route: 'ui-components/slide-toggle', + }, + { + displayName: 'Slider', + iconName: 'point', + route: 'ui-components/slider', + }, + { + displayName: 'Snackbar', + iconName: 'point', + route: 'ui-components/snackbar', + }, + { + displayName: 'Tabs', + iconName: 'point', + route: 'ui-components/tabs', + }, + { + displayName: 'Toolbar', + iconName: 'point', + route: 'ui-components/toolbar', + }, + { + displayName: 'Tooltips', + iconName: 'point', + route: 'ui-components/tooltips', + }, + ], + }, + { + navCap: 'Auth', + }, + { + displayName: 'Login', + iconName: 'login', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/login', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-login', + }, + ], + }, + { + displayName: 'Register', + iconName: 'user-plus', + route: '/authentication', + children: [ + { + displayName: 'Side Register', + iconName: 'point', + route: '/authentication/side-register', + }, + { + displayName: 'Boxed Register', + iconName: 'point', + route: '/authentication/boxed-register', + }, + ], + }, + { + displayName: 'Forgot Password', + iconName: 'rotate', + route: '/authentication', + children: [ + { + displayName: 'Side Forgot Password', + iconName: 'point', + route: '/authentication/side-forgot-pwd', + }, + { + displayName: 'Boxed Forgot Password', + iconName: 'point', + route: '/authentication/boxed-forgot-pwd', + }, + ], + }, + { + displayName: 'Two Steps', + iconName: 'zoom-code', + route: '/authentication', + children: [ + { + displayName: 'Side Two Steps', + iconName: 'point', + route: '/authentication/side-two-steps', + }, + { + displayName: 'Boxed Two Steps', + iconName: 'point', + route: '/authentication/boxed-two-steps', + }, + ], + }, + { + displayName: 'Error', + iconName: 'alert-circle', + route: '/authentication/error', + }, + { + displayName: 'Maintenance', + iconName: 'settings', + route: '/authentication/maintenance', + }, + { + navCap: 'Other', + }, + { + displayName: 'Menu Level', + iconName: 'box-multiple', + route: '/menu-level', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + { + displayName: 'Disabled', + iconName: 'ban', + route: '/disabled', + disabled: true, + }, + { + displayName: 'Chip', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-primary text-white', + chipContent: '9', + }, + { + displayName: 'Outlined', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'outlined', + }, + { + displayName: 'External Link', + iconName: 'star', + route: 'https://www.google.com/', + external: true, + }, +]; diff --git a/theme/packages/main/src/app/layouts/full/vertical/sidebar/sidebar.component.html b/theme/packages/main/src/app/layouts/full/vertical/sidebar/sidebar.component.html new file mode 100644 index 0000000..34d6b71 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/vertical/sidebar/sidebar.component.html @@ -0,0 +1,15 @@ +
+
+ +
+ + @if(showToggle) { + + + + } +
diff --git a/theme/packages/main/src/app/layouts/full/vertical/sidebar/sidebar.component.ts b/theme/packages/main/src/app/layouts/full/vertical/sidebar/sidebar.component.ts new file mode 100644 index 0000000..46d8670 --- /dev/null +++ b/theme/packages/main/src/app/layouts/full/vertical/sidebar/sidebar.component.ts @@ -0,0 +1,25 @@ +import { + Component, + EventEmitter, + Input, + OnInit, + Output, + ViewChild, +} from '@angular/core'; +import { BrandingComponent } from './branding.component'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-sidebar', + imports: [BrandingComponent, TablerIconsModule, MaterialModule], + templateUrl: './sidebar.component.html' +}) +export class SidebarComponent implements OnInit { + constructor() { } + @Input() showToggle = true; + @Output() toggleMobileNav = new EventEmitter(); + @Output() toggleCollapsed = new EventEmitter(); + + ngOnInit(): void { } +} \ No newline at end of file diff --git a/theme/packages/main/src/app/material.module.ts b/theme/packages/main/src/app/material.module.ts new file mode 100644 index 0000000..8fd4750 --- /dev/null +++ b/theme/packages/main/src/app/material.module.ts @@ -0,0 +1,89 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +// Material Form Controls +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatSelectModule } from '@angular/material/select'; +import { MatSliderModule } from '@angular/material/slider'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +// Material Navigation +import { MatMenuModule } from '@angular/material/menu'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatToolbarModule } from '@angular/material/toolbar'; +// Material Layout +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatListModule } from '@angular/material/list'; +import { MatStepperModule } from '@angular/material/stepper'; +import { MatTabsModule } from '@angular/material/tabs'; +import { MatTreeModule } from '@angular/material/tree'; +// Material Buttons & Indicators +import { MatButtonModule } from '@angular/material/button'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatIconModule } from '@angular/material/icon'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +// Material Popups & Modals +import { MatBottomSheetModule } from '@angular/material/bottom-sheet'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { MatTooltipModule } from '@angular/material/tooltip'; +// Material Data tables +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatSortModule } from '@angular/material/sort'; +import { MatTableModule } from '@angular/material/table'; + +@NgModule({ + declarations: [], + imports: [ + + ], + exports: [ + MatAutocompleteModule, + MatCheckboxModule, + MatDatepickerModule, + MatFormFieldModule, + MatInputModule, + MatRadioModule, + MatSelectModule, + MatSliderModule, + MatSlideToggleModule, + MatMenuModule, + MatSidenavModule, + MatToolbarModule, + MatCardModule, + MatDividerModule, + MatExpansionModule, + MatGridListModule, + MatListModule, + MatStepperModule, + MatTabsModule, + MatTreeModule, + MatButtonModule, + MatButtonToggleModule, + MatBadgeModule, + MatChipsModule, + MatIconModule, + MatProgressSpinnerModule, + MatProgressBarModule, + MatRippleModule, + MatBottomSheetModule, + MatDialogModule, + MatSnackBarModule, + MatTooltipModule, + MatPaginatorModule, + MatSortModule, + MatTableModule, + ], + +}) +export class MaterialModule {} diff --git a/theme/packages/main/src/app/pages/apps/apps.routes.ts b/theme/packages/main/src/app/pages/apps/apps.routes.ts new file mode 100644 index 0000000..cee8ef6 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/apps.routes.ts @@ -0,0 +1,361 @@ +import { Routes } from '@angular/router'; + +import { AppChatComponent } from './chat/chat.component'; +import { AppEmailComponent } from './email/email.component'; +import { DetailComponent } from './email/detail/detail.component'; +import { AppCoursesComponent } from './courses/courses.component'; +import { AppCourseDetailComponent } from './courses/course-detail/course-detail.component'; +import { AppEmployeeComponent } from './employee/employee.component'; +import { AppBlogsComponent } from './blogs/blogs.component'; +import { AppBlogDetailsComponent } from './blogs/details/details.component'; +import { AppContactComponent } from './contact/contact.component'; +import { AppNotesComponent } from './notes/notes.component'; +import { AppTodoComponent } from './todo/todo.component'; +import { AppPermissionComponent } from './permission/permission.component'; +import { AppKanbanComponent } from './kanban/kanban.component'; +import { AppFullcalendarComponent } from './fullcalendar/fullcalendar.component'; +import { AppTicketlistComponent } from './tickets/tickets.component'; +import { AppInvoiceListComponent } from './invoice/invoice-list/invoice-list.component'; +import { AppAddInvoiceComponent } from './invoice/add-invoice/add-invoice.component'; +import { AppInvoiceViewComponent } from './invoice/invoice-view/invoice-view.component'; +import { AppEditInvoiceComponent } from './invoice/edit-invoice/edit-invoice.component'; +import { AppContactListComponent } from './contact-list/contact-list.component'; +import { ProfileContentComponent } from './profile-content/profile-content.component'; +import { FollowersComponent } from './profile-content/followers/followers.component'; +import { GalleryComponent } from './profile-content/gallery/gallery.component'; +import { FriendsComponent } from './profile-content/friends/friends.component'; +import { ProductComponent } from './ecommerce/ecommerce.component'; +import { AddProductComponent } from './ecommerce/add-product/add-product.component'; +import { ProductDetailsComponent } from './ecommerce/product-details/product-details.component'; +import { ShopComponent } from './ecommerce/shop/shop.component'; + + +export const AppsRoutes: Routes = [ + { + path: '', + children: [ + { + path: 'chat', + component: AppChatComponent, + data: { + title: 'Chat', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Chat' }, + ], + }, + }, + { + path: 'calendar', + component: AppFullcalendarComponent, + data: { + title: 'Calendar', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Calendar' }, + ], + }, + }, + { + path: 'notes', + component: AppNotesComponent, + data: { + title: 'Notes', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Notes' }, + ], + }, + }, + { path: 'email', redirectTo: 'email/inbox', pathMatch: 'full' }, + { + path: 'email/:type', + component: AppEmailComponent, + data: { + title: 'Email', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Email' }, + ], + }, + children: [ + { + path: ':id', + component: DetailComponent, + data: { + title: 'Email Detail', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Email Detail' }, + ], + }, + }, + ], + }, + { + path: 'permission', + component: AppPermissionComponent, + data: { + title: 'Roll Base Access', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Roll Base Access' }, + ], + }, + }, + { + path: 'todo', + component: AppTodoComponent, + data: { + title: 'Todo App', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Todo App' }, + ], + }, + }, + { + path: 'kanban', + component: AppKanbanComponent, + data: { + title: 'Kanban', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Kanban' }, + ], + }, + }, + { + path: 'tickets', + component: AppTicketlistComponent, + data: { + title: 'Tickets', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Tickets' }, + ], + }, + }, + { + path: 'contacts', + component: AppContactComponent, + data: { + title: 'Contacts', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Contacts' }, + ], + }, + }, + { + path: 'courses', + component: AppCoursesComponent, + data: { + title: 'Courses', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Courses' }, + ], + }, + }, + { + path: 'contact-list', + component: AppContactListComponent, + data: { + title: 'Contact List', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Contact List' }, + ], + }, + }, + { + path: 'courses/coursesdetail/:id', + component: AppCourseDetailComponent, + data: { + title: 'Course Detail', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Course Detail' }, + ], + }, + }, + { + path: 'blog/post', + component: AppBlogsComponent, + data: { + title: 'Posts', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Posts' }, + ], + }, + }, + { + path: 'blog/detail/:id', + component: AppBlogDetailsComponent, + data: { + title: 'Blog Detail', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Blog Detail' }, + ], + }, + }, + { + path: 'employee', + component: AppEmployeeComponent, + data: { + title: 'Employee', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Employee' }, + ], + }, + }, + { + path: 'invoice/list', + component: AppInvoiceListComponent, + data: { + title: 'Invoice', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Invoice' }, + ], + }, + }, + { + path: 'invoice/addInvoice', + component: AppAddInvoiceComponent, + data: { + title: 'Add Invoice', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Add Invoice' }, + ], + }, + }, + { + path: 'invoice/viewInvoice/:id', + component: AppInvoiceViewComponent, + data: { + title: 'View Invoice', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'View Invoice' }, + ], + }, + }, + { + path: 'invoice/editinvoice/:id', + component: AppEditInvoiceComponent, + data: { + title: 'Edit Invoice', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Edit Invoice' }, + ], + }, + }, + { + path: 'profile-details/profile', + component: ProfileContentComponent, + data: { + title: 'User Details', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'User Details' }, + ], + }, + }, + { + path: 'profile-details/followers', + component: FollowersComponent, + data: { + title: 'Followers', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Followers' }, + ], + }, + }, + { + path: 'profile-details/friends', + component: FriendsComponent, + data: { + title: 'Friends', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Friends' }, + ], + }, + }, + { + path: 'profile-details/gallery', + component: GalleryComponent, + data: { + title: 'Gellary', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Gellary' }, + ], + }, + }, + { + path: 'product/product-list', + component: ProductComponent, + data: { + title: 'Product List', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Product List' }, + ], + }, + }, + { + path: 'product/add-product', + component: AddProductComponent, + data: { + title: 'Add Product', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Add Product' }, + ], + }, + }, + { + path: 'product/product-details', + component: ProductDetailsComponent, + data: { + title: 'Product Details', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Product Details' }, + ], + }, + }, + { + path: 'product/edit-product', + component: AddProductComponent, + data: { + title: 'Edit Product', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Edit Product' }, + ], + }, + }, + { + path: 'product/shop', + component: ShopComponent, + data: { + title: 'Shop', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Shop' }, + ], + }, + }, + ], + }, +]; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/blogs/blogData.ts b/theme/packages/main/src/app/pages/apps/blogs/blogData.ts new file mode 100644 index 0000000..a9b5847 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/blogs/blogData.ts @@ -0,0 +1,139 @@ +interface blogPosts { + id: number; + time: string; + imgSrc: string; + user: string; + title: string; + views: string; + category: string; + comments: number; + featuredPost: boolean; + date: string; +} + +export const blogPosts: blogPosts[] = [ + { + id: 1, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img1.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + views: '9,125', + category: 'Gadget', + comments: 3, + featuredPost: true, + date: 'Mon, Dec 25', + }, + { + id: 2, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img2.jpg', + user: '/assets/images/profile/user-2.jpg', + title: 'Presented by Max Rushden with Barry Glendenning, Philippe Auclair', + views: '9,125', + category: 'Health', + comments: 3, + featuredPost: false, + date: 'Sun, Dec 25', + }, + { + id: 3, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img3.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Gadget', + comments: 12, + featuredPost: false, + date: 'Sat, Dec 25', + }, + { + id: 4, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img4.jpg', + user: '/assets/images/profile/user-4.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Social', + comments: 12, + featuredPost: false, + date: 'Sat, Dec 25', + }, + { + id: 5, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img5.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Lifestyle', + comments: 3, + featuredPost: false, + date: 'Mon, Dec 25', + }, + { + id: 6, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img6.jpg', + user: '/assets/images/profile/user-2.jpg', + title: 'Streaming video way before it was cool, go dark tomorrow', + views: '9,125', + category: 'Health', + comments: 3, + featuredPost: false, + date: 'Sun, Dec 25', + }, + { + id: 7, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img8.jpg', + user: '/assets/images/profile/user-3.jpg', + title: + 'Apple is apparently working on a new ‘streamlined’ accessibility iOS', + views: '9,125', + category: 'Design', + comments: 12, + featuredPost: false, + date: 'Sat, Dec 25', + }, + { + id: 8, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img9.jpg', + user: '/assets/images/profile/user-4.jpg', + title: 'After Twitter Staff Cuts, Survivors Face ‘Radio Silence', + views: '9,125', + category: 'Lifestyle', + comments: 12, + featuredPost: false, + date: 'Sat, Dec 25', + }, + { + id: 9, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img10.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'Why Figma is selling to Adobe for $20 billion', + views: '9,125', + category: 'Design', + comments: 3, + featuredPost: false, + date: 'Mon, Dec 25', + }, + { + id: 10, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img11.jpg', + user: '/assets/images/profile/user-2.jpg', + title: 'Garmins Instinct Crossover is a rugged hybrid smartwatch', + views: '9,125', + category: 'Gadget', + comments: 3, + featuredPost: false, + date: 'Sun, Dec 25', + }, +]; + + diff --git a/theme/packages/main/src/app/pages/apps/blogs/blogs.component.html b/theme/packages/main/src/app/pages/apps/blogs/blogs.component.html new file mode 100644 index 0000000..c4b591e --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/blogs/blogs.component.html @@ -0,0 +1,110 @@ +
+ @for(blogPost of blogService.getBlog(); track blogPost.user) { + + + + @if(blogPost.featuredPost) { +
+ + Photo of a Shiba Inu + + +
+ } + + + + + @else { +
+ + Photo of a Shiba Inu +
+ {{ + blogPost.category + }} + {{ + blogPost.time + }} +
+ + +
+ +
+ {{ + blogPost.title + }} +
+
+ {{ blogPost.views }} + {{ blogPost.comments }} +
+ + + {{ blogPost.date }} + +
+
+
+
+ } } +
diff --git a/theme/packages/main/src/app/pages/apps/blogs/blogs.component.ts b/theme/packages/main/src/app/pages/apps/blogs/blogs.component.ts new file mode 100644 index 0000000..1065c2f --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/blogs/blogs.component.ts @@ -0,0 +1,25 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { blogService } from 'src/app/services/apps/blog/blog.service'; +import { MatCardModule } from '@angular/material/card'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatChipsModule } from '@angular/material/chips'; + +@Component({ + selector: 'app-blogs', + imports: [MatCardModule, TablerIconsModule, MatChipsModule], + templateUrl: './blogs.component.html' +}) +export class AppBlogsComponent implements OnInit { + posts = this.blogService.getBlog(); + + constructor(public router: Router, public blogService: blogService) {} + + selectBlog(title: string) { + this.blogService.selectBlogPost(title); + this.router.navigate(['apps/blog/detail', title]); + } + ngOnInit(): void { + console.log('Blog posts loaded:', this.posts); + } +} diff --git a/theme/packages/main/src/app/pages/apps/blogs/details/details.component.html b/theme/packages/main/src/app/pages/apps/blogs/details/details.component.html new file mode 100644 index 0000000..f9fd609 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/blogs/details/details.component.html @@ -0,0 +1,226 @@ + + + +@if(blogDetail()) { + + Photo of a Shiba Inu +
+ 2 mins Read +
+ +
+
+ +
+ {{ blogDetail()?.category }} +
+ + {{ blogDetail()?.title }} + +
+
+ {{ blogDetail()?.views }} + 4 +
+ + + {{ blogDetail()?.date }} + +
+
+ +

Title of the paragraph

+

+ But you cannot figure out what it is or what it can do. MTA web directory + is the simplest way in which one can bid on a link, or a few links if they + wish to do so. The link directory on MTA displays all of the links it + currently has, and does so in alphabetical order, which makes it much + easier for someone to find what they are looking for if it is something + specific and they do not want to go through all the other sites and links + as well. It allows you to start your bid at the bottom and slowly work + your way to the top of the list. +

+ +

+ Gigure out what it is or what it can do. MTA web directory is the simplest + way in which one can bid on a link, or a few links if they wish to do so. + The link directory on MTA displays all of the links it currently has, and + does so in alphabetical order, which makes it much easier for someone to + find what they are looking for if it is something specific and they do not + want to go through all the other sites and links as well. It allows you to + start your bid at the bottom and slowly work your way to the top of the +

+ +

This is strong text.

+

This is italic text.

+ + +

Unorder list.

+
    +
  • Gigure out what it is or
  • +
  • The links it currently
  • +
  • It allows you to start your bid
  • +
  • Gigure out what it is or
  • +
  • The links it currently
  • +
  • It allows you to start your bid
  • +
+ + +

Order list.

+
    +
  1. Gigure out what it is or
  2. +
  3. The links it currently
  4. +
  5. It allows you to start your bid
  6. +
  7. Gigure out what it is or
  8. +
  9. The links it currently
  10. +
  11. It allows you to start your bid
  12. +
+ + +

Quotes

+
+
+ Life is short, Smile + while you still have teeth! +
+
+
+
+} + + + + + +@if (!blogDetail() || blogDetail().length === 0) { + + +

No blog post available.

+
+
+} + + + + Post Comments +
+ + + + +
+ + Comments + 4 + + + + +
+
+ user + Charlie Hamilton + + + now + +
+

+ Jigho tabkubho nira carudi ganlac milza dekpo putog iptodok tuhral canse + mi rega ujnuf kukfag osailu bis oca. Gegeholo hata sogi kod bihdelsa + nege evinog mes loz perdutace kehlondip im fep wiven fefu fi tigfiso. +

+ + +
+ + + +
+
+ user + + + + +
+
+ + + + +
+
+ user + Ethan Gordon + + + now + +
+

+ Diprow wir hilohi ilmi fumow oc co cop iv gi ize tamiv kulok. Bam ci + urkati ul negu ovga hivwe toubugof gok imro ale sujoh saput. +

+ + +
+
+
diff --git a/theme/packages/main/src/app/pages/apps/blogs/details/details.component.ts b/theme/packages/main/src/app/pages/apps/blogs/details/details.component.ts new file mode 100644 index 0000000..ea5e6c3 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/blogs/details/details.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, signal } from '@angular/core'; +import { blogService } from 'src/app/services/apps/blog/blog.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MatCardModule } from '@angular/material/card'; +import { MatChipsModule } from '@angular/material/chips'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatButtonModule } from '@angular/material/button'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-blog-details', + imports: [ + MatCardModule, + MatChipsModule, + TablerIconsModule, + MatDividerModule, + MatFormFieldModule, + MatInputModule, + MatButtonModule, + CommonModule, + ], + templateUrl: './details.component.html', +}) +export class AppBlogDetailsComponent implements OnInit { + title = signal(null); + blogDetail = signal(null); + istoggleReply = signal(true); + activeRoute: any = this.router.url.split('/').pop(); + + constructor( + public router: Router, + activatedRouter: ActivatedRoute, + public blogService: blogService + ) { + this.title.set(activatedRouter.snapshot.paramMap.get('id')); + } + + ngOnInit(): void { + const posts = this.blogService.getBlog(); + this.blogDetail.set(posts.find((post) => post.title === this.title())); + } + toggleReply() { + this.istoggleReply.set(!this.istoggleReply()); + } +} diff --git a/theme/packages/main/src/app/pages/apps/chat/chat.component.html b/theme/packages/main/src/app/pages/apps/chat/chat.component.html new file mode 100644 index 0000000..1530c1f --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/chat/chat.component.html @@ -0,0 +1,123 @@ + + + + + + + +
+ +
+

Mathew Anderson

+ info@modernize.com +
+
+ +
+ + + + + + + +
+ + @if (filteredMessages() && filteredMessages().length > 0) { +
+ + @for(message of filteredMessages(); track message.from) { + + + + +

+ {{ message.from }} +

+

+ {{ message.subject }} +

+
+ } +
+
+ } @else { +
+ No messages found. +
+ } +
+
+ + + + + + +
+ +
+ {{ selectedMessage()?.from }} +
+
+ + + + + + +
+ + + + + + + @for(c of selectedMessage()?.chat; track c) { @if(c.type === 'odd') { +
+
+
+ + {{ c.msg }} +
+ + {{ c.date | date }} + +
+
+ } @else { +
+
+
+ {{ c.msg }} +
+ + {{ c.date | date }} + +
+
+ } } +
+
+ +
+ + + + +
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/chat/chat.component.ts b/theme/packages/main/src/app/pages/apps/chat/chat.component.ts new file mode 100644 index 0000000..e7f309c --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/chat/chat.component.ts @@ -0,0 +1,85 @@ +import { Component, signal, ViewChild } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MaterialModule } from 'src/app/material.module'; +import { ChatService } from 'src/app/services/apps/chat/chat.service'; +import { Message } from 'src/app/pages/apps/chat/chat'; + +@Component({ + selector: 'app-chat', + imports: [ + CommonModule, + NgScrollbarModule, + TablerIconsModule, + FormsModule, + ReactiveFormsModule, + MaterialModule, + ], + templateUrl: './chat.component.html', +}) +export class AppChatComponent { + sidePanelOpened = true; + //input feild for new msg + msg = signal(''); + + // MESSAGE + selectedMessage = signal(null); + + messages = signal([]); + + filteredMessages = signal([]); + + searchTerm = signal(''); + + // tslint:disable-next-line - Disables all + + constructor(private chatService: ChatService) {} + + isOver(): boolean { + return window.matchMedia(`(max-width: 960px)`).matches; + } + + ngOnInit() { + this.messages.set(this.chatService.messages()); + + this.filteredMessages.set(this.messages()); + this.selectedMessage.set(this.chatService.selectedMessage()); + + if (this.isOver()) { + // Check if the screen is small + this.sidePanelOpened = false; // Close the sidebar + } + } + + + + // tslint:disable-next-line - Disables all + selectMessage(message: Message): void { + this.selectedMessage.set(message); + + if (this.isOver()) { + // Check if the screen is small + this.sidePanelOpened = false; // Close the sidebar + } + } + + sendMessage(): void { + const currentSelectedMessage = this.selectedMessage(); + if (currentSelectedMessage) { + this.chatService.sendMessage(currentSelectedMessage, this.msg()); + this.msg.set(''); + } + } + + searchMessages(): void { + this.filteredMessages.set( + this.searchTerm().trim() + ? this.messages().filter((message) => + message.from.toLowerCase().includes(this.searchTerm().toLowerCase()) + ) + : this.messages() + ); + } +} diff --git a/theme/packages/main/src/app/pages/apps/chat/chat.ts b/theme/packages/main/src/app/pages/apps/chat/chat.ts new file mode 100644 index 0000000..a7fc2da --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/chat/chat.ts @@ -0,0 +1,7 @@ +export interface Message { + id: string; + from: string; + subject: string; + photo: string; + chat: { type: string; msg: string; date: Date }[]; + } \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/chat/chatData.ts b/theme/packages/main/src/app/pages/apps/chat/chatData.ts new file mode 100644 index 0000000..ac096aa --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/chat/chatData.ts @@ -0,0 +1,263 @@ +export const messages = [ + { + id: '1', + from: 'James Johnson', + photo: 'assets/images/profile/user-2.jpg', + subject: 'Hey, how are you?', + chat: [ + { + type: 'odd', + msg: 'Hi Luke.', + date: new Date('2025-01-05'), + }, + { + type: 'odd', + msg: 'How are you my friend?', + date: new Date('2025-01-06'), + }, + { + type: 'even', + msg: 'I am good and what about you?', + date: new Date('2025-01-07'), + }, + { + type: 'odd', + msg: 'Lorem Ipsum is simply dummy text of the printing & type setting industry.', + date: new Date('2025-01-08'), + }, + { + type: 'even', + msg: 'I would love to join the team.', + date: new Date('2025-01-09'), + }, + { + type: 'odd', + msg: 'Well we have good budget for the project.', + date: new Date('2025-01-10'), + }, + ], + }, + { + id: '2', + from: 'Maria Hernandez', + photo: 'assets/images/profile/user-3.jpg', + subject: 'Lorem ipsum done', + chat: [ + { + type: 'odd', + msg: 'this is odd2', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even2', + date: new Date('2025-01-10'), + }, + { + type: 'odd', + msg: 'Simply dummy text of the printing & type setting industry.', + date: new Date('2025-01-08'), + }, + { + type: 'even', + msg: 'Love to join the team.', + date: new Date('2025-01-09'), + }, + { + type: 'odd', + msg: 'Have good budget for the project.', + date: new Date('2025-01-10'), + }, + ], + }, + { + id: '3', + from: 'David Smith', + photo: 'assets/images/profile/user-4.jpg', + subject: 'Thanks mate', + chat: [ + { + type: 'odd', + msg: 'Hi Luke.', + date: new Date('2025-01-05'), + }, + { + type: 'odd', + msg: 'How are you my friend?', + date: new Date('2025-01-06'), + }, + { + type: 'even', + msg: 'I am good and what about you?', + date: new Date('2025-01-07'), + }, + { + type: 'odd', + msg: 'Lorem Ipsum is simply dummy text of the printing & type setting industry.', + date: new Date('2025-01-08'), + }, + { + type: 'even', + msg: 'I would love to join the team.', + date: new Date('2025-01-09'), + }, + { + type: 'odd', + msg: 'Well we have good budget for the project.', + date: new Date('2025-01-10'), + }, + ], + }, + { + id: '4', + from: 'Maria Rodriguez', + photo: 'assets/images/profile/user-5.jpg', + subject: 'This is my shot', + chat: [ + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + ], + }, + { + id: '5', + from: 'Robert Smith', + photo: 'assets/images/profile/user-6.jpg', + subject: 'You have to do it..', + chat: [ + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + ], + }, + { + id: '6', + from: 'Joseph Sarah', + photo: 'assets/images/profile/user-7.jpg', + subject: 'No mate this is not', + chat: [ + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + ], + }, + { + id: '7', + from: 'Thomas Smith', + photo: 'assets/images/profile/user-8.jpg', + subject: 'How are you my friend?', + chat: [ + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + { + type: 'odd', + msg: 'this is odd', + date: new Date('2025-01-10'), + }, + { + type: 'even', + msg: 'this is even', + date: new Date('2025-01-10'), + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/contact-list/contact-form-dialog/contact-form-dialog.component.html b/theme/packages/main/src/app/pages/apps/contact-list/contact-form-dialog/contact-form-dialog.component.html new file mode 100644 index 0000000..d95fa50 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/contact-form-dialog/contact-form-dialog.component.html @@ -0,0 +1,133 @@ + + + + +
+

Add New Contact

+ +
+ +
+
+ @if(imageUrl){ + Selected Image + } + +
+ +
+
+ First Name + + + +
+
+ Last Name + + + +
+
+ Company Name + + + +
+
+ Phone Number + + + +
+
+ Email + + + +
+
+ Address + + + +
+
+ Notes + + + +
+
+ Department + + + @for(dept of departments; track dept.id) { + {{ dept.name }} + } + + +
+
+
+
+
+ + +
diff --git a/theme/packages/main/src/app/pages/apps/contact-list/contact-form-dialog/contact-form-dialog.component.ts b/theme/packages/main/src/app/pages/apps/contact-list/contact-form-dialog/contact-form-dialog.component.ts new file mode 100644 index 0000000..21798ff --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/contact-form-dialog/contact-form-dialog.component.ts @@ -0,0 +1,81 @@ +import { Component } from '@angular/core'; +import { MatDialogRef } from '@angular/material/dialog'; +import { MaterialModule } from 'src/app/material.module'; +import { FormsModule } from '@angular/forms'; +import { CommonModule } from '@angular/common'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-contact-form-dialog', + templateUrl: './contact-form-dialog.component.html', + imports: [MaterialModule, CommonModule, FormsModule, TablerIconsModule], +}) +export class ContactFormDialogComponent { + contact = { + firstname: '', + lastname: '', + image: '', + company: '', + phone: '', + email: '', + address: '', + notes: '', + department: '', + }; + departments = [ + { id: 1, name: 'Support' }, + { id: 2, name: 'Engineering' }, + { id: 3, name: 'Sales' }, + ]; + + defaultImageUrl = 'assets/images/profile/user-4.jpg'; + imageUrl: string | ArrayBuffer | null = this.defaultImageUrl; + + constructor( + public dialogRef: MatDialogRef, + private snackBar: MatSnackBar + ) {} + + saveContact(): void { + this.contact.image = this.imageUrl as string; + this.dialogRef.close(this.contact); + this.snackBar.open( + `${this.contact.firstname} ${this.contact.lastname} added successfully!`, + 'Close', + { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + } + ); + } + + cancel(): void { + this.dialogRef.close(); + } + + onFileSelected(event: Event): void { + const file = (event.target as HTMLInputElement).files?.[0]; + + if (file) { + const reader = new FileReader(); + reader.onload = () => { + this.imageUrl = reader.result; + }; + reader.readAsDataURL(file); + } + } + + isFormValid(): any { + return ( + this.contact.firstname && + this.contact.lastname && + this.contact.company && + this.contact.phone && + this.contact.email && + this.contact.address && + this.contact.department + ); + } +} diff --git a/theme/packages/main/src/app/pages/apps/contact-list/contact-list.component.html b/theme/packages/main/src/app/pages/apps/contact-list/contact-list.component.html new file mode 100644 index 0000000..c0395f8 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/contact-list.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/theme/packages/main/src/app/pages/apps/contact-list/contact-list.component.ts b/theme/packages/main/src/app/pages/apps/contact-list/contact-list.component.ts new file mode 100644 index 0000000..112120d --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/contact-list.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { AppListingComponent } from 'src/app/pages/apps/contact-list/listing/listing.component'; +import { MaterialModule } from 'src/app/material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-contact-list', + imports: [AppListingComponent, TablerIconsModule, MaterialModule], + templateUrl: './contact-list.component.html', +}) +export class AppContactListComponent {} diff --git a/theme/packages/main/src/app/pages/apps/contact-list/contact-list.ts b/theme/packages/main/src/app/pages/apps/contact-list/contact-list.ts new file mode 100644 index 0000000..03e9a1b --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/contact-list.ts @@ -0,0 +1,17 @@ +export class ContactBox { + constructor( + public id: number | string, + public firstname: string, + public lastname: string, + public image: string, + public department: string, + public company: string, + public phone: string, + public email: string, + public address: string, + public notes: string, + public frequentlycontacted: boolean, + public starred: boolean, + public deleted: boolean, + ){} + } diff --git a/theme/packages/main/src/app/pages/apps/contact-list/contactlistData.ts b/theme/packages/main/src/app/pages/apps/contact-list/contactlistData.ts new file mode 100644 index 0000000..5e523ec --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/contactlistData.ts @@ -0,0 +1,471 @@ +import { ContactBox } from './contact-list'; +import { Chance } from 'chance'; + +const chance = new Chance(); + +export const ContactList: ContactBox[] = [ + { + id: 1, + firstname: 'Georgeanna', + lastname: 'Ramero', + image: 'assets/images/profile/user-4.jpg', + department: 'Sales', + company: 'Muller Inc', + phone: '456-485-5623', + email: 'qq739v47ggn@claimab.com', + address: '19214 110th Rd, Saint Albans, NY, 1141', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: true, + deleted: false, + }, + + { + id: 2, + firstname: 'Cami', + lastname: 'Macha', + image: 'assets/images/profile/user-3.jpg', + department: 'Support', + company: 'Zboncak LLC', + phone: '999-895-9652', + email: 'Camisad@claimab.com', + address: '76 Hamilton Ave, Yonkers, NY, 10705', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: false, + deleted: false, + }, + { + id: 3, + firstname: 'Alda', + lastname: 'Ziemer', + image: 'assets/images/profile/user-4.jpg', + department: 'Engineering', + company: 'Lehner-Jacobson', + phone: '789-854-8950', + email: 'Ziemer234@claimab.com', + address: '930 Fruit Ave, Farrell, PA, 16121', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: false, + deleted: false, + }, + { + id: 4, + firstname: 'Luciano', + lastname: 'Macpherson', + image: 'assets/images/profile/user-5.jpg', + department: 'Support', + company: 'Champlin', + phone: '452-652-5230', + email: 'Macpherson34@claimab.com', + address: '19103 Stefani Ave, Cerritos, CA, 90703', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: true, + deleted: true, + }, + { + id: 5, + firstname: 'Dalton', + lastname: 'Paden', + image: 'assets/images/profile/user-6.jpg', + department: 'Engineering', + company: 'Balistreri', + phone: '985-985-7850', + email: 'Dalton321@claimab.com', + address: '3059 Edgewood Park Ct, Commerce Township', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: false, + deleted: false, + }, + { + id: 6, + firstname: 'Juan', + lastname: 'Granado', + image: 'assets/images/profile/user-7.jpg', + department: 'Support', + company: 'Bernier-Ankunding', + phone: '230-541-5231', + email: 'Granado567@claimab.com', + address: '1330 N Douglas Ave, Arlington Heights', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: false, + deleted: true, + }, + { + id: 7, + firstname: 'Reva', + lastname: 'Allen', + image: 'assets/images/profile/user-8.jpg', + department: 'Support', + company: 'Rosenbaum Inc', + phone: '478-582-6520', + email: 'Allen326@claimab.com', + address: '180 Topp Ln, Tupelo, MS', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: false, + deleted: true, + }, + { + id: 8, + firstname: 'Jule', + lastname: 'Huseman', + image: 'assets/images/profile/user-9.jpg', + department: 'Sales', + company: 'Smith-Romaguera', + phone: '123-652-2301', + email: 'Huseman458@claimab.com', + address: '33 Caraway Rd, Reisterstown, MD', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: true, + deleted: true, + }, + { + id: 9, + firstname: 'Bridgette', + lastname: 'Phung', + image: 'assets/images/profile/user-10.jpg', + department: 'Engineering', + company: 'Corwin-Kassulke', + phone: '652-452-6521', + email: 'Bridgette890@claimab.com', + address: '#RR, Bruceton Mills, WV', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: true, + deleted: true, + }, + { + id: 10, + firstname: 'Ernest', + lastname: 'Cousins', + image: 'assets/images/profile/user-2.jpg', + department: 'Support', + company: 'Homenick-Hartmann', + phone: '785-985-6541', + email: 'Ernest6543@claimab.com', + address: 'Michael I. Days 3756 Preston Street Wichita', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: false, + deleted: true, + }, + { + id: 11, + firstname: 'Nicolette', + lastname: 'Trapani', + image: 'assets/images/profile/user-3.jpg', + department: 'Engineering', + company: 'Gleason', + phone: '652-632-6520', + email: 'Nicoletteesdasd4@claimab.com', + address: 'Carol J. Stephens 1635 Franklin Street Montgomery', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: false, + deleted: true, + }, + { + id: 12, + firstname: 'Virginia', + lastname: 'Bourdeau', + image: 'assets/images/profile/user-4.jpg', + department: 'Support', + company: 'McKenzie and Sons', + phone: '125-985-3210', + email: 'Bourdeauerwe@claimab.com', + address: 'Donald M. Palmer 2595 Pearlman Avenue', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: false, + deleted: false, + }, + { + id: 13, + firstname: 'Janita', + lastname: 'Vogl', + image: 'assets/images/profile/user-5.jpg', + department: 'Sales', + company: 'Erdman-Moen', + phone: '541-521-6320', + email: 'Janitafdaa@claimab.com', + address: 'Micheal R. Porterfield 508 Virginia Street', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: true, + deleted: false, + }, + { + id: 14, + firstname: 'Jeneva', + lastname: 'Bridgeforth', + image: 'assets/images/profile/user-6.jpg', + department: 'Engineering', + company: 'Fay LLC', + phone: '975-895-5240', + email: 'Bridgeforth564@claimab.com', + address: 'Nathan K. Flores 1516 Holt Street West Palm', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: true, + deleted: false, + }, + { + id: 15, + firstname: 'Roselia', + lastname: 'Principe', + image: 'assets/images/profile/user-8.jpg', + department: 'Sales', + company: 'Bode-Oberbrunner', + phone: '874-546-6521', + email: 'Principe326@claimab.com', + address: '2915 Auburn Creek LnLeague City', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: true, + deleted: false, + }, + { + id: 16, + firstname: 'Elvira', + lastname: 'Hylton', + image: 'assets/images/profile/user-7.jpg', + department: 'Support', + company: 'Pagac Group', + phone: '652-542-5200', + email: 'Elviraoknsss@claimab.com', + address: '2725 Cottage Rd Alpine', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: false, + deleted: false, + }, + { + id: 17, + firstname: 'Maragaret', + lastname: 'Pecor', + image: 'assets/images/profile/user-10.jpg', + department: 'Sales', + company: 'Predovic and Sons', + phone: '326-984-1200', + email: 'Maragaret4352@mediafire.com', + address: '307 Hardy St Aberdeen', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: true, + deleted: false, + }, + { + id: 18, + firstname: 'Willena', + lastname: 'Sugrue', + image: 'assets/images/profile/user-2.jpg', + department: 'Support', + company: 'Graham Group', + phone: '265-632-4521', + email: 'Willena75637@claimab.com', + address: '15919 Golf Club Dr Crosby', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: true, + deleted: false, + }, + { + id: 19, + firstname: 'Eura', + lastname: 'Solley', + image: 'assets/images/profile/user-3.jpg', + department: 'Sales', + company: 'Toy-Ryan', + phone: '645-647-4800', + email: 'Solley6472@claimab.com', + address: 'Po Box 144 Rhome', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: false, + deleted: true, + }, + { + id: 20, + firstname: 'Velva', + lastname: 'Brockett', + image: 'assets/images/profile/user-4.jpg', + department: 'Support', + company: 'Walsh Ltd', + phone: '654-985-6520', + email: 'Brocketterewgdb@claimab.com', + address: '34 Fairview Ln Palm Coast', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: true, + deleted: true, + }, + { + id: 21, + firstname: 'Anya', + lastname: 'Snapp', + image: 'assets/images/profile/user-5.jpg', + department: 'Support', + company: 'Romaguera Inc', + phone: '456-652-3210', + email: 'Snapp76848@claimab.com', + address: '17919 Barney Dr Accokeek', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: false, + deleted: false, + }, + { + id: 22, + firstname: 'Latoria', + lastname: 'Penaloza', + image: 'assets/images/profile/user-6.jpg', + department: 'Engineering', + company: 'Leuschke', + phone: '459-985-4520', + email: 'Penaloza3546@claimab.com', + address: '14 Huntington Dr Greenbrier', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: false, + deleted: true, + }, + { + id: 23, + firstname: 'Tamika', + lastname: 'Inman', + image: 'assets/images/profile/user-7.jpg', + department: 'Sales', + company: 'Schumm', + phone: '645-978-4150', + email: 'Tamikadfdf45@claimab.com', + address: '1341 Mentionville Rd Darien', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: false, + deleted: true, + }, + { + id: 24, + firstname: 'Erich', + lastname: 'Aragon', + image: 'assets/images/profile/user-8.jpg', + department: 'Business Development', + company: 'Brakus', + phone: '450-980-6520', + email: 'Aragondfdf4567@claimab.com', + address: '13 Pent Rd Branford', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: false, + deleted: true, + }, + { + id: 25, + firstname: 'Johanna', + lastname: 'Randel', + image: 'assets/images/profile/user-9.jpg', + department: 'Sales', + company: 'Goyette', + phone: '120-320-4520', + email: 'Johanna456@claimab.com', + address: '5791 S Staghorn Cholla Ct Apache Junction', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: true, + deleted: true, + }, + { + id: 26, + firstname: 'Victorina', + lastname: 'Heinze', + image: 'assets/images/profile/user-10.jpg', + department: 'Business Development', + company: 'Fritsch', + phone: '452-521-1230', + email: 'Victorina4545@claimab.com', + address: '69 El Molino Dr Clayton', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: false, + deleted: true, + }, + { + id: 27, + firstname: 'Kiley', + lastname: 'Light', + image: 'assets/images/profile/user-8.jpg', + department: 'Sales', + company: 'Langosh', + phone: '652-452-1230', + email: 'Kileydfdfd45@claimab.com', + address: '215 Waterfront Ct Noblesville', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: true, + deleted: false, + }, + { + id: 28, + firstname: 'Sanford', + lastname: 'Delorenzo', + image: 'assets/images/profile/user-3.jpg', + department: 'Engineering', + company: 'Huels', + phone: '963-652-1230', + email: 'Delorenzo3456@claimab.com', + address: '11212 Amber Rd Manistee', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: true, + starred: true, + deleted: false, + }, + { + id: 29, + firstname: 'Hans', + lastname: 'Strebel', + image: 'assets/images/profile/user-4.jpg', + department: 'Sales', + company: 'Kohler', + phone: '546-654-1230', + email: 'Strebel345@claimab.com', + address: '2009 W Azalea Ave Baker', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: false, + deleted: false, + }, + { + id: 30, + firstname: 'Roger', + lastname: 'Trinidad', + image: 'assets/images/profile/user-5.jpg', + department: 'Sales', + company: 'Kling-Hintz', + phone: '123-456-7890', + email: '3mcrz8gmymd@claimab.com', + address: '203 Dawn Dr, Mount Holly, NC, 28120', + notes: chance.paragraph({ sentences: 2 }), + frequentlycontacted: false, + starred: true, + deleted: true, + }, +]; +export default ContactList; + +export function getUser(id: string): ContactBox | null { + // tslint:disable-next-line: no-shadowed-variable + const u = ContactList.find((u) => { + return u.id === id; + }); + + if (u === undefined) { + return null; + } + return u; +} diff --git a/theme/packages/main/src/app/pages/apps/contact-list/delete-dialog/delete-dialog.component.html b/theme/packages/main/src/app/pages/apps/contact-list/delete-dialog/delete-dialog.component.html new file mode 100644 index 0000000..699d51d --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/delete-dialog/delete-dialog.component.html @@ -0,0 +1,17 @@ + + + +

Confirmation

+
+

{{ data.message }}

+
+
+ + +
diff --git a/theme/packages/main/src/app/pages/apps/contact-list/delete-dialog/delete-dialog.component.ts b/theme/packages/main/src/app/pages/apps/contact-list/delete-dialog/delete-dialog.component.ts new file mode 100644 index 0000000..231bfcc --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/delete-dialog/delete-dialog.component.ts @@ -0,0 +1,28 @@ +import { Component, Inject } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; + +import { + MatDialog, + MatDialogRef, + MAT_DIALOG_DATA, +} from '@angular/material/dialog'; +@Component({ + selector: 'app-delete-dialog', + imports: [MatButtonModule, MatDialogModule], + templateUrl: './delete-dialog.component.html', +}) +export class AppDeleteDialogComponent { + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: { message: string } + ) {} + + onConfirm(): void { + this.dialogRef.close(true); + } + + onCancel(): void { + this.dialogRef.close(false); + } +} diff --git a/theme/packages/main/src/app/pages/apps/contact-list/detail/detail.component.html b/theme/packages/main/src/app/pages/apps/contact-list/detail/detail.component.html new file mode 100644 index 0000000..0d70495 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/detail/detail.component.html @@ -0,0 +1,239 @@ +
+ + + + @if( selectedContact()) { +
+
Contact Details
+ + +
+ + + +
+
+ } + + + + + + + @if(selectedContact()) { + + @if(!isEditing() && contact()) { +
+
+ userimg +
+
+ {{ contact().firstname }} +
+ + {{ contact().department }} + + + {{ contact().company }} + +
+
+
+
+ Phone Number +
+ {{ contact().phone }} +
+
+
+ Email address +
+ {{ contact().email }} +
+
+
+ Address +
+ {{ contact().address }} +
+
+
+ Department +
+ {{ contact().department }} +
+
+
+ Company +
+ {{ contact().company }} +
+
+
+ Notes +
{{ contact().notes }}
+
+
+
+ +
+ + +
+ + } + + + + + @else { +
+
+
+
+ First Name + + + + Last Name + + + + Company + + + + Phone + + + + Email + + + + Address + + + + Notes + + + + Department + + + @for ( department of departments; track department) { + + {{ department.name }} + + } + + +
+ + +
+
+
+
+
+ } +
+ } +
diff --git a/theme/packages/main/src/app/pages/apps/contact-list/detail/detail.component.ts b/theme/packages/main/src/app/pages/apps/contact-list/detail/detail.component.ts new file mode 100644 index 0000000..8ff80e1 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/detail/detail.component.ts @@ -0,0 +1,90 @@ +import { Component, computed, OnInit, signal } from '@angular/core'; +import { MatDividerModule } from '@angular/material/divider'; +import { FormsModule } from '@angular/forms'; +import { CommonModule } from '@angular/common'; +import { ContactService } from 'src/app/services/apps/contact-list/contact-list.service'; +import { AppDeleteDialogComponent } from '../delete-dialog/delete-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; +import { ContactBox } from 'src/app/pages/apps/contact-list/contact-list'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +@Component({ + selector: 'app-detail', + imports: [ + MatDividerModule, + FormsModule, + CommonModule, + MaterialModule, + TablerIconsModule, + NgScrollbarModule, + ], + templateUrl: './detail.component.html', +}) +export class AppContactListDetailComponent implements OnInit { + isEditing = signal(false); + contact = signal(null); + formData = signal(null); + selectedContact = computed(() => this.contactService.getSelectedContact()); + + constructor( + public dialog: MatDialog, + private contactService: ContactService, + private snackBar: MatSnackBar + ) {} + + departments = [ + { id: 1, name: 'Sales' }, + { id: 2, name: 'Support' }, + { id: 2, name: 'Engineering' }, + ]; + + ngOnInit(): void { + this.contactService.selectedContact$.subscribe((contact) => { + this.contact.set(contact); + this.formData.set(contact ? { ...contact } : null); + }); + } + + toggleStarred(contact: ContactBox, event: Event): void { + this.contactService.toggleStarred(contact, event); + this.contactService.updateContact(contact); + } + + saveContact(): void { + const contact = this.formData(); + if (contact) { + this.contactService.updateContact(contact); + this.isEditing.set(false); + } + } + + track(department: any) { + return department.id; + } + + editContact(): void { + this.isEditing.set(true); + } + + cancelEdit(): void { + this.isEditing.set(false); + this.formData.set(this.contact() ? { ...this.contact() } : null); + } + + deleteContact(contact: ContactBox): void { + const dialogRef = this.dialog.open(AppDeleteDialogComponent, { + width: '300px', + data: { + message: `Are you sure you want to delete ${contact.firstname} ${contact.lastname}?`, + }, + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result) { + this.contactService.deleteContact(contact); + } + }); + } +} diff --git a/theme/packages/main/src/app/pages/apps/contact-list/listing/categories.ts b/theme/packages/main/src/app/pages/apps/contact-list/listing/categories.ts new file mode 100644 index 0000000..0f5804f --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/listing/categories.ts @@ -0,0 +1,61 @@ +export interface Category { + id: number; + name: string; + icon: string; + count: number; + color?: string; + active: boolean; + frequentlycontacted?: boolean; + starred?: boolean; +} + +export const filter = [ + { + id: 1, + name: 'All', + icon: 'mail', + count: 0, + active: true, + }, + { + id: 2, + name: 'Frequent', + icon: 'send', + count: 0, + active: false, + }, + { + id: 3, + name: 'Starred', + icon: 'note', + count: 0, + active: false, + }, +]; + +export const label: Category[] = [ + { + id: 701, + name: 'Engineering', + icon: 'folder', + count: 0, + color: '#5D87FF', + active: false, + }, + { + id: 702, + name: 'Support', + icon: 'folder', + count: 0, + color: '#49BEFF', + active: false, + }, + { + id: 703, + name: 'Sales', + icon: 'folder', + count: 0, + color: '#FA896B', + active: false, + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/contact-list/listing/listing.component.html b/theme/packages/main/src/app/pages/apps/contact-list/listing/listing.component.html new file mode 100644 index 0000000..ca8f450 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/listing/listing.component.html @@ -0,0 +1,224 @@ + + + + + +
+ + + + +
+ + +
diff --git a/theme/packages/main/src/app/pages/apps/contact-list/listing/listing.component.ts b/theme/packages/main/src/app/pages/apps/contact-list/listing/listing.component.ts new file mode 100644 index 0000000..8de829d --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact-list/listing/listing.component.ts @@ -0,0 +1,231 @@ +import { + ChangeDetectorRef, + Component, + computed, + inject, + OnDestroy, + OnInit, + signal, +} from '@angular/core'; +import { Category, filter, label } from './categories'; +import { AppContactListDetailComponent } from '../detail/detail.component'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { ContactFormDialogComponent } from '../contact-form-dialog/contact-form-dialog.component'; +import { MaterialModule } from 'src/app/material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { ContactService } from 'src/app/services/apps/contact-list/contact-list.service'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +import { ContactBox } from 'src/app/pages/apps/contact-list/contact-list'; + +import { AppDeleteDialogComponent } from '../delete-dialog/delete-dialog.component'; +import { AppSearchDialogComponent } from 'src/app/layouts/full/vertical/header/header.component'; +import { CommonModule } from '@angular/common'; +import { MatDividerModule } from '@angular/material/divider'; + +@Component({ + selector: 'app-listing', + imports: [ + CommonModule, + FormsModule, + AppContactListDetailComponent, + MaterialModule, + ReactiveFormsModule, + TablerIconsModule, + NgScrollbarModule, + CommonModule, + MatDividerModule, + ], + templateUrl: './listing.component.html', +}) +export class AppListingComponent implements OnInit, OnDestroy { + mobileQuery: MediaQueryList; + + private _mobileQueryListener: () => void; + + constructor( + public dialog: MatDialog, + public contactService: ContactService, + private snackBar: MatSnackBar + ) { + const changeDetectorRef = inject(ChangeDetectorRef); + const media = inject(MediaMatcher); + this.mobileQuery = media.matchMedia('(max-width: 600px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + } + + ngOnDestroy(): void { + this.mobileQuery.removeListener(this._mobileQueryListener); + } + + searchTerm = signal(''); + private mediaMatcher: MediaQueryList = matchMedia(`(max-width: 1199px)`); + filters: Category[] = []; + labels: Category[] = []; + selectedFilter: Category | null = null; + selectedCategory: Category | null = null; + selectedContact = signal(null); + isActiveContact: boolean = false; + + mailnav = true; + + isOver(): boolean { + return this.mediaMatcher.matches; + } + + openDialog() { + const dialogRef = this.dialog.open(AppSearchDialogComponent, { + autoFocus: false, + }); + + dialogRef.afterClosed().subscribe((result) => { + console.log(`Dialog result: ${result}`); + }); + } + + filteredContacts = computed(() => { + let filtered = this.contactService.contactList(); + + // Apply category filter if selected + if ( + this.contactService.selectedCategory() && + this.contactService.selectedCategory()?.name !== 'All' + ) { + filtered = filtered.filter( + (contact) => + contact.department === this.contactService.selectedCategory()?.name + ); + } + + // Apply filter based on selectedFilter only if no category is selected + if ( + !this.contactService.selectedCategory() || + this.contactService.selectedCategory()?.name === 'All' + ) { + if (this.contactService.selectedFilter()) { + if (this.contactService.selectedFilter()?.name === 'Frequent') { + filtered = filtered.filter((contact) => contact.frequentlycontacted); + } else if (this.contactService.selectedFilter()?.name === 'Starred') { + filtered = filtered.filter((contact) => contact.starred); + } + } + } + + // Apply search term filter + const searchTermLower = this.searchTerm().toLowerCase(); + filtered = filtered.filter( + (contact) => + contact.firstname.toLowerCase().includes(searchTermLower) || + contact.lastname.toLowerCase().includes(searchTermLower) + ); + return filtered; + }); + + ngOnInit() { + // Set up the data after the service has been initialized + + this.filters = this.contactService.filters(); + this.labels = this.contactService.labels(); + this.selectedFilter = this.contactService.selectedFilter(); + this.selectedCategory = this.contactService.selectedCategory(); + + this.contactService.contactList.set(this.contactService.contactList()); + + // Set the selected contact to the first contact if available + const contacts = this.contactService.contactList(); + this.selectedContact.set(contacts[0]); + + // Initialize labels and filters from the data file + this.contactService.labels.set(label); + this.contactService.filters.set(filter); + + // Set the first filter as active by default + const firstFilter = this.contactService.filters()[0]; + if (firstFilter) { + this.contactService.selectedFilter.set(firstFilter); + this.contactService.filters.set( + this.contactService + .filters() + .map((f) => ({ ...f, active: f === firstFilter })) + ); + } + } + + goBack() { + this.selectedContact.set(null); + this.isActiveContact = false; + } + selectContact(contact: ContactBox): void { + this.isActiveContact = true; + this.selectedContact.set(contact); + this.contactService.setSelectedContact(contact); + } + + applyFilter(filter: Category): void { + this.contactService.applyFilter(filter); + } + + applyCategory(category: Category): void { + this.contactService.applyCategory(category); + } + + toggleStarred(contact: ContactBox, $event: any): void { + this.contactService.toggleStarred(contact, $event); + } + + deleteContact(contact: ContactBox): void { + const dialogRef = this.dialog.open(AppDeleteDialogComponent, { + width: '300px', + autoFocus: false, + data: { + message: `Are you sure you want to delete ${contact.firstname} ${contact.lastname}?`, + }, + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result) { + // Delete the contact + this.contactService.deleteContact(contact); + // Check if the deleted contact was selected and clear selection if so + if ( + this.selectedContact() && + this.selectedContact()?.id === contact.id + ) { + this.contactService.setSelectedContact(null); + this.selectedContact.set(null); + } + this.snackBar.open( + `${contact.firstname} ${contact.lastname} deleted successfully!`, + 'Close', + { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + } + ); + } + }); + } + + openAddContactDialog(): void { + const dialogRef = this.dialog.open(ContactFormDialogComponent, { + width: '400px', + autoFocus: false, + }); + dialogRef.afterClosed().subscribe((result) => { + if (result) { + this.contactService.contactList.set([ + result, + ...this.contactService.contactList(), + ]); + + this.contactService.setSelectedContact(result); + this.selectedContact.set(result); + } + }); + } +} diff --git a/theme/packages/main/src/app/pages/apps/contact/contact-dialog-content.html b/theme/packages/main/src/app/pages/apps/contact/contact-dialog-content.html new file mode 100644 index 0000000..4452f3e --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact/contact-dialog-content.html @@ -0,0 +1,143 @@ + +
+

Add New Contact

+ +
+ +
+ Upload Image +
+ @if(local_data.contactimg){ + Selected Image + } + +
+ Name + + + + Post + + + Web Designer + Theme Designer + Front End Developer + Hacker + Back End Developer + Graphics Designer + + + + Address + + + + + Contact Number + + + + +
+
+ Instagram Followers + + + +
+
+ Linkedin Followers + + + +
+
+ Facebook Followers + + + +
+
+
+
+ + + + + diff --git a/theme/packages/main/src/app/pages/apps/contact/contact.component.html b/theme/packages/main/src/app/pages/apps/contact/contact.component.html new file mode 100644 index 0000000..f17aae4 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact/contact.component.html @@ -0,0 +1,88 @@ + + +
+
+ + + + + + + @if(contacts().length === 0){ +

No contacts available.

+ } +
+
+ +
+
+
+
+ +
+ @for(contact of contacts(); track contact.contactname ) { +
+ + + +
+
+

+ {{ contact.contactname }} +

+ {{ contact.contactpost }} +
+
+ + +
+ {{ contact.contactadd }} + Mo: {{ contact.contactno }} +
+
+ + +
+
+ } +
diff --git a/theme/packages/main/src/app/pages/apps/contact/contact.component.ts b/theme/packages/main/src/app/pages/apps/contact/contact.component.ts new file mode 100644 index 0000000..3f77d51 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact/contact.component.ts @@ -0,0 +1,167 @@ +import { Component, OnInit, Inject, Optional, signal } from '@angular/core'; +import { + MatDialog, + MatDialogRef, + MAT_DIALOG_DATA, +} from '@angular/material/dialog'; +import { Contact } from './contact'; +import { ContactService } from 'src/app/services/apps/contact/contact.service'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +export interface ContactData { + contacts: Contact[]; + searchText: any; + Contactname: string; + ContactPost: string; + Contactadd: string; + Contactno: string; + Contactinstagram: string; + Contactlinkedin: string; + Contactfacebook: string; +} + +@Component({ + templateUrl: './contact.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + CommonModule, + ], +}) +export class AppContactComponent implements OnInit { + Contactname = signal(''); + ContactPost = signal(''); + Contactadd = signal(''); + Contactno = signal(''); + Contactinstagram = signal(''); + Contactlinkedin = signal(''); + Contactfacebook = signal(''); + + contacts = signal([]); + searchText = signal(''); + + constructor( + public dialog: MatDialog, + private contactService: ContactService, + private snackBar: MatSnackBar + ) {} + + ngOnInit(): void { + this.contacts.set(this.contactService.getContacts()); + } + + openDialog(action: string, obj: any): void { + obj.action = action; + const dialogRef = this.dialog.open(AppContactDialogContentComponent, { + data: obj, + autoFocus: false + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result.event === 'Add') { + this.addContact(result.data); + } + }); + } + + applyFilter(event: Event): void { + const filterValue = (event.target as HTMLInputElement).value; + this.searchText.set(filterValue); + this.contacts.set(this.contactService.filterContacts(filterValue)); + } + + addContact(row_obj: any): void { + const newContact: Contact = { + contactimg: row_obj.contactimg || 'assets/images/profile/user-1.jpg', + contactname: row_obj.Contactname, + contactpost: row_obj.ContactPost, + contactadd: row_obj.Contactadd, + contactno: row_obj.Contactno, + contactinstagram: row_obj.Contactinstagram, + contactlinkedin: row_obj.Contactlinkedin, + contactfacebook: row_obj.Contactfacebook, + }; + + this.contactService.addContact(newContact); + this.contacts.set(this.contactService.getContacts()); + + this.snackBar.open('New contact added successfully!', 'Close', { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } +} + +@Component({ + selector: 'app-dialog-content', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + CommonModule, + TablerIconsModule, + ], + templateUrl: 'contact-dialog-content.html', +}) +export class AppContactDialogContentComponent { + action: string; + + local_data: ContactData | any; + selectedFile: File | null = null; + + constructor( + public dialogRef: MatDialogRef, + + @Optional() @Inject(MAT_DIALOG_DATA) public data: ContactData + ) { + this.local_data = { ...data }; + this.action = this.local_data.action; + } + + doAction(): void { + // Set the selected image data to local_data before closing + this.local_data.contactimg = this.selectedFile + ? URL.createObjectURL(this.selectedFile) + : null; + this.dialogRef.close({ event: this.action, data: this.local_data }); + } + + closeDialog(): void { + this.dialogRef.close({ event: 'Cancel' }); + } + + validateNumber(event: Event): void { + const input = event.target as HTMLInputElement; + const value = input.value; + + // Check if the input contains non-digit characters + if (/[^0-9]/.test(value)) { + alert('Please enter only digits.'); + input.value = value.replace(/[^0-9]/g, ''); + this.local_data[input.name] = input.value; + } else { + this.local_data[input.name] = value; // Update model with valid input + } + } + + onFileSelected(event: Event): void { + const input = event.target as HTMLInputElement; + if (input.files && input.files.length > 0) { + this.selectedFile = input.files[0]; + const reader = new FileReader(); + + reader.onload = (e) => { + this.local_data.contactimg = e.target?.result as string; // Set the preview image + }; + + reader.readAsDataURL(this.selectedFile); // Convert file to base64 string + } + } +} diff --git a/theme/packages/main/src/app/pages/apps/contact/contact.ts b/theme/packages/main/src/app/pages/apps/contact/contact.ts new file mode 100644 index 0000000..da8a1e1 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact/contact.ts @@ -0,0 +1,10 @@ +export interface Contact { + contactimg: string; + contactname: string; + contactpost: string; + contactadd: string; + contactno: string; + contactinstagram: string; + contactlinkedin: string; + contactfacebook: string; +} diff --git a/theme/packages/main/src/app/pages/apps/contact/contactData.ts b/theme/packages/main/src/app/pages/apps/contact/contactData.ts new file mode 100644 index 0000000..7e3159c --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/contact/contactData.ts @@ -0,0 +1,64 @@ +import { Contact } from './contact'; + +export const contactList: Contact[] = [ + { + contactimg: 'assets/images/profile/user-2.jpg', + contactname: 'Johnathan Doe', + contactpost: 'Web Designer', + contactadd: '795 Folsom Ave, Suite 600 San Francisco, NY, 10003', + contactno: '(123) 456-7890', + contactinstagram: '254', + contactlinkedin: '54', + contactfacebook: '154', + }, + { + contactimg: 'assets/images/profile/user-8.jpg', + contactname: 'Oliver Smith', + contactpost: 'Theme Designer', + contactadd: '55 E 11th St #1OTH, Suite 600 New York, NY, 10003 ', + contactno: '(212) 228-8403', + contactinstagram: '150', + contactlinkedin: '14', + contactfacebook: '165', + }, + { + contactimg: 'assets/images/profile/user-4.jpg', + contactname: 'George Johnson', + contactpost: 'Front End Developer', + contactadd: '36 W 138th St, San Francisco New York, NY, 10037', + contactno: '(212) 234-0783', + contactinstagram: '300', + contactlinkedin: '65', + contactfacebook: '130', + }, + { + contactimg: 'assets/images/profile/user-5.jpg', + contactname: 'Harry Potter', + contactpost: 'Hacker', + contactadd: '2289 5th Ave, Suite 600 San Francisco New York, NY, 10037', + contactno: '(212) 456-8403', + contactinstagram: '220', + contactlinkedin: '38', + contactfacebook: '178', + }, + { + contactimg: 'assets/images/profile/user-6.jpg', + contactname: 'Jack Williams', + contactpost: 'Back End Developer', + contactadd: '425 5th Ave, Suite 600 Francisco New York, NY, 10016', + contactno: '(154) 456-8745', + contactinstagram: '650', + contactlinkedin: '150', + contactfacebook: '195', + }, + { + contactimg: 'assets/images/profile/user-7.jpg', + contactname: 'Jacob Jones', + contactpost: 'Graphics Designer', + contactadd: '17 Stuyvesant Walk, Suite 600 New York, NY, 10009', + contactno: '(150) 784-7890', + contactinstagram: '151', + contactlinkedin: '29', + contactfacebook: '160', + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/courses/course-detail/course-detail.component.html b/theme/packages/main/src/app/pages/apps/courses/course-detail/course-detail.component.html new file mode 100644 index 0000000..83debc1 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/courses/course-detail/course-detail.component.html @@ -0,0 +1,501 @@ + +
+ + + + + {{ courseDetail()?.courseName }} + +
+
+ + + + + + Introduction +

Step 1 - Introduction

+

+ This is an example step of the course. You can put anything in here + from example codes to videos. +

+

+ To install the CLI you need to have installed npm which typically + comes with NodeJS.To install or upgrade the CLI run the following npm + command: +

+

npm -g install @angular/cli

+

+ To verify that the CLI has been installed correctly, open a console + and run: +

+

ng version

+

Install dependencies

+

To moderate the images we'll need a few Node.js packages:

+ The Google Cloud Vision Client Library for Node.js: + @google-cloud/vision to run the image through the Cloud Vision API + to detect inappropriate images. The Google Cloud Storage Client Library + for Node.js: @google-cloud/storage to download and upload the images + from Cloud Storage. A Node.js library allowing us to run processes: + child-process-promise to run ImageMagick since the ImageMagick + command-line tool comes pre-installed on all Functions instances. +

+ To install these three packages into your Cloud Functions app, run the + following npm install --save command. Make sure that you do this from + the functions directory. +

+

+ npm install --save @google-cloud/vision @google-cloud/storage + child-process-promise +

+

+ This will install the three packages locally and add them as declared + dependencies in your package.js file. +

+
+ +
+
+ + + Get the sample code +

Step 2 - Get the sample code

+

+ This is an example step of the course. You can put anything in here + from example codes to videos. +

+

+ To install the CLI you need to have installed npm which typically + comes with NodeJS.To install or upgrade the CLI run the following npm + command: +

+

npm -g install @angular/cli

+

+ To verify that the CLI has been installed correctly, open a console + and run: +

+

ng version

+

Install dependencies

+

To moderate the images we'll need a few Node.js packages:

+ The Google Cloud Vision Client Library for Node.js: + @google-cloud/vision to run the image through the Cloud Vision API + to detect inappropriate images. The Google Cloud Storage Client Library + for Node.js: @google-cloud/storage to download and upload the images + from Cloud Storage. A Node.js library allowing us to run processes: + child-process-promise to run ImageMagick since the ImageMagick + command-line tool comes pre-installed on all Functions instances. +

+ To install these three packages into your Cloud Functions app, run the + following npm install --save command. Make sure that you do this from + the functions directory. +

+

+ npm install --save @google-cloud/vision @google-cloud/storage + child-process-promise +

+

+ This will install the three packages locally and add them as declared + dependencies in your package.js file. +

+
+ + +
+
+ + + + Create a Firebase project and Set up your app +

Step 3 - Create a Firebase project and Set up your app

+

+ This is an example step of the course. You can put anything in here + from example codes to videos. +

+

+ To install the CLI you need to have installed npm which typically + comes with NodeJS.To install or upgrade the CLI run the following npm + command: +

+

npm -g install @angular/cli

+

+ To verify that the CLI has been installed correctly, open a console + and run: +

+

ng version

+

Install dependencies

+

To moderate the images we'll need a few Node.js packages:

+ The Google Cloud Vision Client Library for Node.js: + @google-cloud/vision to run the image through the Cloud Vision API + to detect inappropriate images. The Google Cloud Storage Client Library + for Node.js: @google-cloud/storage to download and upload the images + from Cloud Storage. A Node.js library allowing us to run processes: + child-process-promise to run ImageMagick since the ImageMagick + command-line tool comes pre-installed on all Functions instances. +

+ To install these three packages into your Cloud Functions app, run the + following npm install --save command. Make sure that you do this from + the functions directory. +

+

+ npm install --save @google-cloud/vision @google-cloud/storage + child-process-promise +

+

+ This will install the three packages locally and add them as declared + dependencies in your package.js file. +

+
+ + +
+
+ + + Install the Firebase Command Line Interface +

Step 4 - Install the Firebase Command Line Interface

+

+ This is an example step of the course. You can put anything in here + from example codes to videos. +

+

+ To install the CLI you need to have installed npm which typically + comes with NodeJS.To install or upgrade the CLI run the following npm + command: +

+

npm -g install @angular/cli

+

+ To verify that the CLI has been installed correctly, open a console + and run: +

+

ng version

+

Install dependencies

+

To moderate the images we'll need a few Node.js packages:

+ The Google Cloud Vision Client Library for Node.js: + @google-cloud/vision to run the image through the Cloud Vision API + to detect inappropriate images. The Google Cloud Storage Client Library + for Node.js: @google-cloud/storage to download and upload the images + from Cloud Storage. A Node.js library allowing us to run processes: + child-process-promise to run ImageMagick since the ImageMagick + command-line tool comes pre-installed on all Functions instances. +

+ To install these three packages into your Cloud Functions app, run the + following npm install --save command. Make sure that you do this from + the functions directory. +

+

+ npm install --save @google-cloud/vision @google-cloud/storage + child-process-promise +

+

+ This will install the three packages locally and add them as declared + dependencies in your package.js file. +

+
+ + +
+
+ + + Deploy and run the web app +

Step 5 - Deploy and run the web app

+

+ This is an example step of the course. You can put anything in here + from example codes to videos. +

+

+ To install the CLI you need to have installed npm which typically + comes with NodeJS.To install or upgrade the CLI run the following npm + command: +

+

npm -g install @angular/cli

+

+ To verify that the CLI has been installed correctly, open a console + and run: +

+

ng version

+

Install dependencies

+

To moderate the images we'll need a few Node.js packages:

+ The Google Cloud Vision Client Library for Node.js: + @google-cloud/vision to run the image through the Cloud Vision API + to detect inappropriate images. The Google Cloud Storage Client Library + for Node.js: @google-cloud/storage to download and upload the images + from Cloud Storage. A Node.js library allowing us to run processes: + child-process-promise to run ImageMagick since the ImageMagick + command-line tool comes pre-installed on all Functions instances. +

+ To install these three packages into your Cloud Functions app, run the + following npm install --save command. Make sure that you do this from + the functions directory. +

+

+ npm install --save @google-cloud/vision @google-cloud/storage + child-process-promise +

+

+ This will install the three packages locally and add them as declared + dependencies in your package.js file. +

+
+ + +
+
+ + + The Functions Directory +

Step 6 - The Functions Directory

+

+ This is an example step of the course. You can put anything in here + from example codes to videos. +

+

+ To install the CLI you need to have installed npm which typically + comes with NodeJS.To install or upgrade the CLI run the following npm + command: +

+

npm -g install @angular/cli

+

+ To verify that the CLI has been installed correctly, open a console + and run: +

+

ng version

+

Install dependencies

+

To moderate the images we'll need a few Node.js packages:

+ The Google Cloud Vision Client Library for Node.js: + @google-cloud/vision to run the image through the Cloud Vision API + to detect inappropriate images. The Google Cloud Storage Client Library + for Node.js: @google-cloud/storage to download and upload the images + from Cloud Storage. A Node.js library allowing us to run processes: + child-process-promise to run ImageMagick since the ImageMagick + command-line tool comes pre-installed on all Functions instances. +

+ To install these three packages into your Cloud Functions app, run the + following npm install --save command. Make sure that you do this from + the functions directory. +

+

+ npm install --save @google-cloud/vision @google-cloud/storage + child-process-promise +

+

+ This will install the three packages locally and add them as declared + dependencies in your package.js file. +

+
+ + +
+
+ + + Import the Cloud Functions and Firebase Admin modules +

Step 7 -Import the Cloud Functions and Firebase Admin modules

+

+ This is an example step of the course. You can put anything in here + from example codes to videos. +

+

+ To install the CLI you need to have installed npm which typically + comes with NodeJS.To install or upgrade the CLI run the following npm + command: +

+

npm -g install @angular/cli

+

+ To verify that the CLI has been installed correctly, open a console + and run: +

+

ng version

+

Install dependencies

+

To moderate the images we'll need a few Node.js packages:

+ The Google Cloud Vision Client Library for Node.js: + @google-cloud/vision to run the image through the Cloud Vision API + to detect inappropriate images. The Google Cloud Storage Client Library + for Node.js: @google-cloud/storage to download and upload the images + from Cloud Storage. A Node.js library allowing us to run processes: + child-process-promise to run ImageMagick since the ImageMagick + command-line tool comes pre-installed on all Functions instances. +

+ To install these three packages into your Cloud Functions app, run the + following npm install --save command. Make sure that you do this from + the functions directory. +

+

+ npm install --save @google-cloud/vision @google-cloud/storage + child-process-promise +

+

+ This will install the three packages locally and add them as declared + dependencies in your package.js file. +

+
+ + +
+
+ + + Welcome New Users +

Step 8 - Welcome New Users

+

+ This is an example step of the course. You can put anything in here + from example codes to videos. +

+

+ To install the CLI you need to have installed npm which typically + comes with NodeJS.To install or upgrade the CLI run the following npm + command: +

+

npm -g install @angular/cli

+

+ To verify that the CLI has been installed correctly, open a console + and run: +

+

ng version

+

Install dependencies

+

To moderate the images we'll need a few Node.js packages:

+ The Google Cloud Vision Client Library for Node.js: + @google-cloud/vision to run the image through the Cloud Vision API + to detect inappropriate images. The Google Cloud Storage Client Library + for Node.js: @google-cloud/storage to download and upload the images + from Cloud Storage. A Node.js library allowing us to run processes: + child-process-promise to run ImageMagick since the ImageMagick + command-line tool comes pre-installed on all Functions instances. +

+ To install these three packages into your Cloud Functions app, run the + following npm install --save command. Make sure that you do this from + the functions directory. +

+

+ npm install --save @google-cloud/vision @google-cloud/storage + child-process-promise +

+

+ This will install the three packages locally and add them as declared + dependencies in your package.js file. +

+
+ + +
+
+ + + Images moderation +

Step 9 - Images moderation

+

+ This is an example step of the course. You can put anything in here + from example codes to videos. +

+

+ To install the CLI you need to have installed npm which typically + comes with NodeJS.To install or upgrade the CLI run the following npm + command: +

+

npm -g install @angular/cli

+

+ To verify that the CLI has been installed correctly, open a console + and run: +

+

ng version

+

Install dependencies

+

To moderate the images we'll need a few Node.js packages:

+ The Google Cloud Vision Client Library for Node.js: + @google-cloud/vision to run the image through the Cloud Vision API + to detect inappropriate images. The Google Cloud Storage Client Library + for Node.js: @google-cloud/storage to download and upload the images + from Cloud Storage. A Node.js library allowing us to run processes: + child-process-promise to run ImageMagick since the ImageMagick + command-line tool comes pre-installed on all Functions instances. +

+ To install these three packages into your Cloud Functions app, run the + following npm install --save command. Make sure that you do this from + the functions directory. +

+

+ npm install --save @google-cloud/vision @google-cloud/storage + child-process-promise +

+

+ This will install the three packages locally and add them as declared + dependencies in your package.js file. +

+
+ + +
+
+ + + New Message Notifications +

Step 10 - New Message Notifications

+

+ This is an example step of the course. You can put anything in here + from example codes to videos. +

+

+ To install the CLI you need to have installed npm which typically + comes with NodeJS.To install or upgrade the CLI run the following npm + command: +

+

npm -g install @angular/cli

+

+ To verify that the CLI has been installed correctly, open a console + and run: +

+

ng version

+

Install dependencies

+

To moderate the images we'll need a few Node.js packages:

+ The Google Cloud Vision Client Library for Node.js: + @google-cloud/vision to run the image through the Cloud Vision API + to detect inappropriate images. The Google Cloud Storage Client Library + for Node.js: @google-cloud/storage to download and upload the images + from Cloud Storage. A Node.js library allowing us to run processes: + child-process-promise to run ImageMagick since the ImageMagick + command-line tool comes pre-installed on all Functions instances. +

+ To install these three packages into your Cloud Functions app, run the + following npm install --save command. Make sure that you do this from + the functions directory. +

+

+ npm install --save @google-cloud/vision @google-cloud/storage + child-process-promise +

+

+ This will install the three packages locally and add them as declared + dependencies in your package.js file. +

+
+ + +
+
+ + + Congratulations! +

Step 11 - Congratulations!

+

+ You've built a full-fidelity, offline-capable progressive web app by + leveraging the power of reusable Web Components and Firebase. Why + bother with a native app when you know how to do all that?! +

+
+ + +
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/apps/courses/course-detail/course-detail.component.ts b/theme/packages/main/src/app/pages/apps/courses/course-detail/course-detail.component.ts new file mode 100644 index 0000000..75e8cb2 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/courses/course-detail/course-detail.component.ts @@ -0,0 +1,41 @@ +import { Component, signal } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { CourseService } from 'src/app/services/apps/course/course.service'; +import { MatCardModule } from '@angular/material/card'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatStepperModule } from '@angular/material/stepper'; +import { MatInputModule } from '@angular/material/input'; +import { MatButtonModule } from '@angular/material/button'; +import { Router } from '@angular/router'; +@Component({ + selector: 'app-course-detail', + templateUrl: './course-detail.component.html', + imports: [ + MatCardModule, + TablerIconsModule, + MatStepperModule, + MatInputModule, + MatButtonModule, + ], +}) +export class AppCourseDetailComponent { + id = signal(null); + courseDetail = signal(null); + + + constructor( + activatedRouter: ActivatedRoute, + public courseService: CourseService, + private router: Router, + ) { + this.id.set(activatedRouter?.snapshot?.paramMap?.get('id')); + + const courses = this.courseService.getCourse(); + this.courseDetail.set(courses.filter((x) => x?.Id === +this.id())[0]); + } + + goBack(): void { + + this.router.navigate(['/apps/courses']); + } +} diff --git a/theme/packages/main/src/app/pages/apps/courses/course.ts b/theme/packages/main/src/app/pages/apps/courses/course.ts new file mode 100644 index 0000000..78d2123 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/courses/course.ts @@ -0,0 +1,9 @@ +// tslint:disable-next-line: class-name +export class course { + Id = -1; + courseType = ''; + courseFramework = ''; + Time = ''; + courseName = ''; + Update = ''; +} diff --git a/theme/packages/main/src/app/pages/apps/courses/courseData.ts b/theme/packages/main/src/app/pages/apps/courses/courseData.ts new file mode 100644 index 0000000..04e6139 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/courses/courseData.ts @@ -0,0 +1,76 @@ +import { course } from './course'; + +export const courseList: course[] = [ + { + Id: 1, + courseType: 'primary', + courseFramework: 'Web', + Time: '30 min', + courseName: 'Html Crash Course', + Update: 'Updated 21 Jan 2024', + }, + { + Id: 2, + courseType: 'error', + courseFramework: 'Angular', + Time: '90 min', + courseName: 'Angular Course', + Update: 'Updated 25 Jan 2024', + }, + { + Id: 3, + courseType: 'warning', + courseFramework: 'Android', + Time: '30 min', + courseName: 'Android Crash Course', + Update: 'Updated 30 Jan 2024', + }, + { + Id: 4, + courseType: 'secondary', + courseFramework: 'Design', + Time: '50 min', + courseName: 'Web Designing Course', + Update: 'Updated 01 Feb 2024', + }, + { + Id: 5, + courseType: 'primary', + courseFramework: 'Web', + Time: '120 min', + courseName: 'Basics of TypeScript', + Update: 'Updated 15 Feb 2024', + }, + { + Id: 6, + courseType: 'warning', + courseFramework: 'Android', + Time: '60 min', + courseName: 'Android N: Quick Settings', + Update: 'Updated 16 Feb 2024', + }, + { + Id: 7, + courseType: 'primary', + courseFramework: 'Web', + Time: '90 min', + courseName: 'First Progressive Web App', + Update: 'Updated 18 Feb 2024', + }, + { + Id: 8, + courseType: 'error', + courseFramework: 'Angular', + Time: '150 min', + courseName: 'Basics of Angular', + Update: 'Updated 20 Feb 2024', + }, + { + Id: 9, + courseType: 'secondary', + courseFramework: 'Design', + Time: '80 min', + courseName: 'PSD to HTML From Scratch', + Update: 'Updated 21 Feb 2024', + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/courses/courses.component.html b/theme/packages/main/src/app/pages/apps/courses/courses.component.html new file mode 100644 index 0000000..3bc8f17 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/courses/courses.component.html @@ -0,0 +1,69 @@ + + +
+
+ + Search + + + + + +
+
+ + Category + + All + Web + Android + Angular + Design + + +
+
+
+
+ +
+ @for(course of courseList(); track course.courseName) { +
+ +
+ + {{ course.courseFramework }} + + {{ course.Time }} +
+ +

+ {{ course.courseName }} +

+ {{ course.Update }} +
+ + +
+
+ } +
diff --git a/theme/packages/main/src/app/pages/apps/courses/courses.component.ts b/theme/packages/main/src/app/pages/apps/courses/courses.component.ts new file mode 100644 index 0000000..5fc5c51 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/courses/courses.component.ts @@ -0,0 +1,66 @@ +import { Component, signal } from '@angular/core'; +import { CourseService } from 'src/app/services/apps/course/course.service'; +import { course } from './course'; +import { MatCardModule } from '@angular/material/card'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatDividerModule } from '@angular/material/divider'; +import { RouterModule } from '@angular/router'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatButtonModule } from '@angular/material/button'; + +@Component({ + selector: 'app-courses', + templateUrl: './courses.component.html', + imports: [ + MatCardModule, + TablerIconsModule, + MatFormFieldModule, + MatSelectModule, + FormsModule, + ReactiveFormsModule, + MatDividerModule, + RouterModule, + MatIconModule, + MatInputModule, + MatButtonModule, + ] +}) +export class AppCoursesComponent { + courseList = signal([]); + selectedCategory = signal('All'); + + constructor(private courseService: CourseService) { + this.courseList.set(this.courseService.getCourse()); + } + + applyFilter(event: Event): void { + const filterValue = (event.target as HTMLInputElement).value; + this.courseList.set(this.filter(filterValue)); + } + + filter(v: string): course[] { + return this.courseService + .getCourse() + .filter( + (x) => x.courseName.toLowerCase().indexOf(v.toLowerCase()) !== -1 + ); + } + + ddlChange(ob: any): void { + const filterValue = ob.value; + if (filterValue === 'All') { + this.courseList.set(this.courseService.getCourse()); + } else { + this.courseList.set( + this.courseService + .getCourse() + // tslint:disable-next-line: no-shadowed-variable + .filter((course) => course.courseFramework === filterValue) + ); + } + } +} diff --git a/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.html b/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.html new file mode 100644 index 0000000..1d0eb9d --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.html @@ -0,0 +1,17 @@ +

Delete Confirmation

+ + Would you like to delete + {{ itemCount > 1 ? "these products" : "this product" }}? + + + + + diff --git a/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.scss b/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.spec.ts b/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.spec.ts new file mode 100644 index 0000000..a188ee9 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DeleteDialogComponent } from './delete-dialog.component'; + +describe('DeleteDialogComponent', () => { + let component: DeleteDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [DeleteDialogComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DeleteDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.ts b/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.ts new file mode 100644 index 0000000..19d172a --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/delete-dialog/delete-dialog.component.ts @@ -0,0 +1,35 @@ +import { Component, inject } from '@angular/core'; +import { + MAT_DIALOG_DATA, + MatDialogActions, + MatDialogClose, + MatDialogContent, + MatDialogRef, + MatDialogTitle, +} from '@angular/material/dialog'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-delete-dialog', + imports: [ + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MaterialModule, + ], + templateUrl: './delete-dialog.component.html', + styleUrl: './delete-dialog.component.scss', +}) +export class DeleteDialogComponent { + readonly dialogRef = inject(MatDialogRef); + readonly data = inject(MAT_DIALOG_DATA); + + get itemCount(): number { + return this.data?.ids?.length ?? 1; + } + + confirmDelete() { + this.dialogRef.close('delete'); + } +} diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/add-product/add-product.component.html b/theme/packages/main/src/app/pages/apps/ecommerce/add-product/add-product.component.html new file mode 100644 index 0000000..37d2087 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/add-product/add-product.component.html @@ -0,0 +1,291 @@ +
+
+
+
+ +

General

+ Product Name * + + + + A product name is required and recommended to be unique. + + + +
Description
+
+ + +
+
+ Set a description to the product for better visibility. +
+
+ +

Media

+
+ +
+ Upload +

Drop or select file

+

+ Drop files here or click to + browse through your machine. +

+
+
+ + @for (f of mediaArray.controls; track f) { + + + + } +
+ +
Files:
+
+ +

Variation

+
+ Add Product Variations +
+
+
+ + + @for (size of sizes; track size) { + + + {{ size }} + + + } + + +
+
+ + + +
+
+ +
+
+
+ +
+
+ +

Pricing

+ Base Price * + + + Set the product price. + + +
+ Discount Type* +
+ + @for (season of seasons; track season) { + + + {{ season }} + + + } + + + +
+
+ Set Discount Percentage* +
+ + + +
+ Set a percentage discount to be applied on this + product. +
+
+ +
+
+
+ Fixed Discounted Price * +
+ + + Set the discounted product price. The product will be + reduced at the determined fixed price. + + +
+
+
+
+
+
+ Tax Class* +
+ + + @for (taxClass of taxClasses; track taxClass) { + + {{ taxClass }} + + } + + Set the product tax class. + +
+
+
+ VAT Amount (%)* +
+ + + Set the product VAT about. + +
+
+
+
+
+ +

Thumbnail

+
+ +
+

Drop or select file

+

+ Drop files here or click to + browse through your machine. +

+
+
+ + @for (f of files; track f) { + + + + } +
+
+ Set the product thumbnail image. Only *.png, *.jpg and *.jpeg image + files are accepted. +
+
Files:
+
+ +
+

Status

+
+ +
+
+ + + + @for (status of productStatuses; track status) { + + {{ status.label }} + + } + + Set the product status. + +
+ +

Product Details

+
Categories
+ + + @for (category of categories; track category) { + + {{ category }} + + } + + Add product to a category. + +
+ +
+ +
Tags
+ +
+ + @for(tag of tags;track tag){ + + {{ tag }} + + + + } + + + +
+
+ + + @for (tag of allTags; track tag) { + + {{ tag }} + + } + +
+ +

Product Template

+
+ Select a product template +
+ + + @for (template of templates; track template) { + + {{ template }} + + } + + Assign a template from your current theme to define how a single + product is displayed. + +
+
+
+
+ + +
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/add-product/add-product.component.scss b/theme/packages/main/src/app/pages/apps/ecommerce/add-product/add-product.component.scss new file mode 100644 index 0000000..139597f --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/add-product/add-product.component.scss @@ -0,0 +1,2 @@ + + diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/add-product/add-product.component.ts b/theme/packages/main/src/app/pages/apps/ecommerce/add-product/add-product.component.ts new file mode 100644 index 0000000..dc0ee62 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/add-product/add-product.component.ts @@ -0,0 +1,316 @@ +import { CommonModule } from '@angular/common'; +import { Component, inject, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; + +import { + FormArray, + FormBuilder, + FormGroup, + FormsModule, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; + +import { Router } from '@angular/router'; +import { ProductService } from 'src/app/services/apps/product/product.service'; +import { debounceTime } from 'rxjs'; +import { NgxDropzoneModule } from 'ngx-dropzone'; +import { PRODUCT_DATA } from '../ecommerceData'; +import { + NgxEditorComponent, + NgxEditorMenuComponent, + Editor, + Toolbar, +} from 'ngx-editor'; +@Component({ + selector: 'app-add-product', + imports: [ + MaterialModule, + IconModule, + CommonModule, + FormsModule, + ReactiveFormsModule, + NgxDropzoneModule, + NgxEditorComponent, + NgxEditorMenuComponent, + ], + templateUrl: './add-product.component.html', + styleUrl: './add-product.component.scss', +}) +export class AddProductComponent implements OnInit { + private router = inject(Router); + private productService = inject(ProductService); + private fb = inject(FormBuilder); + + html = ''; + editor: Editor; + htmlContent1 = ''; + toolbar: Toolbar = [ + ['bold', 'italic'], + ['underline'], + ['ordered_list', 'bullet_list'], + [{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }], + ['link', 'image'], + ['text_color', 'background_color'], + ['align_left', 'align_center', 'align_right', 'align_justify'], + ]; + + files: File[] = []; + seasons: string[] = ['No Discount', 'Percentage %', 'Fixed Price']; + sizes: string[] = ['XS', 'S', 'M', 'L', 'XL']; + + taxClasses: string[] = [ + 'Select an option', + 'Tax Free', + 'Taxable Goods', + 'Downloadable Products', + ]; + categories: string[] = [ + 'Computer', + 'Watches', + 'Headphones', + 'Beauty', + 'Fashion', + 'Footwear', + ]; + templates: string[] = [ + 'Default template', + 'Fashion', + 'Office Stationary', + 'Electronics', + ]; + + productStatuses = [ + { label: 'Stock', value: true }, + { label: 'Out of stock', value: false }, + ]; + selectedOption: string = ''; + tags: string[] = []; // Selected tags + allTags: string[] = ['electronics', 'books', 'clothing', 'music']; // Suggestions + AddProduct!: FormGroup; + + product: any; + isEditMode: boolean = false; + constructor() { + this.AddProduct = this.fb.group({ + id: [null], + product_name: ['', Validators.required], + description: [''], + size: [''], + variations: [''], + base_price: [''], + + discount_type: ['No Discount'], + set_discount_percentage: [''], + fixed_discounted_price: [''], + tax_class: [''], + VAT_amount: [''], + status: [''], + categories: [''], + default_template: [''], + tags: this.fb.array([]), + + media: this.fb.array([]), + Thumbnail: this.fb.array([]), + }); + } + + get isFormValid() { + return this.AddProduct.valid; + } + + get mediaArray() { + return this.AddProduct.get('media') as FormArray; + } + get sizeControl() { + return this.AddProduct.get('size'); + } + get Thumbnail(): FormArray { + return this.AddProduct.get('Thumbnail') as FormArray; + } + get tagsArray(): FormArray { + return this.AddProduct.get('tags') as FormArray; + } + ngOnInit(): void { + this.editor = new Editor(); + + const currentUrl = this.router.url; + + if (currentUrl.includes('edit-product')) { + const product = this.productService.getProduct(); + if (product) { + // Case: Navigate via button with selected product + this.isEditMode = true; + this.populateForm(product); + } else { + // Case: Direct navigation to /edit-product with no data + this.isEditMode = true; + this.populateForm(PRODUCT_DATA[0]); // fallback product + } + + this.productService.clearProduct(); // cleanup + } else if (currentUrl.includes('add-product')) { + // Case: Add mode + this.isEditMode = false; + this.populateForm({}); // empty form + } + } + ngOnDestroy() { + this.editor.destroy(); + // Optional: Clear product data when leaving the component + this.productService.clearProduct(); + } + + onChange(event: any) { + console.log('changed'); + } + + onBlur(event: any) { + console.log('blur ' + event); + } + onSelect(event: any) { + const files = event.addedFiles; // Getting the selected files + + // Loop through the selected files and add them to the FormArray + files.forEach((file: any) => { + this.mediaArray.push(this.fb.control(file)); // Add file to FormArray + }); + } + + // Method to remove file + onRemove(file: any, index?: any) { + index = this.mediaArray.controls.findIndex( + (control) => control.value === file + ); + if (index > -1) { + this.mediaArray.removeAt(index); // Remove file from FormArray + } + } + onSeasonChange(event: any) { + this.selectedOption = event.value; + } + selectTag(tag: string) { + if (!this.tags.includes(tag)) { + this.tags.push(tag); + } + } + + addTagFromInput(event: any) { + const input = event.input; + const value = event.value?.trim(); + + if (value && !this.tags.includes(value)) { + this.tags.push(value); + } + + if (input) input.value = ''; + } + + removeTag(tag: string) { + this.tags = this.tags.filter((t) => t !== tag); + } + getBack() { + this.router.navigate(['apps/product/product-list']); + } + getAddProduct(data: any) { + const formData = this.AddProduct.getRawValue(); + const imageFilename = formData.media[0]; // e.g., "Spike Nextjs Free.jpg" + + // Store the image filename in localStorage (as a string) + localStorage.setItem('productImage', imageFilename); + if (this.isEditMode) { + if (!formData.id) { + console.error('Updated product does not have an id:', formData); // Log if id is missing + } + this.updateProduct(formData); // Pass formData which should have id + } else { + this.addProduct(formData); // Handle adding a new product (no id for new product) + } + } + + addProduct(data: any) { + if (this.AddProduct.valid) { + // Extract plain text from ngx-editor content + if (data.description?.content?.length) { + data.description = this.extractPlainText(data.description); + } else { + data.description = ''; + } + + // Handle media + if (data.media && data.media.length > 0) { + data.media = data.media.map((file: any) => file.name); + } else { + data.media = []; + } + + // Clean up unnecessary fields + delete data.size; + delete data.Thumbnail; + delete data.VAT_amount; + delete data.default_template; + delete data.fixed_discounted_price; + delete data.tags; + delete data.tax_class; + delete data.variations; + delete data.set_discount_percentage; + delete data.discount_type; + + this.productService.emitProduct(data); + this.getBack(); + } + } + extractPlainText(doc: any): string { + let text = ''; + + if (!doc?.content) return text; + + doc.content.forEach((node: any) => { + if (node.content) { + node.content.forEach((child: any) => { + if (child.text) { + text += child.text + ' '; + } + }); + } + }); + + return text.trim(); + } + + populateForm(product: any) { + this.AddProduct.patchValue({ + id: product.id, + product_name: product.product_name || product.title || '', + category: product.category, + base_price: product.base_price || product.price || '', + status: product.status, + description: product.description, + imagePath: product.imagePath, + }); + } + updateProduct(data: any) { + if (this.AddProduct.valid) { + if (data.media && data.media.length > 0) { + data.media = data.media.map((file: any) => file.name); + } else { + data.media = []; + } + + // clean up unnecessary fields + delete data.size; + delete data.Thumbnail; + delete data.VAT_amount; + delete data.default_template; + delete data.fixed_discounted_price; + delete data.tags; + delete data.tax_class; + delete data.variations; + delete data.set_discount_percentage; + delete data.discount_type; + this.productService.updateProduct(data); // <-- make sure you have this method in service + this.getBack(); + } + } +} diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/ecommerce.component.html b/theme/packages/main/src/app/pages/apps/ecommerce/ecommerce.component.html new file mode 100644 index 0000000..d4390d6 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/ecommerce.component.html @@ -0,0 +1,139 @@ +
+ @if(selection.selected.length === 0 ){ +
+
+ + search + + + +
+
+ +
+
+ + } + @if(selection.selected.length > 0){ +
+
Selected: {{ selection.selected.length }}
+ +
+ } + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + Product Name + +
+ users +
+
+ {{ element.product_name }} +
+ + {{ element.categories[0] }} + +
+
+
+ Date + + {{ element.date }} + + Status + + @if (element.status) { + + Stock + + } @else { + + Out Of Stock + + } + + Price + + ${{ element.base_price }} + + Action + + + + + + + +
+ @if(dataSource.filteredData.length == 0){ +

Not Found

+ } + + +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/ecommerce.component.scss b/theme/packages/main/src/app/pages/apps/ecommerce/ecommerce.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/ecommerce.component.ts b/theme/packages/main/src/app/pages/apps/ecommerce/ecommerce.component.ts new file mode 100644 index 0000000..de88039 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/ecommerce.component.ts @@ -0,0 +1,292 @@ +import { SelectionModel } from '@angular/cdk/collections'; +import { + AfterViewInit, + ChangeDetectorRef, + Component, + inject, + NgZone, + OnInit, + ViewChild, +} from '@angular/core'; +import { MatTable, MatTableDataSource } from '@angular/material/table'; +import { MaterialModule } from 'src/app/material.module'; + +import { CommonModule } from '@angular/common'; +import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { Router } from '@angular/router'; +import { MatDialog } from '@angular/material/dialog'; +import { DeleteDialogComponent } from '../delete-dialog/delete-dialog.component'; +import { ProductService } from 'src/app/services/apps/product/product.service'; +import { Element, PRODUCT_DATA } from './ecommerceData'; + +@Component({ + selector: 'app-ecommerce', + imports: [MaterialModule, CommonModule, IconModule], + templateUrl: './ecommerce.component.html', + styleUrl: './ecommerce.component.scss', +}) +export class ProductComponent implements AfterViewInit, OnInit { + @ViewChild(MatTable) table!: MatTable; + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator = + Object.create(null); + private _snackBar = inject(MatSnackBar); + private router = inject(Router); + private productService = inject(ProductService); + readonly dialog = inject(MatDialog); + + + displayedColumns: string[] = [ + 'select', + 'product_name', + 'date', + 'status', + 'base_price', + ]; + dataSource = new MatTableDataSource(PRODUCT_DATA); + selection = new SelectionModel(true, []); + durationInSeconds = 1; + constructor( + private breakpointObserver: BreakpointObserver, + private cdr: ChangeDetectorRef, + ) { + this.breakpointObserver + .observe(['(max-width: 600px)']) + .subscribe((result: BreakpointState) => { + this.displayedColumns = result.matches + ? ['product_name', 'date', 'status', 'base_price'] + : [ + 'select', + 'product_name', + 'date', + 'status', + 'base_price', + 'actions', + ]; + }); + } + ngOnInit(): void { + this.getAddedTableData(); + this.productService.productUpdated.subscribe((updatedProduct: any) => { + // Ensure updatedProduct has an id and dataSource is an array + if (!updatedProduct.id) { + console.warn('Updated product does not have an id:', updatedProduct); + return; + } + + const productIndex = this.dataSource.data.findIndex( + (product: any) => product.id === updatedProduct.id + ); + if (productIndex !== -1) { + // If the product is found, update it with the new data + this.dataSource.data[productIndex] = { + ...this.dataSource.data[productIndex], + ...updatedProduct, + }; + + // Trigger reactivity by setting the data again + this.dataSource.data = [...this.dataSource.data]; + + // Reset paginator if any + if (this.paginator) { + this.paginator.pageIndex = 0; + this.dataSource.paginator = this.paginator; + } + + // Trigger table re-render + setTimeout(() => { + if (this.table) { + this.table.renderRows(); + } + }); + + // Run change detection if necessary (for OnPush change detection) + this.cdr.detectChanges(); + this.openSnackBar('Product updated successfully!'); + } else { + console.warn('Product not found for update:', updatedProduct); + } + }); + } + + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + } + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value + .trim() + .toLowerCase(); + + this.dataSource.filterPredicate = (data: Element, filter: string) => { + return ( + data.product_name.toLowerCase().includes(filter) || + data.categories.join(' ').toLowerCase().includes(filter) + ); + }; + + this.dataSource.filter = filterValue; + + } + + + /** Whether the number of selected elements matches the total number of rows. */ + isAllSelected(): any { + const numSelected = this.selection.selected.length; + const numRows = this.dataSource.data.length; + return numSelected === numRows; + } + + /** Selects all rows if they are not all selected; otherwise clear selection. */ + masterToggle(): void { + this.isAllSelected() + ? this.selection.clear() + : this.dataSource.data.forEach((row) => this.selection.select(row)); + } + + /** The label for the checkbox on the passed row */ + checkboxLabel(row?: Element): string { + if (!row) { + return `${this.isAllSelected() ? 'deselect' : 'select'} all`; + } + return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${ + row.id + 1 + }`; + } + + openSnackBar(message: string) { + this._snackBar.open(message, 'Close', { + duration: this.durationInSeconds * 1000, + verticalPosition: 'top', + horizontalPosition: 'center', + }); + } + + getDeletedById(id: number) { + // Remove the record from dataSource by filtering out the one with matching id + const updatedData = this.dataSource.data.filter((item) => item.id !== id); + + // Update the dataSource with the filtered data + this.dataSource.data = updatedData; + if (this.table) { + this.table.renderRows(); + } else { + console.error('Table reference is undefined'); + } + // Refresh table view + this.dataSource._updateChangeSubscription(); + this.cdr.detectChanges(); + + this.openSnackBar('Product deleted successfully!'); + } + + getViewNavigate(element: Element) { + this.productService.setProduct(element); + this.router.navigate(['apps/product/product-details']); + } + + + openDialog(idOrIds: number | number[]): void { + const dialogRef = this.dialog.open(DeleteDialogComponent, { + data: { + ids: Array.isArray(idOrIds) ? idOrIds : [idOrIds], // Always pass as array + }, + width: '400px', + enterAnimationDuration: '0ms', + exitAnimationDuration: '0ms', + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result === 'delete') { + if (Array.isArray(idOrIds)) { + this.deleteSelectedIds(idOrIds); // ⬅️ Handle multiple deletion + } else { + this.getDeletedById(idOrIds); // ⬅️ Handle single deletion + } + } + }); + } + + + getEditProduct(element?: Element) { + const productToEdit = element || PRODUCT_DATA[0]; + this.productService.setProduct(productToEdit); // Store product to localStorage/service + this.router.navigate(['apps/product/edit-product']); // Navigate to edit page + } + getAddedTableData() { + this.productService.productAdded$.subscribe((result: any) => { + if (result) { + const newId = this.dataSource.data.length + 1; + + const now = new Date(); + const parts = new Intl.DateTimeFormat('en-US', { + weekday: 'short', + month: 'short', + day: '2-digit', + year: 'numeric', + }).formatToParts(now); + + const weekday = parts.find((p) => p.type === 'weekday')?.value; + const month = parts.find((p) => p.type === 'month')?.value; + const day = parts.find((p) => p.type === 'day')?.value; + const year = parts.find((p) => p.type === 'year')?.value; + + const formattedDate = `${weekday}, ${month} ${day} ${year}`; + + // ✅ Convert HTML description to plain text + const plainTextDescription = + new DOMParser().parseFromString(result.description, 'text/html').body + .textContent || ''; + + + const storedImage = localStorage.getItem('productImage') || 'assets/images/products/s3.jpg'; + + + const newProduct: Element = { + id: newId, + imagePath:'assets/images/products/s3.jpg', + product_name: result.product_name, + categories: [result.categories], + date: formattedDate, + status: result.status, + base_price: Number(result.base_price), + dealPrice: Number(result.discounted), + description: plainTextDescription, + rating:4.5 + }; + + this.dataSource.data.unshift(newProduct); + this.dataSource.data = [...this.dataSource.data]; + + if (this.paginator) { + this.paginator.pageIndex = 0; + this.dataSource.paginator = this.paginator; + } + + setTimeout(() => this.table?.renderRows()); + + this.cdr.detectChanges(); + this.openSnackBar('Product added successfully!'); + this.productService.clearEmittedProduct(); + } + }); + } + + deleteSelected(): void { + const selectedIds = this.selection.selected.map((item) => item.id); + if (selectedIds.length > 0) { + this.openDialog(selectedIds); // Open dialog with selected IDs + } + } + + deleteSelectedIds(ids: number[]): void { + this.dataSource.data = this.dataSource.data.filter(item => !ids.includes(item.id)); + this.openSnackBar('Selected products deleted successfully!'); + this.selection.clear(); // Clear selection after deletion + } + getAddProductNavigate(){ + this.router.navigate(['apps/product/add-product']) + } +} diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/ecommerceData.ts b/theme/packages/main/src/app/pages/apps/ecommerce/ecommerceData.ts new file mode 100644 index 0000000..8d01002 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/ecommerceData.ts @@ -0,0 +1,242 @@ +export interface Element { + id: number; + imagePath: string; + product_name: string; + categories: string[]; + date: string; + status: boolean; + base_price: number; + dealPrice: number; + description: string; + media?: any; + discountPercent?: number; + gender?: string; + rating?: number; +} + +interface productcards { + id: number; + imgSrc: string; + title: string; + price: string; + rprice: string; + date: string; +} + +export const PRODUCT_DATA: Element[] = [ + { + id: 1, + imagePath: 'assets/images/products/s11.jpg', + product_name: 'Cute Soft Teddybear', + categories: ['toys', 'women', 'men'], + date: 'Fri, Jan 11 2025', + status: false, + base_price: 285, + dealPrice: 345, + discountPercent: 18, + rating: 4.5, + gender: 'women', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis', + }, + { + id: 2, + imagePath: 'assets/images/products/s5.jpg', + product_name: 'MacBook Air Pro', + categories: ['fashionelectronics', 'women', 'men', 'fashion', 'electronics'], + date: 'Thu, Jan 16 2025', + status: true, + base_price: 650, + dealPrice: 900, + discountPercent: 36, + rating: 4.3, + gender: 'kids', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis', + }, + { + id: 3, + imagePath: 'assets/images/products/s6.jpg', + product_name: 'Gaming Console', + categories: ['electronics', 'wireless'], + date: 'Wed, Feb 9 2025', + status: true, + base_price: 25, + dealPrice: 31, + discountPercent: 35, + rating: 4.0, + gender: 'men', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis', + }, + { + id: 4, + imagePath: 'assets/images/products/s4.jpg', + product_name: 'Boat Headphone', + categories: ['electronics', 'accessories', 'laptop accessories', 'bags'], + date: 'Wed, Feb 16 2025', + status: false, + base_price: 50, + dealPrice: 65, + discountPercent: 53, + rating: 4.2, + gender: 'women', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis', + }, + { + id: 5, + imagePath: 'assets/images/products/s10.jpg', + product_name: 'Toy Dino for Fun', + categories: ['toys', 'accessories', 'wallets'], + date: 'Wed, Feb 20 2025', + status: false, + base_price: 210, + dealPrice: 250, + discountPercent: 21, + rating: 3.0, + gender: 'kids', + description: + 'A sleek and elegant leather wallet with a minimalist design, perfect for everyday use.', + }, + { + id: 6, + imagePath: 'assets/images/products/s7.jpg', + product_name: 'Red Valvet Dress', + categories: ['headphones', 'audio', 'Apple', 'fashion'], + date: 'Wed, Mar 9 2025', + status: true, + base_price: 150, + dealPrice: 200, + discountPercent: 48, + rating: 4.7, + gender: 'men', + description: + 'The Apple AirPods Max offers high-fidelity audio, active noise cancellation, and spatial audio with dynamic head tracking.', + }, + { + id: 7, + imagePath: 'assets/images/products/s8.jpg', + product_name: 'Shoes for Girls', + categories: ["headphones", "audio", "Apple", 'fashion', 'toys'], + date: 'Fri, Mar 11 2025', + status: false, + base_price: 300, + dealPrice: 380, + discountPercent: 48, + rating: 4.7, + gender: 'women', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis', + }, + { + id: 8, + imagePath: 'assets/images/products/s9.jpg', + product_name: 'Short & Sweet Purse', + categories: ["smartphone", "Samsung", "Android", 'fashion'], + date: 'Wed, Mar 19 2025', + status: false, + base_price: 175, + dealPrice: 200, + discountPercent: 48, + rating: 4.7, + gender: 'kids', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis', + }, + { + id: 9, + imagePath: 'assets/images/products/s3.jpg', + product_name: 'The Psychology of Money', + categories: ["accessories", "mouse", "Logitech", 'fashion', 'books'], + date: 'Wed, Mar 22 2025', + status: true, + base_price: 125, + dealPrice: 137, + discountPercent: 48, + rating: 4.7, + gender: 'men', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis', + }, + { + id: 10, + imagePath: 'assets/images/products/s1.jpg', + product_name: 'How Innovation Works', + categories: ["gaming", "console", "Nintendo", 'books'], + date: 'Wed, Mar 28 2025', + status: false, + base_price: 275, + dealPrice: 350, + discountPercent: 48, + rating: 4.7, + gender: 'women', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis', + }, + { + id: 11, + imagePath: 'assets/images/products/s12.jpg', + product_name: 'Little Angel Toy', + categories: ["beauty", "makeup", "foundation", "Maybelline", 'toys'], + date: 'Thu, Apr 1 2025', + status: false, + base_price: 5, + dealPrice: 10, + discountPercent: 48, + rating: 4.7, + gender: 'kids', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis', + }, + { + id: 12, + imagePath: 'assets/images/products/s2.jpg', + product_name: 'Psalms Book for Growth', + categories: ["watch", "Fossil", "wearables", 'books'], + date: 'Fri, Apr 7 2025', + status: true, + base_price: 89, + dealPrice: 99, + discountPercent: 48, + rating: 4.7, + gender: 'men', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis', + }, +]; + +export const productcards: productcards[] = [ + { + id: 1, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Headphone', + price: '285', + rprice: '375', + date: 'Tue, Apr 03, 2025', + }, + { + id: 2, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Air Pro', + price: '285', + rprice: '375', + date: 'Tue, Apr 10, 2025', + }, + { + id: 3, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Red Velvet Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 15, 2025', + }, + { + id: 4, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Soft Plush Teddy', + price: '285', + rprice: '375', + date: 'Tue, Apr 12, 2025', + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/product-details/product-details.component.html b/theme/packages/main/src/app/pages/apps/ecommerce/product-details/product-details.component.html new file mode 100644 index 0000000..cf1330e --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/product-details/product-details.component.html @@ -0,0 +1,243 @@ +
+ +
+ +
+
+ user +
+
+
+ + {{ product?.status === "Stock" ? "In Stock" : "Out of Stock" }} + Books +
+ +

{{ product?.product_name }}

+

{{ product.description || 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ex arcu, tincidunt bibendum felis' }}

+ +
+ ${{ product.base_price }} + ${{ product.dealPrice || 134}} + ({{ product.discountPercent || 14 }}% off) +
+
+
+ + @if(product.rating !== undefined){ + @for (star of [1, 2, 3, 4, 5]; track star) { + + + + } + } + +
+ + 236 reviews +
+ +
+ + + + @if(isSelected){ + + } + + +
+ +
+ + + + + - + + + {{ quantity }} + + + + + + +
+ +
+ + +
+

+ Dispatched in 2–3 weeks
+ Why the longer time for delivery? +

+
+
+
+ + + + + Description + +
+ Sed at diam elit. Vivamus tortor odio, pellentesque eu tincidunt a, + aliquet sit amet lorem pellentesque eu tincidunt a, aliquet sit amet + lorem. +
+

+ Cras eget elit semper, congue sapien id, pellentesque diam. Nulla + faucibus diam nec fermentum ullamcorper. Praesent sed ipsum ut augue + vestibulum malesuada. Duis vitae volutpat odio. Integer sit amet elit ac + justo sagittis dignissim. +

+

+ Vivamus quis metus in nunc semper efficitur eget vitae diam. Proin justo + diam, venenatis sit amet eros in, iaculis auctor magna. Pellentesque sit + amet accumsan urna, sit amet pretium ipsum. Fusce condimentum venenatis + mauris et luctus. Vestibulum ante ipsum primis in faucibus orci luctus + et ultrices posuere cubilia curae. +

+
+ + + + Reviews + +
+
+ +
+
Average Rating
+
4/5
+
+ + + + + +
+
+
+
+ +
+ + @for(rating of ratings; track rating) { +
+ {{ rating.label }} Stars + + + ({{ rating.count }}) +
+ } +
+
+ +
+ + + +
+
+
+
+
+ +
Related Products
+
+ @for(productcard of productcards; track productcard.title) { +
+ + + imgSrc + + + {{ + productcard.title + }} +
+
+
${{ productcard.price }}
+ ${{ productcard.rprice }} +
+
+ @if(product.rating !== undefined){ + @for (star of [1, 2, 3, 4, 5]; track star) { + + + + } + } +
+
+
+
+
+ } +
+
diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/product-details/product-details.component.scss b/theme/packages/main/src/app/pages/apps/ecommerce/product-details/product-details.component.scss new file mode 100644 index 0000000..bdc4af9 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/product-details/product-details.component.scss @@ -0,0 +1,41 @@ +.border-style{ + border-color: var(--mat-sys-secondary) +} +.mat-card { + min-height: 100%; /* Ensures cards grow equally */ + } + + + .progress { + flex-grow: 1; + width: 25px; + height: 8px; + border-radius: 4px; + background-color: #fcfafa; + } + + .count { + width: 50px; + text-align: right; + font-size: 14px; + } + .cards-circle { + width: 25px; + height: 25px; + border-radius: var(--mat-sys-corner-full); + display: flex; + align-items: center; + justify-content: center; + background-color: var(--mat-sys-primary); // <-- dynamic! + .theme-icon { + display: none; + } + &.selected { + .theme-icon { + display: block; + color: white; + width: 18px; + height: 18px; + } + } + } \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/product-details/product-details.component.ts b/theme/packages/main/src/app/pages/apps/ecommerce/product-details/product-details.component.ts new file mode 100644 index 0000000..c75af28 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/product-details/product-details.component.ts @@ -0,0 +1,154 @@ +import { + AfterViewInit, + Component, + ElementRef, + inject, + ViewChild, +} from '@angular/core'; +import { MaterialModule } from 'src/app/material.module'; +import { CarouselModule, OwlOptions } from 'ngx-owl-carousel-o'; +import { IconModule } from 'src/app/icon/icon.module'; +import { CommonModule } from '@angular/common'; +import { Router } from '@angular/router'; +import { ProductService } from 'src/app/services/apps/product/product.service'; +import { productcards } from '../ecommerceData'; + +@Component({ + selector: 'app-product-details', + imports: [MaterialModule, CarouselModule, IconModule, CommonModule], + templateUrl: './product-details.component.html', + styleUrl: './product-details.component.scss', +}) +export class ProductDetailsComponent implements AfterViewInit { + @ViewChild('carouselContainer', { static: false }) + private productService = inject(ProductService); + carouselContainer!: ElementRef; + product: any; + isSelected = false; + + quantity: number = 1; + toggleValue: any = null; + + selectedTabIndex = 0; + + customOptions: OwlOptions = { + loop: true, + mouseDrag: false, + touchDrag: false, + pullDrag: false, + dots: false, + navSpeed: 700, + navText: ['', ''], + responsive: { + 0: { + items: 1, + }, + 400: { + items: 2, + }, + 740: { + items: 3, + }, + 940: { + items: 4, + }, + }, + nav: true, + }; + slides = [ + { + id: 'slide-1', + imgUrl: 'assets/images/products/s2.jpg', + altText: 'Slide 1', + title: 'text1', + }, + { + id: 'slide-2', + imgUrl: 'assets/images/products/s2.jpg', + altText: 'Slide 2', + title: 'text2', + }, + { + id: 'slide-3', + imgUrl: 'path/to/image3.jpg', + altText: 'Slide 3', + title: 'text3', + }, + { + id: 'slide-3', + imgUrl: 'path/to/image3.jpg', + altText: 'Slide 3', + title: 'text3', + }, + // Add more slides as needed + ]; + + productcards = productcards; + + ratings = [ + { label: 1, value: 30, count: 485 }, + { label: 2, value: 20, count: 215 }, + { label: 3, value: 10, count: 110 }, + { label: 4, value: 60, count: 620 }, + { label: 5, value: 15, count: 160 }, + ]; + + constructor(private router: Router) { + this.product = this.productService.getProduct(); + + if (!this.product) { + console.error('Product not found!'); + // Redirect to another page if the product is not found + // this.router.navigate(['/apps/product']); + } else { + console.log('Received Product:', this.product); + + } + } + + ngOnDestroy() { + // Optional: Clear product data when leaving the component + //this.productService.clearProduct(); + } + + ngAfterViewInit(): void {} + + trackById(index: number, item: any): string { + return item.id; // Make sure each slide has a unique 'id' property + } + + increaseQty() { + this.quantity++; + } + + decreaseQty() { + if (this.quantity > 1) { + this.quantity--; + } + } + + getBack() { + this.router.navigate(['apps/product/product-list']); + } + + toggleSelected() { + this.isSelected = !this.isSelected; + } + resetToggleValue() { + this.toggleValue = null; + } + getStarClass(index: number, rating?: number): string { + const safeRating = rating ?? 0; // Fallback if undefined + const fullStars = Math.floor(safeRating); // Full stars + const partialStars = safeRating % 1 !== 0; // Whether there is a partial star + + if (index < fullStars) { + return 'fill-warning'; // full star + } else if (index === fullStars && partialStars) { + return 'text-warning'; // partial star + } else { + return ''; // empty star, no class + } + } + +} diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/shop/shop.component.html b/theme/packages/main/src/app/pages/apps/ecommerce/shop/shop.component.html new file mode 100644 index 0000000..4609163 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/shop/shop.component.html @@ -0,0 +1,158 @@ + + + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/shop/shop.component.scss b/theme/packages/main/src/app/pages/apps/ecommerce/shop/shop.component.scss new file mode 100644 index 0000000..baf2635 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/shop/shop.component.scss @@ -0,0 +1,92 @@ +.img-wrapper { + position: relative; + + img { + display: block; + width: 100%; + height: auto; + } + + .icon-container { + position: absolute; + bottom: -14px; + right: 10px; + display: flex; + gap: 8px; // spacing between icons + } + + .cart-btn-overlay { + position: relative; + z-index: 1; + width: 30px; + height: 30px; + min-width: 30px; + } + + +} + +.cards-circle { + width: 25px; + height: 25px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: 0.3s ease; + border: 1px solid transparent; +} + +.pricing-section { + .section-title { + margin-bottom: 8px; + } + + mat-radio-group { + display: flex; + flex-direction: column; + gap: 5px; + } + + .custom-radio { + font-size: 14px; + color: #2c2c2c; + + .mat-radio-outer-circle { + border-width: 2px; + } + + .mat-radio-inner-circle { + background-color: var(--mat-sys-primary); // Customize selected color + } + + &.mat-radio-checked { + .mat-radio-outer-circle { + border-color: var(--mat-sys-primary); + } + } + } +} + +.iconPosition { + position: relative; + top: 3px; +} + +.productcard { + -webkit-transition: 0.1s ease-in; + transition: 0.1s ease-in; + + &:hover { + scale: 1.01; + } +} + +.active-primary{ + &.bg-primary{ + i-tabler, .mdc-list-item__primary-text{ + color: white; + } + } +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/ecommerce/shop/shop.component.ts b/theme/packages/main/src/app/pages/apps/ecommerce/shop/shop.component.ts new file mode 100644 index 0000000..caf1650 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/ecommerce/shop/shop.component.ts @@ -0,0 +1,283 @@ +import { CommonModule } from '@angular/common'; +import { + ChangeDetectorRef, + Component, + inject, + OnInit, + signal, +} from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { Router } from '@angular/router'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { DeleteDialogComponent } from '../../delete-dialog/delete-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { ProductService } from 'src/app/services/apps/product/product.service'; +import { Element, PRODUCT_DATA } from '../ecommerceData'; + +export interface Section { + name: string; + icon: string; +} + +@Component({ + selector: 'app-shop', + imports: [ + MaterialModule, + IconModule, + CommonModule, + FormsModule, + NgScrollbarModule, + ], + templateUrl: './shop.component.html', + styleUrl: './shop.component.scss', +}) +export class ShopComponent implements OnInit { + private router = inject(Router); + readonly dialog = inject(MatDialog); + private cdr = inject(ChangeDetectorRef); + private _snackBar = inject(MatSnackBar); + private productService = inject(ProductService); + mobileQuery: MediaQueryList; + private mediaMatcher: MediaQueryList = matchMedia(`(max-width: 1199px)`); + durationInSeconds = 1; + searchText: string = ''; + + filteredCards: Element[] = PRODUCT_DATA; + folders: Section[] = [ + { name: 'all', icon: 'users' }, + { name: 'fashion', icon: 'hanger' }, + { name: 'books', icon: 'book' }, + { name: 'toys', icon: 'mood-smile' }, + { name: 'electronics', icon: 'device-laptop' }, + ]; + selectedCategory: string = this.folders[0].name; + notes: Section[] = [ + { name: 'newest', icon: 'calendar' }, + { name: 'Price: High-Low', icon: 'sort-descending' }, + { name: 'Price: Low-High', icon: 'sort-ascending' }, + { name: 'discounted', icon: 'percentage' }, + ]; + selectedSortBy: string = this.notes[0].name; + selectedColor: string | null = null; + isMobileView = false; + selectedGender: string = 'all'; + genderOptions = [ + { label: 'All', value: 'all' }, + { label: 'Men', value: 'men' }, + { label: 'Women', value: 'women' }, + { label: 'Kids', value: 'kids' }, + ]; + + selectedPrice: string = 'all'; + priceOptions = [ + { label: 'All', value: 'all' }, + { label: '0 – 50', value: '0-50' }, + { label: '50–100', value: '50-100' }, + { label: '100–200', value: '100-200' }, + { label: 'Over 200', value: 'over-200' }, + ]; + constructor() { + const media = inject(MediaMatcher); + this.mobileQuery = media.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + this.mobileQuery.addEventListener('change', (e) => { + this.isMobileView = e.matches; + }); + } + ngOnInit(): void { + + } + + filterCards() { + const text = this.searchText.toLowerCase(); + + this.filteredCards = PRODUCT_DATA.filter( + (card) => + card.product_name.toLowerCase().includes(text) || + card.categories.join(' ').toLowerCase().includes(text) + ); + } + + getCategory(name: string): void { + this.selectedCategory = name; + if (name.toLowerCase() === 'all') { + this.filteredCards = [...PRODUCT_DATA]; + } else { + this.filteredCards = PRODUCT_DATA.filter((card) => + card.categories.some( + (cat) => cat.toLowerCase() === name.toLowerCase() + ) + ); + } + } + + + getSorted(name: string): void { + this.selectedSortBy = name; // ✅ Add this line to track selection + + const nameLower = name.toLowerCase(); + + switch (nameLower) { + case 'newest': + this.filteredCards = [...PRODUCT_DATA].sort((a, b) => { + const dateA = new Date(a.date); + const dateB = new Date(b.date); + return dateB.getTime() - dateA.getTime(); // Newest first + }); + break; + + case 'base_price: hiah-low': + case 'base_price: high-low': + this.filteredCards = [...PRODUCT_DATA].sort( + (a, b) => +b.base_price - +a.base_price + ); + break; + + case 'base_price: low-hiah': + case 'base_price: low-high': + this.filteredCards = [...PRODUCT_DATA].sort( + (a, b) => +a.base_price - +b.base_price + ); + break; + + case 'discounted': + this.filteredCards = [...PRODUCT_DATA].sort((a, b) => { + const discountA = +a.dealPrice - +a.base_price; + const discountB = +b.dealPrice - +b.base_price; + return discountB - discountA; + }); + break; + + default: + this.filteredCards = [...PRODUCT_DATA]; + } + } + + getGender(gender: string): void { + if (gender.toLowerCase() === 'all') { + this.filteredCards = [...PRODUCT_DATA]; + } else { + this.filteredCards = PRODUCT_DATA.filter( + (card) => card.gender === gender.toLowerCase() + ); + } + } + getPricing(base_priceRange: string): void { + this.selectedPrice = base_priceRange; + + switch (base_priceRange) { + case '0-50': + this.filteredCards = PRODUCT_DATA.filter( + (card) => +card.base_price >= 0 && +card.base_price <= 50 + ); + break; + + case '50-100': + this.filteredCards = PRODUCT_DATA.filter( + (card) => +card.base_price > 50 && +card.base_price <= 100 + ); + break; + + case '100-200': + this.filteredCards = PRODUCT_DATA.filter( + (card) => +card.base_price > 100 && +card.base_price <= 200 + ); + break; + + case 'over-200': + this.filteredCards = PRODUCT_DATA.filter( + (card) => +card.base_price > 200 + ); + break; + + case 'all': + default: + this.filteredCards = [...PRODUCT_DATA]; + break; + } + } + getRestFilter() { + this.selectedCategory = this.folders[0].name; + this.selectedSortBy = this.notes[0].name; + this.filteredCards = [...PRODUCT_DATA]; + } + + getProductList() { + this.searchText = ''; + this.filteredCards = [...PRODUCT_DATA]; + } + + isOver(): boolean { + return this.mediaMatcher.matches; + } + + getAddProductRoute() { + this.router.navigate(['apps/product/add-product']); + } + openDialog(idOrIds: number | number[]): void { + const dialogRef = this.dialog.open(DeleteDialogComponent, { + data: { + ids: Array.isArray(idOrIds) ? idOrIds : [idOrIds], // Always pass as array + }, + width: '400px', + enterAnimationDuration: '0ms', + exitAnimationDuration: '0ms', + }); + + dialogRef.afterClosed().subscribe((result: any) => { + if (result === 'delete') { + if (Array.isArray(idOrIds)) { + } else { + this.getDeletedById(idOrIds); // ⬅️ Handle single deletion + } + } + }); + } + getDeletedById(id: number) { + this.filteredCards = this.filteredCards.filter( + (product) => product.id !== id + ); + + this.cdr.detectChanges(); // Optional if view updates correctly + this.openSnackBar('Product deleted successfully!'); + } + openSnackBar(message: string) { + this._snackBar.open(message, 'Close', { + duration: this.durationInSeconds * 1000, + verticalPosition: 'top', + horizontalPosition: 'center', + }); + } + getviewDetails(productcardDetails: Element) { + this.productService.setProduct(productcardDetails); + this.router.navigate(['apps/product/product-details']); + } + toggleColor(color: string): void { + this.selectedColor = this.selectedColor === color ? null : color; + } + getEditedProduct(productcardDetails: Element) { + this.productService.setProduct(productcardDetails); + this.router.navigate(['apps/product/edit-product']); + } + getStarClass(index: number, rating?: number): string { + const safeRating = rating ?? 0 ; // Fallback if undefined + const fullStars = Math.floor(safeRating); // Full stars + const partialStars = safeRating % 1 !== 0; // Whether there is a partial star + + if (index < fullStars) { + return 'fill-warning'; // full star + } else if (index === fullStars && partialStars) { + return 'text-warning'; // partial star + } else { + return ''; // empty star, no class + } + } + + + +} diff --git a/theme/packages/main/src/app/pages/apps/email/detail/detail.component.html b/theme/packages/main/src/app/pages/apps/email/detail/detail.component.html new file mode 100644 index 0000000..5b9c677 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/detail/detail.component.html @@ -0,0 +1,234 @@ +
+ @if(ms.selectedMail()) { +
+ + + + + + + + + + + + + + + +
+ + + + + + +
+
+ } + + + + + + + @if(ms.selectedMail()) { + +
+
+ userimg +
+
+ {{ ms.selectedUser().name }} +
+ {{ ms.selectedUser().email }} +
+
+ @for(l of ms.selectedMail()?.label; track l) { + + @if(l === 'Personal') { + + Personal + + } @if(l === 'Work') { + + Work + + } @if(l === 'Payments') { + + Payment + + } @if(l === 'Accounts') { + + Account + + } + + } +
+
+
+ {{ ms.selectedMail()?.Subject }} +
+
+ {{ ms.selectedMail()?.Message }} +
+
+ + + + + @if(ms.replyShow()) { +
+ + Type your reply here + + + + +
+ } @if(!ms.replyShow()) { +
+ + +
+ } +
+
+
+ } +
diff --git a/theme/packages/main/src/app/pages/apps/email/detail/detail.component.ts b/theme/packages/main/src/app/pages/apps/email/detail/detail.component.ts new file mode 100644 index 0000000..9922797 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/detail/detail.component.ts @@ -0,0 +1,106 @@ +import { Component, signal } from '@angular/core'; +import { getUser } from '../user-data'; +import { + mailGlobalVariable, + mailService, +} from 'src/app/services/apps/email/email.service'; +import { Router } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { CommonModule } from '@angular/common'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-maildetail', + templateUrl: './detail.component.html', + imports: [ + MaterialModule, + TablerIconsModule, + CommonModule, + NgScrollbarModule, + FormsModule, + ], +}) +export class DetailComponent { + // tslint:disable-next-line: no-shadowed-variable + + selectedMail = this.ms.selectedMail; + users = signal([]); + topLabel = signal('Inbox'); + type = signal('inbox'); + + selectedLabel: string; + + constructor( + public ms: mailGlobalVariable, + public mailService: mailService, + public router: Router + ) {} + + labelClick(type: string): void { + const mail = this.selectedMail(); + if (mail) { + if (!mail.label.includes(type)) { + mail.label = [type]; + } + } + } + + ddlRemoveClick(st: string): void { + const mail = this.selectedMail(); + if (mail) { + if (st === 'Spam') { + mail.mailbox = 'Spam'; + this.ms.spamList().push(mail); + this.resetSelectedMail(); + } else if (st === 'Trash') { + mail.mailbox = 'Trash'; + this.ms.trashList().push(mail); + this.resetSelectedMail(); + } else if (st === 'Read') { + mail.seen = !mail.seen; + } + } + } + resetSelectedMail(): void { + this.selectedMail.set(null); + } + + iconsClick(name: string): void { + this.ms.toggleStar(name); + } + resetCount(): void { + this.ms.inboxList.set(this.mailService.getInbox()); + this.ms.sentList.set(this.mailService.getSent()); + this.ms.draftList.set(this.mailService.getDraft()); + this.ms.spamList.set(this.mailService.getSpam()); + this.ms.trashList.set(this.mailService.getTrash()); + + const usersArray: any[] = []; + for (const mail of this.ms.mailList()) { + const user = getUser(mail.fromId); + if (user) { + usersArray.push(user); + } + } + + this.users.set(usersArray); + this.ms.collectionSize.set(this.ms.inboxList.length); + this.resetSelectedMail(); + this.topLabel.set('Inbox'); + this.type.set('inbox'); + } + + reply(): void { + this.ms.replyShow.set(true); + } + + sendButtonClick(): void { + this.ms.replyShow.set(false); + } + + removeClass(): void { + this.ms.selectedMail.set(null); + } +} diff --git a/theme/packages/main/src/app/pages/apps/email/email-data.ts b/theme/packages/main/src/app/pages/apps/email/email-data.ts new file mode 100644 index 0000000..fef9c1c --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/email-data.ts @@ -0,0 +1,112 @@ +import { Mailbox } from './email'; + +export const mailboxList: Mailbox[] = [ + { + MailId: 'bb428c03-1bc6-4f3d-9d5e-268ec44eebc3', + fromId: '899d0e31-b71e-4d95-a8a0-6a8bceb314bd', + Subject: 'Kindly check this latest updated', + date: new Date('1-15-2024'), + Message: + '1.The phrase Lorem ipsum dolor sit amet consectetuer appears in Microsoft Word online Help. This phrase has the appearance of an intelligent Latin idiom. Actually, it is nonsense.', + readStatus: false, + seen: false, + mailbox: 'Inbox', + filter: ['Star'], + label: ['Personal'], + }, + { + MailId: '65a6eb21-67b5-45c3-9af7-faca2d9b60d5', + fromId: 'ee272550-36e8-4fe2-889d-c1ee701c5863', + Subject: 'Literature from 45 BC, making', + date: new Date('1-15-2024'), + Message: + '1.The phrase Lorem ipsum dolor sit amet consectetuer appears in Microsoft Word online Help. This phrase has the appearance of an intelligent Latin idiom. Actually, it is nonsense.', + readStatus: false, + seen: false, + mailbox: 'Inbox', + filter: ['Star'], + label: ['Personal'], + }, + { + MailId: '910d7e0a-f3b0-47a7-bb53-9036ed717291', + fromId: 'eef93cb1-7766-4413-a5cf-ecbf71fa3674', + Subject: 'consectetuer adipiscing elit.', + date: new Date('11-25-2024'), + Message: + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.', + readStatus: false, + seen: false, + mailbox: 'Spam', + filter: ['Star'], + label: ['Accounts'], + }, + { + MailId: '910d7e0a-f3b0-47a7-bb53-9036ed717298', + fromId: 'a41c6c4a-9cb1-45d1-8c6f-091044ba51ff', + Subject: + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aenean commodo ligula eget dolor. Aenean massa.', + date: new Date('02-15-2024'), + Message: + 'The phrase Lorem ipsum dolor sit amet consectetuer appears in Microsoft Word online Help. This phrase has the appearance of an intelligent Latin idiom. Actually, it is nonsense.', + readStatus: false, + seen: false, + mailbox: 'Sent', + filter: ['Star', 'Important'], + label: ['Payments'], + }, + { + MailId: '0c914dfd-be0d-4d46-b963-47bcb064154f', + fromId: '3782c174-1f2c-4dc4-b75d-0bedf400e023', + Subject: + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aenean commodo ligula eget dolor. Aenean massa.', + date: new Date('03-30-2024'), + Message: + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.', + readStatus: false, + seen: false, + mailbox: 'Draft', + filter: [], + label: ['Work'], + }, + { + MailId: '2b0e4083-00e4-48fd-9cb3-05434767ca66', + fromId: '36a1ead7-57a0-4275-8a21-956194ab7cdf', + Subject: + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.', + date: new Date('5-20-2024'), + Message: + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.', + readStatus: false, + seen: false, + mailbox: 'Sent', + filter: [], + label: ['Work'], + }, + { + MailId: '65a6eb21-67b5-45c3-9af7-faca2d9b60d5', + fromId: 'b5899bef-d01e-42d8-af2d-edfb16b6b21e', + Subject: 'Literature from 45 BC, making', + date: new Date('1-15-2024'), + Message: + '1.The phrase Lorem ipsum dolor sit amet consectetuer appears in Microsoft Word online Help. This phrase has the appearance of an intelligent Latin idiom. Actually, it is nonsense.', + readStatus: false, + seen: false, + mailbox: 'Inbox', + filter: ['Star'], + label: ['Personal'], + }, + { + MailId: '0c914dfd-be0d-4d46-b963-47bcb064154f', + fromId: '7d910620-84e1-49fc-951e-d375587b8189', + Subject: + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aenean commodo ligula eget dolor. Aenean massa.', + date: new Date('10-50-2024'), + Message: + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.', + readStatus: false, + seen: false, + mailbox: 'Draft', + filter: [], + label: ['Work'], + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/email/email.component.html b/theme/packages/main/src/app/pages/apps/email/email.component.html new file mode 100644 index 0000000..c0395f8 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/email.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/theme/packages/main/src/app/pages/apps/email/email.component.ts b/theme/packages/main/src/app/pages/apps/email/email.component.ts new file mode 100644 index 0000000..876d99c --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/email.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { ListingComponent } from './listing/listing.component'; + +@Component({ + selector: 'app-email', + templateUrl: './email.component.html', + imports: [MaterialModule, TablerIconsModule, ListingComponent] +}) +export class AppEmailComponent { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/apps/email/email.ts b/theme/packages/main/src/app/pages/apps/email/email.ts new file mode 100644 index 0000000..823b14d --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/email.ts @@ -0,0 +1,16 @@ +export class Mailbox { + + constructor( + public MailId: string, + public fromId: string, + public Subject: string, + public Message: string, + public date: Date, + public readStatus: boolean, + public seen: boolean, + public mailbox: string, + public filter: string[], + public label: string[], + public isChecked?: boolean + ) {} +} diff --git a/theme/packages/main/src/app/pages/apps/email/listing/categories.ts b/theme/packages/main/src/app/pages/apps/email/listing/categories.ts new file mode 100644 index 0000000..878cb64 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/listing/categories.ts @@ -0,0 +1,98 @@ +export interface Category { + id: number; + name: string; + icon: string; + count: number; + color?: string; + active: boolean; +} + +export const mailbox = [ + { + id: 1, + name: 'Inbox', + icon: 'mail', + count: 0, + active: true, + }, + { + id: 2, + name: 'Sent', + icon: 'send', + count: 0, + active: false, + }, + { + id: 3, + name: 'Draft', + icon: 'note', + count: 0, + active: false, + }, + { + id: 4, + name: 'Spam', + icon: 'flag', + count: 0, + active: false, + }, + { + id: 5, + name: 'Trash', + icon: 'trash', + count: 0, + active: false, + }, +]; + +export const filter = [ + { + id: 501, + name: 'Star', + icon: 'star', + count: 0, + active: false, + }, + { + id: 502, + name: 'Important', + icon: 'info-circle', + count: 0, + active: false, + }, +]; + +export const label: Category[] = [ + { + id: 701, + name: 'Personal', + icon: 'folder', + count: 0, + color: '#5D87FF', + active: false, + }, + { + id: 702, + name: 'Work', + icon: 'folder', + count: 0, + color: '#49BEFF', + active: false, + }, + { + id: 703, + name: 'Payments', + icon: 'folder', + count: 0, + color: '#FA896B', + active: false, + }, + { + id: 704, + name: 'Accounts', + icon: 'folder', + count: 0, + color: '#FFAE1F', + active: false, + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/email/listing/compose-dialog-content.html b/theme/packages/main/src/app/pages/apps/email/listing/compose-dialog-content.html new file mode 100644 index 0000000..11ba774 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/listing/compose-dialog-content.html @@ -0,0 +1,39 @@ + + + + + +
+

Compose Email

+ +
+
+
+
+ + + +
+
+ + + +
+
+
+ + +
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/email/listing/listing.component.html b/theme/packages/main/src/app/pages/apps/email/listing/listing.component.html new file mode 100644 index 0000000..b71c62f --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/listing/listing.component.html @@ -0,0 +1,203 @@ + + + + +
+
+ +
Inbox
+
+
+ + + + +
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/email/listing/listing.component.ts b/theme/packages/main/src/app/pages/apps/email/listing/listing.component.ts new file mode 100644 index 0000000..19fd7fd --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/listing/listing.component.ts @@ -0,0 +1,354 @@ +import { + Component, + OnInit, + Inject, + signal, + inject, + ChangeDetectorRef, + OnDestroy, +} from '@angular/core'; +import { Category, mailbox, filter, label } from './categories'; +import { MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { + mailGlobalVariable, + mailService, +} from 'src/app/services/apps/email/email.service'; +import { getUser, User } from '../user-data'; +import { mailboxList } from '../email-data'; +import { Mailbox } from '../email'; +import { Router } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { NgxEditorComponent, NgxEditorMenuComponent, Editor, Toolbar, NgxEditorModule } from 'ngx-editor'; + +import { + FormBuilder, + FormGroup, + FormsModule, + ReactiveFormsModule, + UntypedFormBuilder, + UntypedFormGroup, + Validators, +} from '@angular/forms'; +import { CommonModule } from '@angular/common'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { NgxPaginationModule } from 'ngx-pagination'; +import { DetailComponent } from '../detail/detail.component'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +type MailboxType = 'Inbox' | 'Sent' | 'Draft' | 'Spam' | 'Trash'; + +@Component({ + + selector: 'app-dialog-data-example-dialog', + schemas: [NO_ERRORS_SCHEMA], + templateUrl: './compose-dialog-content.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + NgxEditorModule, + ], +}) +export class ListingDialogDataExampleDialogComponent implements OnInit{ + form: FormGroup; + + html = ''; + editor: Editor; + htmlContent1 = ''; + toolbar: Toolbar = [ + ['bold', 'italic'], + ['underline'], + ['ordered_list', 'bullet_list'], + [{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }], + ['link', 'image'], + ['text_color', 'background_color'], + ['align_left', 'align_center', 'align_right', 'align_justify'], + ]; + + constructor( + @Inject(MAT_DIALOG_DATA) public data: any, + private formBuilder: FormBuilder + ) { } + ngOnInit(): void { + this.editor = new Editor(); + + } + + + onChange(event: any) { + console.log('changed'); + } + + onBlur(event: any) { + console.log('blur ' + event); + } +} + +@Component({ + selector: 'app-listing', + templateUrl: './listing.component.html', + imports: [ + MaterialModule, + CommonModule, + NgScrollbarModule, + TablerIconsModule, + NgxPaginationModule, + DetailComponent, + MatCheckboxModule, + FormsModule, + + ], + +}) +export class ListingComponent implements OnInit, OnDestroy { + searchText = signal(''); + private mediaMatcher: MediaQueryList = matchMedia(`(max-width: 960px)`); + sidePanelOpened = signal(true); + displayMode = signal('default'); + p = signal(1); + + mailboxes = signal(mailbox); + filters = signal(filter); + labels = signal(label); + selectedIndex = signal(''); + activeFilter = signal(null); + activeLabel = signal(null); + isChecked = false; + showDetail = signal(false); + + mobileQuery: MediaQueryList; + + private _mobileQueryListener: () => void; + + constructor( + public ms: mailGlobalVariable, + public mailService: mailService, + public router: Router, + public dialog: MatDialog, + private snackBar: MatSnackBar + ) { + if (!this.ms.type()) { + this.router.navigate(['apps/email/inbox']); + } + this.ms.type.set('inbox'); + const changeDetectorRef = inject(ChangeDetectorRef); + const media = inject(MediaMatcher); + this.mobileQuery = media.matchMedia('(max-width: 600px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + } + + ngOnDestroy(): void { + this.mobileQuery.removeListener(this._mobileQueryListener); + } + + isOver(): boolean { + return window.innerWidth < 1199; + } + + ngOnInit(): void { + + this.loadMailboxes(); + this.ms.topLabel.set('Inbox'); + this.selectFirstMail(); + window.addEventListener('resize', () => { + this.showDetail.set(false); + }); + } + + private selectFirstMail(): void { + const inboxMails = this.ms.inboxList(); + if (inboxMails.length > 0) { + this.mailSelected(inboxMails[0]); + } + } + + private loadMailboxes(): void { + this.ms.inboxList.set(this.mailService.getInbox()); + this.ms.sentList.set(this.mailService.getSent()); + this.ms.draftList.set(this.mailService.getDraft()); + this.ms.spamList.set(this.mailService.getSpam()); + this.ms.trashList.set(this.mailService.getTrash()); + + this.updateMailListAndUsers(this.ms.inboxList()); + } + + private updateMailListAndUsers(mailList: Mailbox[]): void { + this.ms.mailList.set(mailList); + this.ms.collectionSize.set(mailList.length); + this.ms.users.set(this.extractUsers(mailList)); + } + + private extractUsers(mailList: Mailbox[]): User[] | any { + return mailList + .map((mail) => getUser(mail.fromId)) + .filter((user) => user !== null); + } + + mailSelected(mail: Mailbox): void { + const currentMailbox = this.ms.mailList(); // Get the current mailbox + const mailExists = currentMailbox.some( + (item: { MailId: string }) => item.MailId === mail.MailId + ); + + if (!mailExists) { + this.ms.selectedMail.set(null); // Clear selected mail if it doesn't exist + this.selectedIndex.set(''); // Clear selected index + return; // Exit early if the mail does not exist + } + + // Set the selected mail and mark it as seen + this.ms.selectedMail.set(mail); + mail.seen = true; + this.ms.selectedUser.set(getUser(mail.fromId)); + this.selectedIndex.set(mail.MailId); + + if (this.isOver()) { + this.showDetail.set(true); // Show detail on smaller screens + } + } + + mailboxesChanged(type: MailboxType): void { + const listMap: Record Mailbox[]> = { + Inbox: this.ms.inboxList, + Sent: this.ms.sentList, + Draft: this.ms.draftList, + Spam: this.ms.spamList, + Trash: this.ms.trashList, + }; + + // Get the mails based on the selected mailbox type + let filteredMails = listMap[type](); + + // Exclude emails that are in Trash for all filters except Trash + if (type !== 'Trash') { + filteredMails = filteredMails.filter((mail) => mail.mailbox !== 'Trash'); + } + this.p.set(1); + // Apply the selected filter and update the displayed mail list + this.updateMailListAndUsers(filteredMails); + this.ms.topLabel.set(type); + this.mailActiveClass(type); + this.ms.type.set(type.toLowerCase()); + this.router.navigate([`apps/email/${type.toLowerCase()}`]); + } + + mailActiveClass(type: string): void { + mailbox.forEach((mail) => (mail.active = mail.name === type)); + } + iconsClick(name: string): void { + this.ms.toggleStar(name); + } + filtersClick(type: string): void { + this.activeLabel.set(null); + this.activeFilter.set(type); + this.mailActiveClass(''); + + this.p.set(1); + // Filter mails based on the filter type (Starred, Important, etc.) + let filteredMails = mailboxList.filter((mail) => + mail.filter.includes(type) + ); + + // Exclude Trash emails from the filter results + filteredMails = filteredMails.filter((mail) => mail.mailbox !== 'Trash'); + + this.updateMailListAndUsers(filteredMails); + this.ms.topLabel.set(type); + this.mailActiveClass(type); + this.ms.type.set(type.toLowerCase()); + this.router.navigate([`apps/email/${type.toLowerCase()}`]); + } + + labelChange(type: string): void { + this.activeFilter.set(null); + this.activeLabel.set(type); + this.mailActiveClass(''); + this.p.set(1); + // Filter mails based on the selected label + let labeledMails = mailboxList.filter((mail) => mail.label.includes(type)); + + // Exclude Trash emails from the label filter + labeledMails = labeledMails.filter((mail) => mail.mailbox !== 'Trash'); + + this.updateMailListAndUsers(labeledMails); + this.ms.topLabel.set(type); + this.ms.type.set(type); + this.router.navigate([`apps/email/${type.toLowerCase()}`]); + } + + openDialog(): void { + const dialogRef = this.dialog.open( + ListingDialogDataExampleDialogComponent, + { autoFocus: false } + ); + dialogRef.afterClosed().subscribe((result) => { + console.log(`Dialog result: ${result}`); + }); + } + + deleteItem(mail: Mailbox): void { + const snackBarRef = this.snackBar.open( + 'Are you sure you want to delete this mail?', + 'Delete', + { + duration: 15000, + horizontalPosition: 'center', + verticalPosition: 'top', + } + ); + snackBarRef.onAction().subscribe(() => { + // Remove the email from its current mailbox (Inbox, Sent, etc.) + let updatedList: Mailbox[] = []; + + // Depending on the mailbox, filter out the deleted email + if (mail.mailbox === 'Inbox') { + updatedList = this.ms + .inboxList() + .filter((item: any) => item.MailId !== mail.MailId); + this.ms.inboxList.set(updatedList); + } else if (mail.mailbox === 'Sent') { + updatedList = this.ms + .sentList() + .filter((item) => item.MailId !== mail.MailId); + this.ms.sentList.set(updatedList); + } else if (mail.mailbox === 'Draft') { + updatedList = this.ms + .draftList() + .filter((item) => item.MailId !== mail.MailId); + this.ms.draftList.set(updatedList); + } else if (mail.mailbox === 'Spam') { + updatedList = this.ms + .spamList() + .filter((item) => item.MailId !== mail.MailId); + this.ms.spamList.set(updatedList); + } + + // Now, move the email to Trash (do not remove it entirely) + mail.mailbox = 'Trash'; + this.ms.trashList.set([...this.ms.trashList(), mail]); + mail.isChecked = false; + this.ms.selectedMail.set(null); + + // Update the mail list and users after moving the email to Trash + this.updateMailListAndUsers(updatedList); + }); + } + + onCheckboxChange(selectedMail: Mailbox): void { + this.mailboxes().forEach((mail: { MailId: string; isChecked: boolean }) => { + if (mail.MailId !== selectedMail.MailId) { + mail.isChecked = false; + } + }); + + selectedMail.isChecked = true; + } +} +function selectedMail(): Mailbox { + throw new Error('Function not implemented.'); +} diff --git a/theme/packages/main/src/app/pages/apps/email/user-data.ts b/theme/packages/main/src/app/pages/apps/email/user-data.ts new file mode 100644 index 0000000..df0b572 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/email/user-data.ts @@ -0,0 +1,340 @@ +export interface User { + userId: string; + name: string; + email: string; + username: string; + jobTitle: string; + phone: string; + imagePath: string; + address: any; +} + +export const users: User[] = [ + { + userId: 'ee272550-36e8-4fe2-889d-c1ee701c5863', + name: 'Katherine Flintoff', + email: 'katherine.flintoff@yahoo.com', + jobTitle: 'Project Manager', + username: 'Hortense99', + phone: '712.916.2569 x0663', + imagePath: 'assets/images/profile/user-5.jpg', + address: { + street: '9046 Allen Ferry', + suite: 'Suite 429', + city: 'Angushaven', + state: 'Michigan', + country: 'Costa Rica', + zipcode: '92378-7065', + geo: { + lat: '78.1292', + lng: '-134.6632', + }, + }, + }, + { + userId: '36a1ead7-57a0-4275-8a21-956194ab7cdf', + name: 'Mike Torello', + jobTitle: 'Web Developer', + email: 'Mike.Torello@hotmail.com', + username: 'Mike Torello', + phone: '789-914-4904 x173', + imagePath: 'assets/images/profile/user-5.jpg', + address: { + street: '8153 Favian Walk', + suite: 'Apt. 495', + city: 'East Preston', + state: 'Idaho', + country: 'Iceland', + zipcode: '24555', + geo: { + lat: '-42.5691', + lng: '-2.5791', + }, + }, + }, + { + userId: 'b5899bef-d01e-42d8-af2d-edfb16b6b21e', + name: 'Bianca Macdowells', + jobTitle: 'Programmer', + email: 'BiancaMacdowells@hotmail.com', + username: 'Bianca Macdowells', + phone: '961-703-4134', + imagePath: 'assets/images/profile/user-6.jpg', + address: { + street: '886 Wendy Circles', + suite: 'Apt. 933', + city: 'Lake Loy', + state: 'Rhode Island', + country: 'South Africa', + zipcode: '65261', + geo: { + lat: '-58.9245', + lng: '-43.6330', + }, + }, + }, + { + userId: '7d910620-84e1-49fc-951e-d375587b8189', + name: 'Michael Knight', + jobTitle: 'Sales Executive', + email: 'MichaelKnight@yahoo.com', + username: 'Michael Knight', + phone: '(326) 903-5706 x6854', + imagePath: 'assets/images/profile/user-7.jpg', + address: { + street: '416 Cathy Spur', + suite: 'Apt. 431', + city: 'North Camila', + state: 'Pennsylvania', + country: 'Libyan Arab Jamahiriya', + zipcode: '31751', + geo: { + lat: '64.0673', + lng: '154.7671', + }, + }, + }, + { + userId: 'afdb5033-5bcc-4cec-b932-353a83410b44', + name: 'Jamey', + jobTitle: 'PHP Developer', + email: 'Jamey_Grant_Cruickshank73@gmail.com', + username: 'Jamey_Grant', + phone: '545-939-2404 x32373', + imagePath: 'assets/images/profile/user-8.jpg', + address: { + street: '38372 Mante Glen', + suite: 'Suite 090', + city: 'Robertsside', + state: 'Texas', + country: 'Equatorial Guinea', + zipcode: '86558-7214', + geo: { + lat: '-55.0222', + lng: '-100.5977', + }, + }, + }, + { + userId: '60d07662-bfec-42c7-b044-c81bc4ff8c7a', + name: 'Barton', + email: 'Barton85_Emard@gmail.com', + jobTitle: 'Web Developer', + username: 'Barton85', + phone: '(979) 560-8322 x174', + imagePath: 'assets/images/profile/user-d1.jpg', + address: { + street: '185 Florine Spurs', + suite: 'Suite 178', + city: 'Port Carrollburgh', + state: 'Alaska', + country: 'Saint Barthelemy', + zipcode: '30126', + geo: { + lat: '24.0545', + lng: '-88.8499', + }, + }, + }, + { + userId: '5c44b666-baca-4f18-a3cb-23068c6edc14', + name: 'Gloria', + jobTitle: 'Assets', + email: 'Gloria78.Nicolas83@hotmail.com', + username: 'Gloria78', + phone: '188.890.3246', + imagePath: 'assets/images/profile/user-d2.jpg', + address: { + street: '643 Arch Mews', + suite: 'Apt. 171', + city: 'Wymanland', + state: 'Indiana', + country: 'Jersey', + zipcode: '73594-9840', + geo: { + lat: '-70.9980', + lng: '-151.6234', + }, + }, + }, + { + userId: '46d6f992-5729-4588-b7f8-ce74f21157ba', + name: 'Olin', + jobTitle: 'Finaice', + email: 'Olin.Robel49.Schowalter24@yahoo.com', + username: 'Olin.Robel49', + phone: '1-982-234-7756', + imagePath: 'assets/images/profile/user-d3.jpg', + address: { + street: '0813 Mayer Greens', + suite: 'Apt. 551', + city: 'Bergstromburgh', + state: 'Ohio', + country: 'Anguilla', + zipcode: '42502-9731', + geo: { + lat: '-48.2520', + lng: '60.6556', + }, + }, + }, + { + userId: 'bd30e201-cceb-410e-8497-a4072bc399f5', + name: 'Rollin', + jobTitle: 'Supporting', + email: 'Rollin43_Fay@yahoo.com', + username: 'Rollin43', + phone: '477-651-5715 x502', + imagePath: 'assets/images/profile/user-d4.jpg', + address: { + street: '5704 Spinka Causeway', + suite: 'Suite 388', + city: 'Pollyburgh', + state: 'Arizona', + country: 'Virgin Islands, U.S.', + zipcode: '45048', + geo: { + lat: '55.3046', + lng: '3.8129', + }, + }, + }, + { + userId: 'da95e977-cd54-4077-a767-1b7f33ef6919', + name: 'Murl', + email: 'Murl_Abshire41_Lakin@hotmail.com', + username: 'Murl_Abshire41', + jobTitle: 'Web Developer', + phone: '107-733-1219 x0615', + imagePath: 'assets/images/profile/user-d5.jpg', + address: { + street: '4880 Tanner Circles', + suite: 'Apt. 994', + city: 'Bauchside', + state: 'Ohio', + country: 'Uganda', + zipcode: '11259', + geo: { + lat: '11.6209', + lng: '-45.1766', + }, + }, + }, + { + userId: '6124d4e8-77ed-4b34-868d-d312bfab5de2', + name: 'Breanna', + jobTitle: 'Web Developer', + email: 'Breanna.Bartoletti21@hotmail.com', + username: 'Breanna.Bartoletti', + phone: '645.045.0876 x35882', + imagePath: 'assets/images/profile/user-profile.png', + address: { + street: '431 Grimes Common', + suite: 'Apt. 530', + city: 'East Lunahaven', + state: 'Virginia', + country: 'Hungary', + zipcode: '12012-3038', + geo: { + lat: '29.7991', + lng: '-70.4033', + }, + }, + }, + { + userId: 'eef93cb1-7766-4413-a5cf-ecbf71fa3674', + name: 'Michael Knight', + email: 'MichaelKnight@yahoo.com', + username: 'MichaelKnight55', + jobTitle: 'Web Developer', + phone: '199.260.3770 x2815', + imagePath: 'assets/images/profile/user-4.jpg', + address: { + street: '58581 Guillermo Springs', + suite: 'Suite 574', + city: 'Cloydville', + state: 'Delaware', + country: 'Saint Barthelemy', + zipcode: '95633-3394', + geo: { + lat: '-57.5740', + lng: '104.5634', + }, + }, + }, + { + userId: '899d0e31-b71e-4d95-a8a0-6a8bceb314bd', + name: 'James Smith', + jobTitle: 'Web Developer', + email: 'abc@company.com', + username: 'Santiago41', + phone: '1-489-921-2159 x8655', + imagePath: 'assets/images/profile/user-8.jpg', + address: { + street: '7868 Windler Dam', + suite: 'Suite 876', + city: 'Port Emmetfurt', + state: 'Alabama', + country: 'Belarus', + zipcode: '63739-4581', + geo: { + lat: '-28.7166', + lng: '-167.7070', + }, + }, + }, + { + userId: 'a41c6c4a-9cb1-45d1-8c6f-091044ba51ff', + name: 'Jonathan Higgings', + jobTitle: 'Web Developer', + email: 'Jonathan.Higgings@yahoo.com', + username: 'Jonathan Higgings10', + phone: '445-761-1519', + imagePath: 'assets/images/profile/user-11.jpg', + address: { + street: '146 Lemke Mountains', + suite: 'Apt. 407', + city: 'North Toyfort', + state: 'Connecticut', + country: 'Senegal', + zipcode: '90211-1855', + geo: { + lat: '-56.3849', + lng: '-167.1372', + }, + }, + }, + { + userId: '3782c174-1f2c-4dc4-b75d-0bedf400e023', + name: 'Bianca Macdowells', + jobTitle: 'Web Developer', + email: 'Bianca.Macdowells@hotmail.com', + username: 'Bianca Macdowells', + phone: '315-215-2852 x69280', + imagePath: 'assets/images/profile/user-3.jpg', + address: { + street: '4018 Willms Turnpike', + suite: 'Suite 573', + city: 'Leuschkemouth', + state: 'Kentucky', + country: 'Dominican Republic', + zipcode: '70964', + geo: { + lat: '80.2384', + lng: '38.1323', + }, + }, + }, +]; + +export function getUser(uid: string): User | null { + // tslint:disable-next-line: no-shadowed-variable + const u = users.find((u) => { + return u.userId === uid; + }); + + if (u === undefined) { + return null; + } + return u; +} diff --git a/theme/packages/main/src/app/pages/apps/employee/add/add.component.html b/theme/packages/main/src/app/pages/apps/employee/add/add.component.html new file mode 100644 index 0000000..39c8c08 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/employee/add/add.component.html @@ -0,0 +1,11 @@ + + + + + +

Employee Successfully Added.

+ You can find your employee at last of table. +
+ + + diff --git a/theme/packages/main/src/app/pages/apps/employee/add/add.component.ts b/theme/packages/main/src/app/pages/apps/employee/add/add.component.ts new file mode 100644 index 0000000..38e30ed --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/employee/add/add.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; + +@Component({ + selector: 'app-add', + imports: [MatDialogModule, MatButtonModule], + templateUrl: './add.component.html' +}) +export class AppAddEmployeeComponent { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/apps/employee/employee-dialog-content.html b/theme/packages/main/src/app/pages/apps/employee/employee-dialog-content.html new file mode 100644 index 0000000..efa3193 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/employee/employee-dialog-content.html @@ -0,0 +1,176 @@ +
+

{{action}} Employee

+ +
+ + + + + +@if(action !== 'Delete') { + +
+
+ + +
+
+
+ Name + + + +
+
+ Position + + + +
+
+ Email + + + +
+
+ Mobile Number + + + +
+ @if(action === 'Update') { +
+ Joining Date + + + + + +
+ } + +
+ Salary + + + +
+
+ Projects + + + +
+
+ + +
+
+} + + + + +@else { +
+

+ Sure to delete {{local_data.Name}} ? +

+
+
+ + +
+} diff --git a/theme/packages/main/src/app/pages/apps/employee/employee.component.html b/theme/packages/main/src/app/pages/apps/employee/employee.component.html new file mode 100644 index 0000000..2de13df --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/employee/employee.component.html @@ -0,0 +1,126 @@ + + +
+
+ + + + + + +
+
+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#{{ element.id }}Name +
+ +
+
+ {{ element.Name }} +
+ {{ element.Position }} +
+
+
+ Email + + {{ element.Email }} + + Mobile + + {{ element.Mobile }} + + Date of Joining + + {{ element.DateOfJoining | date : "fullDate" }} + + Salary + + {{ element.Salary }} + + Projects + + {{ element.Projects }} + + Action +
+ +
+
+
diff --git a/theme/packages/main/src/app/pages/apps/employee/employee.component.ts b/theme/packages/main/src/app/pages/apps/employee/employee.component.ts new file mode 100644 index 0000000..f6b1a5a --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/employee/employee.component.ts @@ -0,0 +1,200 @@ +import { + Component, + Inject, + Optional, + ViewChild, + AfterViewInit, +} from '@angular/core'; +import { MatTableDataSource, MatTable } from '@angular/material/table'; +import { MatPaginator } from '@angular/material/paginator'; +import { + MatDialog, + MatDialogRef, + MAT_DIALOG_DATA, +} from '@angular/material/dialog'; +import { DatePipe } from '@angular/common'; +import { AppAddEmployeeComponent } from './add/add.component'; +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MaterialModule } from 'src/app/material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { Employee } from 'src/app/pages/apps/employee/employee'; +import { EmployeeService } from 'src/app/services/apps/employee/employee.service'; +import { CommonModule } from '@angular/common'; +import { MatSnackBar } from '@angular/material/snack-bar'; +@Component({ + templateUrl: './employee.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + CommonModule, + ], +}) +export class AppEmployeeComponent implements AfterViewInit { + @ViewChild(MatTable, { static: true }) table: MatTable = + Object.create(null); + + searchText: any; + + displayedColumns: string[] = [ + '#', + 'name', + 'email', + 'mobile', + 'date of joining', + 'salary', + 'projects', + 'action', + ]; + + dataSource = new MatTableDataSource([]); + + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator = + Object.create(null); + + constructor( + public dialog: MatDialog, + private employeeService: EmployeeService + ) {} + + ngOnInit(): void { + this.loadEmployees(); + } + + loadEmployees(): void { + const employee = this.employeeService.getEmployees(); + this.dataSource.data = employee; + this.dataSource = new MatTableDataSource(employee); + } + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + } + + applyFilter(filterValue: string): void { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + openDialog(action: string, employee: Employee | any): void { + const dialogRef = this.dialog.open(AppEmployeeDialogContentComponent, { + data: { action, employee }, autoFocus: false + }); + + dialogRef.afterClosed().subscribe((result) => { + this.dataSource.data = this.employeeService.getEmployees(); + if (result && result.event === 'Refresh') { + this.loadEmployees(); // Refresh the employee list if necessary + } + }); + } +} + +interface DialogData { + action: string; + employee: Employee; +} + +@Component({ + // tslint:disable-next-line: component-selector + selector: 'app-dialog-content', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + CommonModule, + TablerIconsModule, + ], + templateUrl: 'employee-dialog-content.html', +}) +// tslint:disable-next-line: component-class-suffix +export class AppEmployeeDialogContentComponent { + action: string | any; + // tslint:disable-next-line - Disables all + local_data: Employee; + selectedImage: any = ''; + joiningDate = new FormControl(); + + constructor( + public dialog: MatDialog, + public dialogRef: MatDialogRef, + private employeeService: EmployeeService, + private snackBar: MatSnackBar, + + // @Optional() is used to prevent error if no data is passed + @Optional() @Inject(MAT_DIALOG_DATA) public data: DialogData + ) { + this.action = data.action; + this.local_data = { ...data.employee }; + + this.joiningDate = new FormControl(); + + if (this.local_data.DateOfJoining) { + this.joiningDate.setValue( + new Date(this.local_data.DateOfJoining).toISOString().split('T')[0] + ); // existing date + } else { + // Set to today's date if no existing date is available + this.joiningDate.setValue(new Date().toISOString().split('T')[0]); + } + + // Set default image path if not already set + if (!this.local_data.imagePath) { + this.local_data.imagePath = 'assets/images/profile/user-1.jpg'; + } + } + + doAction(): void { + this.local_data.DateOfJoining = this.joiningDate.value; + + if (this.action === 'Add') { + this.employeeService.addEmployee(this.local_data); + this.dialogRef.close(); + // Open success dialog + const successDialogRef = this.dialog.open(AppAddEmployeeComponent); + successDialogRef.afterClosed().subscribe(() => { + this.dialogRef.close({ event: 'Refresh' }); + this.openSnackBar('Employee Added successfully!', 'Close'); + }); + } else if (this.action === 'Update') { + this.employeeService.updateEmployee(this.local_data); + this.dialogRef.close({ event: 'Update' }); + this.openSnackBar('Employee Updated successfully!', 'Close'); + } else if (this.action === 'Delete') { + this.employeeService.deleteEmployee(this.local_data.id); + this.dialogRef.close({ event: 'Delete' }); + this.openSnackBar('Employee Deleted successfully!', 'Close'); + } + } + + openSnackBar(message: string, action: string) { + this.snackBar.open(message, action, { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } + + closeDialog(): void { + this.dialogRef.close({ event: 'Cancel' }); + } + + selectFile(event: any): void { + if (!event.target.files[0] || event.target.files[0].length === 0) { + return; // No file selected + } + + const mimeType = event.target.files[0].type; + if (mimeType.match(/image\/*/) == null) { + return; // Not an image file + } + + const reader = new FileReader(); + reader.readAsDataURL(event.target.files[0]); + + reader.onload = (_event) => { + if (typeof reader.result === 'string') { + this.local_data.imagePath = reader.result; // Set selected image path + } + }; + } +} diff --git a/theme/packages/main/src/app/pages/apps/employee/employee.ts b/theme/packages/main/src/app/pages/apps/employee/employee.ts new file mode 100644 index 0000000..fa8e0e5 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/employee/employee.ts @@ -0,0 +1,12 @@ +export interface Employee { + id: number; + Name: string; + Position: string; + Email: string; + Mobile: number; + DateOfJoining: Date; + Salary: number; + Projects: number; + imagePath: string; + action?: string; +} diff --git a/theme/packages/main/src/app/pages/apps/employee/employeeData.ts b/theme/packages/main/src/app/pages/apps/employee/employeeData.ts new file mode 100644 index 0000000..950e252 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/employee/employeeData.ts @@ -0,0 +1,103 @@ +import { Employee } from 'src/app/pages/apps/employee/employee'; + +export const employees: Employee[] = [ + { + id: 1, + Name: 'Johnathan Deo', + Position: 'Seo Expert', + Email: 'r@gmail.com', + Mobile: 9786838, + DateOfJoining: new Date('01-2-2024'), + Salary: 12000, + Projects: 10, + imagePath: 'assets/images/profile/user-2.jpg', + }, + { + id: 2, + Name: 'Mark Zukerburg', + Position: 'Web Developer', + Email: 'mark@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('04-2-2024'), + Salary: 12000, + Projects: 10, + imagePath: 'assets/images/profile/user-3.jpg', + }, + { + id: 3, + Name: 'Sam smith', + Position: 'Web Designer', + Email: 'sam@gmail.com', + Mobile: 7788838, + DateOfJoining: new Date('02-2-2024'), + Salary: 12000, + Projects: 10, + imagePath: 'assets/images/profile/user-4.jpg', + }, + { + id: 4, + Name: 'John Deo', + Position: 'Tester', + Email: 'john@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('03-2-2024'), + Salary: 12000, + Projects: 11, + imagePath: 'assets/images/profile/user-5.jpg', + }, + { + id: 5, + Name: 'Genilia', + Position: 'Actor', + Email: 'genilia@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('05-2-2024'), + Salary: 12000, + Projects: 19, + imagePath: 'assets/images/profile/user-6.jpg', + }, + { + id: 6, + Name: 'Jack Sparrow', + Position: 'Content Writer', + Email: 'jac@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('05-21-2024'), + Salary: 12000, + Projects: 5, + imagePath: 'assets/images/profile/user-7.jpg', + }, + { + id: 7, + Name: 'Tom Cruise', + Position: 'Actor', + Email: 'tom@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('02-15-2024'), + Salary: 12000, + Projects: 9, + imagePath: 'assets/images/profile/user-3.jpg', + }, + { + id: 8, + Name: 'Hary Porter', + Position: 'Actor', + Email: 'hary@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('07-3-2024'), + Salary: 12000, + Projects: 7, + imagePath: 'assets/images/profile/user-6.jpg', + }, + { + id: 9, + Name: 'Kristen Ronaldo', + Position: 'Player', + Email: 'kristen@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('01-15-2024'), + Salary: 12000, + Projects: 1, + imagePath: 'assets/images/profile/user-5.jpg', + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/fullcalendar/calendar-form-dialog/calendar-form-dialog.component.html b/theme/packages/main/src/app/pages/apps/fullcalendar/calendar-form-dialog/calendar-form-dialog.component.html new file mode 100644 index 0000000..3137bf6 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/fullcalendar/calendar-form-dialog/calendar-form-dialog.component.html @@ -0,0 +1,96 @@ + + + + +
+
+

Add Event

+ +
+ +
+
+
+ + + +
+
+ + + +
+ +
+ + + + + +
+
+ + + + + +
+
+ +
+ + +
+
+
diff --git a/theme/packages/main/src/app/pages/apps/fullcalendar/calendar-form-dialog/calendar-form-dialog.component.ts b/theme/packages/main/src/app/pages/apps/fullcalendar/calendar-form-dialog/calendar-form-dialog.component.ts new file mode 100644 index 0000000..a59b6e3 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/fullcalendar/calendar-form-dialog/calendar-form-dialog.component.ts @@ -0,0 +1,89 @@ +import { + ChangeDetectionStrategy, + Component, + Inject, + signal, +} from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { CalendarEvent } from 'angular-calendar'; +import { + FormsModule, + ReactiveFormsModule, + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup, +} from '@angular/forms'; +import { EgretCalendarEvent } from '../event.model'; +import { MaterialModule } from 'src/app/material.module'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { provideNativeDateAdapter } from '@angular/material/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +interface DialogData { + event?: CalendarEvent; + action?: string; + date?: Date; +} + +@Component({ + selector: 'app-calendar-form-dialog', + templateUrl: './calendar-form-dialog.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + MatDatepickerModule, + TablerIconsModule + ], + providers: [provideNativeDateAdapter()], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CalendarFormDialogComponent { + event = signal(null); + dialogTitle = signal(''); + action = signal('Add Event'); + eventForm: UntypedFormGroup; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) private data: DialogData, + private formBuilder: UntypedFormBuilder + ) { + this.event.set(data.event); + this.action.set(data.action); + + if (this.action() === 'edit') { + this.dialogTitle.set(this.event().title); + } else { + this.dialogTitle.set('Add Event'); + this.event.set( + new EgretCalendarEvent({ + start: data.date, + end: data.date, + }) + ); + } + + // console.log(data); + this.eventForm = this.buildEventForm(this.event()); + } + + buildEventForm(event: any): any { + return new UntypedFormGroup({ + _id: new UntypedFormControl(event._id), + title: new UntypedFormControl(event.title), + start: new UntypedFormControl(event.start), + end: new UntypedFormControl(event.end), + allDay: new UntypedFormControl(event.allDay), + color: this.formBuilder.group({ + primary: new UntypedFormControl(event.color.primary), + secondary: new UntypedFormControl(event.color.secondary), + }), + meta: this.formBuilder.group({ + location: new UntypedFormControl(event.meta.location), + notes: new UntypedFormControl(event.meta.notes), + }), + draggable: new UntypedFormControl(true), + }); + } +} diff --git a/theme/packages/main/src/app/pages/apps/fullcalendar/dialog.component.html b/theme/packages/main/src/app/pages/apps/fullcalendar/dialog.component.html new file mode 100644 index 0000000..312dd2f --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/fullcalendar/dialog.component.html @@ -0,0 +1,86 @@ + + + + +
+
+

{{ data?.action }}

+ +
+ + @if(data?.action === 'Edit') { +
+
+ +
+ + + +
+ +
+ + + +
+ +
+ + + + + +
+ +
+ + + + + +
+
+
+ } +
+ + +
+
diff --git a/theme/packages/main/src/app/pages/apps/fullcalendar/event.model.ts b/theme/packages/main/src/app/pages/apps/fullcalendar/event.model.ts new file mode 100644 index 0000000..e496d6d --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/fullcalendar/event.model.ts @@ -0,0 +1,52 @@ +import { CalendarEventAction, CalendarEvent } from 'angular-calendar'; +import { + startOfDay, +} from 'date-fns'; + +export class EgretCalendarEvent implements CalendarEvent { + // tslint:disable-next-line - Disables all + _id?: string; + start: Date; + end: Date; + title: string; + color?: { + primary: string; + secondary: string; + }; + actions?: CalendarEventAction[]; + allDay?: boolean; + cssClass?: string; + resizable?: { + beforeStart?: boolean; + afterEnd?: boolean; + }; + draggable?: boolean; + meta?: { + location: string; + notes: string; + }; + + constructor(data: any) { + data = data || {}; + this.start = new Date(data.start) || startOfDay(new Date()); + this.end = new Date(data.end); + this._id = data._id || ''; + this.title = data.title || ''; + this.color = { + primary: (data.color && data.color.primary) || '#247ba0', + secondary: (data.color && data.color.secondary) || '#D1E8FF', + }; + this.draggable = data.draggable || true; + this.resizable = { + beforeStart: (data.resizable && data.resizable.beforeStart) || true, + afterEnd: (data.resizable && data.resizable.afterEnd) || true, + }; + this.actions = data.actions || []; + this.allDay = data.allDay || false; + this.cssClass = data.cssClass || ''; + this.meta = { + location: (data.meta && data.meta.location) || '', + notes: (data.meta && data.meta.notes) || '', + }; + } +} diff --git a/theme/packages/main/src/app/pages/apps/fullcalendar/fullcalendar.component.html b/theme/packages/main/src/app/pages/apps/fullcalendar/fullcalendar.component.html new file mode 100644 index 0000000..ed84fc4 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/fullcalendar/fullcalendar.component.html @@ -0,0 +1,120 @@ + + +
+ Angular Calendar +
+ +
+
+
+
+ + + + +
+ {{ + viewDate() | calendarDate : view() + "ViewTitle" : "en" + }} +
+ + + + + + + + + + +
+
+
+
+ +
+ + + + + + + + + + + +
+
+
diff --git a/theme/packages/main/src/app/pages/apps/fullcalendar/fullcalendar.component.ts b/theme/packages/main/src/app/pages/apps/fullcalendar/fullcalendar.component.ts new file mode 100644 index 0000000..a4565ca --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/fullcalendar/fullcalendar.component.ts @@ -0,0 +1,286 @@ +import { + Component, + ChangeDetectionStrategy, + Inject, + signal, + DOCUMENT +} from '@angular/core'; +import { CommonModule, NgSwitch } from '@angular/common'; +import { + MatDialog, + MatDialogRef, + MatDialogConfig, + MAT_DIALOG_DATA, + MatDialogModule, +} from '@angular/material/dialog'; +import { + FormsModule, + ReactiveFormsModule, + UntypedFormGroup, +} from '@angular/forms'; +import { CalendarFormDialogComponent } from './calendar-form-dialog/calendar-form-dialog.component'; +import { + startOfDay, + subDays, + addDays, + endOfMonth, + isSameDay, + isSameMonth, + addHours, + subMonths, + addMonths, +} from 'date-fns'; +import { Subject } from 'rxjs'; +import { + CalendarDateFormatter, + CalendarEvent, + CalendarEventAction, + CalendarEventTimesChangedEvent, + CalendarModule, + CalendarView, +} from 'angular-calendar'; +import { MaterialModule } from 'src/app/material.module'; +import { + MatNativeDateModule, + provideNativeDateAdapter, +} from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +const colors: any = { + red: { + primary: '#fa896b', + secondary: '#fdede8', + }, + blue: { + primary: '#5d87ff', + secondary: '#ecf2ff', + }, + yellow: { + primary: '#ffae1f', + secondary: '#fef5e5', + }, +}; + +@Component({ + selector: 'app-calendar-dialog', + templateUrl: './dialog.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + CommonModule, + MatNativeDateModule, + MatDialogModule, + MatDatepickerModule, TablerIconsModule + ], + providers: [provideNativeDateAdapter()], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CalendarDialogComponent { + options!: UntypedFormGroup; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) {} +} + +@Component({ + selector: 'app-fullcalendar', + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './fullcalendar.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + NgSwitch, + CalendarModule, + CommonModule, + MatDatepickerModule, + MatDialogModule, + MatFormFieldModule, + ], + providers: [provideNativeDateAdapter(), CalendarDateFormatter] +}) +export class AppFullcalendarComponent { + dialogRef = signal | any>(null); + dialogRef2 = signal | any>(null); + lastCloseResult = signal(''); + actionsAlignment = signal(''); + view = signal('month'); + viewDate = signal(new Date()); + activeDayIsOpen = signal(true); + + config: MatDialogConfig = { + disableClose: false, + width: '', + height: '', + position: { + top: '', + bottom: '', + left: '', + right: '', + }, + data: { + action: '', + event: [], + }, + }; + numTemplateOpens = 0; + + actions: CalendarEventAction[] = [ + { + label: ': Edit', + onClick: ({ event }: { event: CalendarEvent }): void => { + this.handleEvent('Edit', event); + }, + }, + { + label: 'Delete', + onClick: ({ event }: { event: CalendarEvent }): void => { + this.events.set( + this.events().filter((iEvent: CalendarEvent) => iEvent !== event) + ); + this.handleEvent('Deleted', event); + }, + }, + ]; + + refresh: Subject = new Subject(); + + events = signal([ + { + start: subDays(startOfDay(new Date()), 1), + end: addDays(new Date(), 1), + title: 'A 3 day event', + color: colors.red, + actions: this.actions, + }, + { + start: startOfDay(new Date()), + title: 'An event with no end date', + color: colors.blue, + actions: this.actions, + }, + { + start: subDays(endOfMonth(new Date()), 3), + end: addDays(endOfMonth(new Date()), 3), + title: 'A long event that spans 2 months', + color: colors.blue, + }, + { + start: addHours(startOfDay(new Date()), 2), + end: new Date(), + title: 'A draggable and resizable event', + color: colors.yellow, + actions: this.actions, + resizable: { + beforeStart: true, + afterEnd: true, + }, + draggable: true, + }, + ]); + + constructor(public dialog: MatDialog, @Inject(DOCUMENT) doc: any) {} + + dayClicked({ date, events }: { date: Date; events: CalendarEvent[] }): void { + if (isSameMonth(date, this.viewDate())) { + if ( + (isSameDay(this.viewDate(), date) && this.activeDayIsOpen() === true) || + events.length === 0 + ) { + this.activeDayIsOpen.set(false); + } else { + this.activeDayIsOpen.set(true); + this.viewDate.set(date); + } + } + } + + eventTimesChanged({ + event, + newStart, + newEnd, + }: CalendarEventTimesChangedEvent): void { + this.events.set( + this.events().map((iEvent: CalendarEvent) => { + if (iEvent === event) { + return { + ...event, + start: newStart, + end: newEnd, + }; + } + return iEvent; + }) + ); + + this.handleEvent('Dropped or resized', event); + } + + handleEvent(action: string, event: CalendarEvent): void { + this.config.data = { event, action }; + this.dialogRef.set(this.dialog.open(CalendarDialogComponent, this.config)); + + this.dialogRef() + .afterClosed() + .subscribe((result: string) => { + this.lastCloseResult.set(result); + this.dialogRef.set(null); + this.refresh.next(result); + }); + } + + addEvent(): void { + this.dialogRef2.set( + this.dialog.open(CalendarFormDialogComponent, { + panelClass: 'calendar-form-dialog', + autoFocus: false, + data: { + action: 'add', + date: new Date(), + }, + }) + ); + this.dialogRef2() + .afterClosed() + .subscribe((res: { action: any; event: any }) => { + if (!res) { + return; + } + const dialogAction = res.action; + const responseEvent = res.event; + responseEvent.actions = this.actions; + this.events.set([...this.events(), responseEvent]); + this.dialogRef2.set(null); + this.refresh.next(res); + }); + } + + deleteEvent(eventToDelete: CalendarEvent): void { + this.events.set( + this.events().filter( + (event: CalendarEvent) => event !== eventToDelete + ) + ); + } + + setView(view: CalendarView | any): void { + this.view.set(view); + } + + goToPreviousMonth(): void { + this.viewDate.set(subMonths(this.viewDate(), 1)); + } + + goToNextMonth(): void { + this.viewDate.set(addMonths(this.viewDate(), 1)); + } + + goToToday() { + this.viewDate.set(new Date()); + } +} diff --git a/theme/packages/main/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html b/theme/packages/main/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html new file mode 100644 index 0000000..027a82b --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html @@ -0,0 +1,156 @@ + + +
+
+
+

+ # + + {{ invoice().id }} +

+
+
+ + Cancel + + +
+
+ + + +
+
+ + Order Status: + + +
+ {{ invoice().status }} +
+
+
+
+ + Order Date + +
+ {{ invoice().orderDate | date : "dd-MM-yyyy" }} +
+
+
+
+ + + +
+
+ + Bill From + + +
+
+ + Bill To + + +
+
+ + Enter From Address + + +
+
+ + Bill From + + +
+
+
+ +
+
+ + + + + + + + + + + + + @for(row of addForm.get('rows')['controls']; track row; let index = + $index) { + + + + + + + + + + + + + + } + +
#Item NameUnit PriceUnitsUnit Total Price
+ {{ index + 1 }} + + + + + + + + + + + + + + + + + + @if(addForm.get('rows')) { + + } + + @if(index > 0) { + + } +
+
+ +
+
Sub total: {{ subTotal() }}
+
Total Vat: {{ vat() }}%
+ +

Grand Total: {{ grandTotal() }}

+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/invoice/add-invoice/add-invoice.component.ts b/theme/packages/main/src/app/pages/apps/invoice/add-invoice/add-invoice.component.ts new file mode 100644 index 0000000..c81e40c --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/add-invoice/add-invoice.component.ts @@ -0,0 +1,145 @@ +import { Component, signal } from '@angular/core'; +import { + UntypedFormGroup, + UntypedFormBuilder, + Validators, + UntypedFormArray, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { order, InvoiceList } from '../invoice'; +import { InvoiceService } from 'src/app/services/apps/invoice/invoice.service'; +import { Router, RouterModule } from '@angular/router'; +import { MatDialog } from '@angular/material/dialog'; +import { AddedDialogComponent } from './added-dialog/added-dialog.component'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +@Component({ + selector: 'app-add-invoice', + templateUrl: './add-invoice.component.html', + imports: [ + MaterialModule, + CommonModule, + RouterModule, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ] +}) +export class AppAddInvoiceComponent { + addForm: UntypedFormGroup | any; + rows: UntypedFormArray; + invoice = signal([]); + subTotal = signal(0); + vat = signal(0); + grandTotal = signal(0); + + constructor( + private fb: UntypedFormBuilder, + private invoiceService: InvoiceService, + private router: Router, + public dialog: MatDialog, + private snackBar: MatSnackBar, + ) { + this.invoice.set(this.invoiceService.getInvoiceList()); + + const maxId = Math.max.apply( + Math, + this.invoiceService.getInvoiceList().map((o) => o.id) + ); + this.invoice.set({ + id: maxId + 1, + status: 'Pending', + orders: [], + orderDate: new Date(), + }); + this.addForm = this.fb.group({}); + + this.rows = this.fb.array([]); + this.addForm.addControl('rows', this.rows); + this.rows.push(this.createItemFormGroup()); + } + + onAddRow(): void { + this.rows.push(this.createItemFormGroup()); + } + + onRemoveRow(rowIndex: number): void { + const totalCostOfItem = + this.addForm.get('rows')?.value[rowIndex].unitPrice * + this.addForm.get('rows')?.value[rowIndex].units; + this.subTotal.update((value) => value - totalCostOfItem); + this.vat.update((value) => this.subTotal() / 10); + this.grandTotal.update((value) => this.subTotal() + this.vat()); + this.rows.removeAt(rowIndex); + } + + createItemFormGroup(): UntypedFormGroup { + return this.fb.group({ + itemName: ['', Validators.required], + units: ['', Validators.required], + unitPrice: ['', Validators.required], + itemTotal: ['0'], + }); + } + + itemsChanged(): void { + let total: number = 0; + // tslint:disable-next-line - Disables all + for ( + let t = 0; + t < (this.addForm.get('rows')).length; + t++ + ) { + if ( + this.addForm.get('rows')?.value[t].unitPrice !== '' && + this.addForm.get('rows')?.value[t].units + ) { + total = + this.addForm.get('rows')?.value[t].unitPrice * + this.addForm.get('rows')?.value[t].units + + total; + } + } + this.subTotal.set(total); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + } + + saveDetail(event: Event): void { + event.preventDefault(); + this.invoice().grandTotal = this.grandTotal(); + this.invoice().totalCost = this.subTotal(); + this.invoice().vat = this.vat(); + + // tslint:disable-next-line - Disables all + for ( + let t = 0; + t < (this.addForm.get('rows')).length; + t++ + ) { + const o: order = new order(); + o.itemName = this.addForm.get('rows')?.value[t].itemName; + o.unitPrice = this.addForm.get('rows')?.value[t].unitPrice; + o.units = this.addForm.get('rows')?.value[t].units; + o.unitTotalPrice = o.units * o.unitPrice; + this.invoice()?.orders.push(o); + } + this.dialog.open(AddedDialogComponent); + this.invoiceService.addInvoice(this.invoice()); + this.router.navigate(['/apps/invoice']); + this.showSnackbar('Invoice added successfully!'); + + } + + showSnackbar(message: string): void { + this.snackBar.open(message, 'Close', { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } +} diff --git a/theme/packages/main/src/app/pages/apps/invoice/add-invoice/added-dialog/added-dialog.component.html b/theme/packages/main/src/app/pages/apps/invoice/add-invoice/added-dialog/added-dialog.component.html new file mode 100644 index 0000000..8a92920 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/add-invoice/added-dialog/added-dialog.component.html @@ -0,0 +1,9 @@ + + + + +

Invoice Successfully Updated.

+ +
+ +
diff --git a/theme/packages/main/src/app/pages/apps/invoice/add-invoice/added-dialog/added-dialog.component.ts b/theme/packages/main/src/app/pages/apps/invoice/add-invoice/added-dialog/added-dialog.component.ts new file mode 100644 index 0000000..581b774 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/add-invoice/added-dialog/added-dialog.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; + +@Component({ + selector: 'app-added-dialog', + templateUrl: './added-dialog.component.html', + imports: [MatDialogModule, MatButtonModule] +}) +export class AddedDialogComponent { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html b/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html new file mode 100644 index 0000000..f5f0397 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html @@ -0,0 +1,239 @@ + + + @if( invoice()) { + +
+
+
+

+ # + + {{ invoice().id }} +

+
+
+ + Cancel + + + +
+
+ + + +
+
+ Order Status: + + + Pending + Shipped + Delivered + + +
+
+
+ Order Date +
+ {{ invoice().orderDate | date : "dd-MM-yyyy" }} +
+
+
+
+ + + +
+
+ + Bill From + + +
+
+ + Bill To + + +
+
+ + Enter From Address + + +
+
+ + Bill From + + +
+
+
+
+ } + +
+
+ + + + + + + + + + + + + @for(a of addForm.get('item')['controls']; track a; let i =$index) { + + + + + + + + + + + + } +
#Item NameUnit PriceUnitsUnit Total Price
+ {{ i + 1 }} + + + + + + + + + + + + + + + + + + + + @if(addForm.get('item')?.length > 1) { + + } +
+
+ +
+
+ @if(addForm.get('rows')) { + + } + +
Sub total: {{ subTotal() }}
+
Total Vat: {{ vat() }}%
+ +

Grand Total: {{ grandTotal() }}

+
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts b/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts new file mode 100644 index 0000000..3e5b5b4 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts @@ -0,0 +1,164 @@ +import { Component, signal } from '@angular/core'; +import { ActivatedRoute, Router, RouterLink } from '@angular/router'; +import { InvoiceService } from 'src/app/services/apps/invoice/invoice.service'; +import { InvoiceList, order } from '../invoice'; +import { + UntypedFormGroup, + UntypedFormArray, + UntypedFormBuilder, + Validators, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { OkDialogComponent } from './ok-dialog/ok-dialog.component'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatSnackBar } from '@angular/material/snack-bar'; +@Component({ + selector: 'app-edit-invoice', + templateUrl: './edit-invoice.component.html', + imports: [ + MaterialModule, + CommonModule, + RouterLink, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ], +}) +export class AppEditInvoiceComponent { + id = signal(null); + subTotal = signal(0); + vat = signal(0); + grandTotal = signal(0); + addForm: UntypedFormGroup | any; + invoice = signal([]); + constructor( + activatedRouter: ActivatedRoute, + private invoiceService: InvoiceService, + private router: Router, + private fb: UntypedFormBuilder, + public dialog: MatDialog, + private snackBar: MatSnackBar + ) { + this.id.set(activatedRouter.snapshot.paramMap.get('id')); + this.loadInvoice(); // Load invoice here + this.subTotal.set(this.invoice()?.totalCost || 0); + this.vat.set(this.invoice()?.vat || 0); + this.grandTotal.set(this.invoice()?.grandTotal || 0); + this.addForm = this.fb.group({ + item: this.fb.array([this.itemControl()]), + }); + + this.fillAddControls(); + } + + loadInvoice(): void { + const invoiceData = this.invoiceService + .getInvoiceList() + .find((x) => x.id === +this.id()); + this.invoice.set(invoiceData); // Set the invoice signal + } + itemControl(): UntypedFormGroup { + return this.fb.group({ + itemName: ['', Validators.required], + itemCost: ['', Validators.required], + itemSold: ['', Validators.required], + itemTotal: [{ value: 0, disabled: true }], + }); + } + + fillAddControls(): void { + this.addForm.setControl('item', this.setItem(this.invoice()?.orders)); + } + + setItem(order: any): UntypedFormArray { + const fa = new UntypedFormArray([]); + order?.forEach((s: any) => { + fa.push( + this.fb.group({ + itemName: s.itemName, + itemCost: s.unitPrice, + itemSold: s.units, + itemTotal: s.unitTotalPrice, + }) + ); + }); + return fa; + } + + btnAddItemClick(): void { + (this.addForm.get('item')).push(this.itemControl()); + } + + btnRemoveClick(i: number): void { + const totalCostOfItem = + this.addForm.get('item')?.value[i].itemCost * + this.addForm.get('item')?.value[i].itemSold; + + this.subTotal.set(this.subTotal() - totalCostOfItem); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + + (this.addForm.get('item')).removeAt(i); + } + + itemsChanged(): void { + let total = 0; + for ( + let t = 0; + t < (this.addForm.get('item')).length; + t++ + ) { + if ( + this.addForm.get('item')?.value[t].itemCost != '' && + this.addForm.get('item')?.value[t].itemSold + ) { + total += + this.addForm.get('item')?.value[t].itemCost * + this.addForm.get('item')?.value[t].itemSold; + } + } + this.subTotal.set(total); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + } + + saveDetail(event: Event): void { + event.preventDefault(); + const currentInvoice = this.invoice(); + if (currentInvoice) { + currentInvoice.grandTotal = this.grandTotal(); + currentInvoice.totalCost = this.subTotal(); + currentInvoice.vat = this.vat(); + currentInvoice.orders = []; + + for ( + let t = 0; + t < (this.addForm.get('item')).length; + t++ + ) { + const o: order = new order(); + o.itemName = this.addForm.get('item')?.value[t].itemName; + o.unitPrice = this.addForm.get('item')?.value[t].itemCost; + o.units = this.addForm.get('item')?.value[t].itemSold; + o.unitTotalPrice = o.units * o.unitPrice; + currentInvoice.orders.push(o); + } + this.dialog.open(OkDialogComponent); + this.invoiceService.updateInvoice(currentInvoice.id, currentInvoice); + this.router.navigate(['/apps/invoice/list']); + this.showSnackbar('Invoice updated successfully!'); + } + } + + showSnackbar(message: string): void { + this.snackBar.open(message, 'Close', { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } +} diff --git a/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/ok-dialog/ok-dialog.component.html b/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/ok-dialog/ok-dialog.component.html new file mode 100644 index 0000000..52423a8 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/ok-dialog/ok-dialog.component.html @@ -0,0 +1,8 @@ + + + + +

Invoice Successfully Updated.

+ + + diff --git a/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/ok-dialog/ok-dialog.component.ts b/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/ok-dialog/ok-dialog.component.ts new file mode 100644 index 0000000..3fef533 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/edit-invoice/ok-dialog/ok-dialog.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; + +@Component({ + selector: 'app-ok-dialog', + templateUrl: './ok-dialog.component.html', + imports: [MatDialogModule, MatButtonModule] +}) +export class OkDialogComponent { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/apps/invoice/invoice-list/confirm-delete-dialog.component.html b/theme/packages/main/src/app/pages/apps/invoice/invoice-list/confirm-delete-dialog.component.html new file mode 100644 index 0000000..5939f6f --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/invoice-list/confirm-delete-dialog.component.html @@ -0,0 +1,8 @@ + + + +

Are you sure you want to delete this invoice?

+ + + + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/invoice/invoice-list/confirm-delete-dialog.component.ts b/theme/packages/main/src/app/pages/apps/invoice/invoice-list/confirm-delete-dialog.component.ts new file mode 100644 index 0000000..34b32fc --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/invoice-list/confirm-delete-dialog.component.ts @@ -0,0 +1,21 @@ +import { Component } from '@angular/core'; +import { MatDialogRef } from '@angular/material/dialog'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; + +@Component({ + selector: 'app-confirm-delete-dialog', + templateUrl: 'confirm-delete-dialog.component.html', + imports: [MatDialogModule, MatButtonModule] +}) +export class AppConfirmDeleteDialogComponent { + constructor(private dialogRef: MatDialogRef) {} + + onCancel(): void { + this.dialogRef.close(false); + } + + onConfirm(): void { + this.dialogRef.close(true); + } +} diff --git a/theme/packages/main/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html b/theme/packages/main/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html new file mode 100644 index 0000000..3942ba6 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html @@ -0,0 +1,281 @@ +
+
+ + +
+ +
+
+
Total
+
+ {{ allInvoices().length }} invoices +
+
+
+
+
+
+ + +
+ +
+
+
Shipped
+
+ {{ countInvoicesByStatus("Shipped") }} invoices +
+
+
+
+
+ +
+ + +
+ +
+
+
Delivered
+
+ {{ countInvoicesByStatus("Delivered") }} invoices +
+
+
+
+
+ +
+ + +
+ +
+
+
Pending
+
+ {{ countInvoicesByStatus("Pending") }} invoices +
+
+
+
+
+
+ + + +
+
+ + + + + + +
+ +
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + Id + + {{ element.id }} + + Bill From + + {{ element.billFrom }} + + Bill To + + {{ element.billTo }} + + Total Cost + + {{ element.totalCost }} + + Status + + + {{ element.status }} + + + Action + + + + + + + + + + + +
+ +
+
+
diff --git a/theme/packages/main/src/app/pages/apps/invoice/invoice-list/invoice-list.component.ts b/theme/packages/main/src/app/pages/apps/invoice/invoice-list/invoice-list.component.ts new file mode 100644 index 0000000..f593df2 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/invoice-list/invoice-list.component.ts @@ -0,0 +1,141 @@ +import { + Component, + AfterViewInit, + ViewChild, + Signal, + signal, +} from '@angular/core'; +import { InvoiceService } from 'src/app/services/apps/invoice/invoice.service'; +import { InvoiceList } from '../invoice'; +import { MatTableDataSource } from '@angular/material/table'; +import { MatSort } from '@angular/material/sort'; +import { MatPaginator } from '@angular/material/paginator'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { RouterModule } from '@angular/router'; +import { AppConfirmDeleteDialogComponent } from './confirm-delete-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +@Component({ + selector: 'app-invoice-list', + templateUrl: './invoice-list.component.html', + imports: [ + MaterialModule, + CommonModule, + RouterModule, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ] +}) +export class AppInvoiceListComponent implements AfterViewInit { + allComplete = signal(false); + invoiceList = new MatTableDataSource([]); + activeTab = signal('All'); + allInvoices = signal([]); + searchQuery = signal(''); + displayedColumns: string[] = [ + 'chk', + 'id', + 'billFrom', + 'billTo', + 'totalCost', + 'status', + 'action', + ]; + + @ViewChild(MatSort) sort: MatSort = Object.create(null); + @ViewChild(MatPaginator) paginator: MatPaginator = Object.create(null); + + constructor(private invoiceService: InvoiceService,private dialog: MatDialog, private snackBar: MatSnackBar) {} + + ngOnInit(): void { + // Fetch all invoices and initialize the data source + this.allInvoices.set(this.invoiceService.getInvoiceList()); + this.invoiceList = new MatTableDataSource(this.allInvoices()); + } + + ngAfterViewInit(): void { + this.invoiceList.paginator = this.paginator; + this.invoiceList.sort = this.sort; + } + + handleTabClick(tab: string): void { + this.activeTab.set(tab); + this.filterInvoices(); // Filter when tab is clicked + } + + filter(filterValue: string): void { + this.searchQuery.set(filterValue); + this.filterInvoices(); + } + filterInvoices(): void { + const currentTab = this.activeTab(); + const filteredInvoices = this.allInvoices().filter((invoice) => { + const matchesTab = currentTab === 'All' || invoice.status === currentTab; + + // Search filtering + const matchesSearch = + invoice.billFrom + .toLowerCase() + .includes(this.searchQuery().toLowerCase()) || + invoice.billTo.toLowerCase().includes(this.searchQuery().toLowerCase()); + + return matchesTab && matchesSearch; // Return true if both conditions are met + }); + + this.invoiceList.data = filteredInvoices; // Update the data source + this.updateAllComplete(); + } + + updateAllComplete(): void { + const allInvoices = this.invoiceList.data; + this.allComplete.set( + allInvoices.length > 0 && allInvoices.every((t) => t.completed) + ); // Update the allComplete signal + } + + someComplete(): boolean { + return ( + this.invoiceList.data.filter((t) => t.completed).length > 0 && + !this.allComplete() + ); + } + + setAll(completed: boolean): void { + this.allComplete.set(completed); + this.invoiceList.data.forEach((t) => (t.completed = completed)); + this.invoiceList._updateChangeSubscription(); + } + + countInvoicesByStatus(status: string): number { + return this.allInvoices().filter((invoice) => invoice.status === status) + .length; + } + + + deleteInvoice(id: number): void { + const dialogRef = this.dialog.open(AppConfirmDeleteDialogComponent); + + dialogRef.afterClosed().subscribe((result: any) => { + if (result) { + this.invoiceService.deleteInvoice(id); + this.allInvoices.set(this.invoiceService.getInvoiceList()); + this.filterInvoices(); + this.showSnackbar('Invoice deleted successfully!'); + } + }); + } + + showSnackbar(message: string): void { + this.snackBar.open(message, 'Close', { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } + +} diff --git a/theme/packages/main/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html b/theme/packages/main/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html new file mode 100644 index 0000000..b3bbc15 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html @@ -0,0 +1,125 @@ + + + @if(invoiceDetail()){ + +
+
+

#{{ invoiceDetail()?.id }}

+
+ +
+ +
+
+ Order Status: +
+ {{ invoiceDetail()?.status }} +
+
+
+ Order Date: +
+ {{ invoiceDetail()?.orderDate | date : "fullDate" }} +
+
+
+ +
+
+ Bill From: +
+ {{ invoiceDetail()?.billFrom }} +
+
+ {{ invoiceDetail()?.billFromEmail }} +
+
+ {{ invoiceDetail()?.billFromAddress }} +
+
+ {{ invoiceDetail()?.billFromPhone }} +
+
+
+ Bill To: +
+ {{ invoiceDetail()?.billTo }} +
+
+ {{ invoiceDetail()?.billToEmail }} +
+
+ {{ invoiceDetail()?.billToAddress }} +
+
+ {{ invoiceDetail()?.billToPhone }} +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ Item Name + + {{ element.itemName }} + + Unit Price + + {{ element.unitPrice }} + + Unit + + {{ element.units }} + + Total Cost + + {{ element.unitTotalPrice }} +
+
+ +
+
+ Sub total: {{ invoiceDetail()?.totalCost }} +
+ Vat: 10% +

+ Grand Total: {{ invoiceDetail()?.grandTotal }} +

+
+
+ } +
+
diff --git a/theme/packages/main/src/app/pages/apps/invoice/invoice-view/invoice-view.component.ts b/theme/packages/main/src/app/pages/apps/invoice/invoice-view/invoice-view.component.ts new file mode 100644 index 0000000..04f8439 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/invoice-view/invoice-view.component.ts @@ -0,0 +1,44 @@ +import { Component, signal } from '@angular/core'; +import { InvoiceService } from 'src/app/services/apps/invoice/invoice.service'; +import { InvoiceList } from '../invoice'; +import { ActivatedRoute, RouterLink } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-invoice-view', + templateUrl: './invoice-view.component.html', + imports: [ + MaterialModule, + CommonModule, + RouterLink, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ] +}) +export class AppInvoiceViewComponent { + id = signal(0); + invoiceDetail = signal(null); + displayedColumns: string[] = ['itemName', 'unitPrice', 'unit', 'total']; + + constructor( + private activatedRouter: ActivatedRoute, + private invoiceService: InvoiceService + ) {} + + ngOnInit(): void { + this.id.set(+this.activatedRouter.snapshot.paramMap.get('id')!); + + this.loadInvoiceDetail(); + } + + private loadInvoiceDetail(): void { + const invoiceList = this.invoiceService.getInvoiceList(); // Get the list of invoices + const invoiceId = this.id(); + const invoice = invoiceList.find((x) => x.id === invoiceId); + this.invoiceDetail.set(invoice || null); + } +} diff --git a/theme/packages/main/src/app/pages/apps/invoice/invoice.ts b/theme/packages/main/src/app/pages/apps/invoice/invoice.ts new file mode 100644 index 0000000..b889eaf --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/invoice.ts @@ -0,0 +1,32 @@ +export class order { + constructor( + public itemName: string = '', + public unitPrice: number = 0, + public units: number = 0, + public unitTotalPrice: number = 0 + ) {} +} + +export class InvoiceList { + constructor( + public id: number = 0, + public billFrom: string = '', + public billFromEmail: string = 'from@mail.com', + public billFromAddress: string = '', + public billFromPhone: number = 758269842, + public billFromFax: number = 0, + public billTo: string = '', + public billToEmail: string = 'to@mail.com', + public billToAddress: string = '', + public billToPhone: number = 58258855, + public billToFax: number = 0, + public orders: order[] = [], + public orderDate: Date = new Date(), + public totalCost: number = 0, + public vat: number = 0, + public grandTotal: number = 0, + public status: string = '', + public completed: boolean = false, + public isSelected: boolean = false + ) {} +} diff --git a/theme/packages/main/src/app/pages/apps/invoice/invoiceData.ts b/theme/packages/main/src/app/pages/apps/invoice/invoiceData.ts new file mode 100644 index 0000000..b6787b9 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/invoice/invoiceData.ts @@ -0,0 +1,200 @@ +import { InvoiceList } from './invoice'; + +export const invoceLists: InvoiceList[] = [ + { + id: 101, + billFrom: 'Pineapple Inc.', + billFromEmail: 'first@xabz.com', + billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.', + billFromPhone: 979796786, + billFromFax: 13, + billTo: 'Redq Inc.', + billToEmail: 'toFirst@agth.com', + billToAddress: 'Godrej garden city,Ahmedabad.', + billToPhone: 757575233, + billToFax: 76, + orders: [ + { + itemName: 'Courge', + unitPrice: 10, + units: 9, + unitTotalPrice: 90, + }, + ], + orderDate: new Date(), + totalCost: 90, + vat: 9, + grandTotal: 99, + status: 'Shipped', + completed: false, + isSelected: false, + }, + { + id: 102, + billFrom: 'Pineapple.', + billFromEmail: 'first@xabz.com', + billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.', + billFromPhone: 979796786, + billFromFax: 13, + billTo: 'ME Inc.', + billToEmail: 'toFirst@agth.com', + billToAddress: 'Godrej garden city,Ahmedabad.', + billToPhone: 757575233, + billToFax: 76, + orders: [ + { + itemName: 'Courge', + unitPrice: 10, + units: 9, + unitTotalPrice: 90, + }, + ], + orderDate: new Date(), + totalCost: 90, + vat: 9, + grandTotal: 99, + status: 'Delivered', + completed: false, + isSelected: false, + }, + { + id: 103, + billFrom: 'Incorporation.', + billFromEmail: 'first@xabz.com', + billFromAddress: 'Ahmedabad.', + billFromPhone: 979796786, + billFromFax: 13, + billTo: 'Redirwed.', + billToEmail: 'toFirst@agth.com', + billToAddress: 'Godrej garden city,Ahmedabad.', + billToPhone: 757575233, + billToFax: 76, + orders: [ + { + itemName: 'Courge', + unitPrice: 10, + units: 9, + unitTotalPrice: 90, + }, + ], + orderDate: new Date(), + totalCost: 90, + vat: 9, + grandTotal: 99, + status: 'Pending', + completed: false, + isSelected: false, + }, + { + id: 104, + billFrom: 'PineappleTimes .', + billFromEmail: 'first@xabz.com', + billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.', + billFromPhone: 979796786, + billFromFax: 13, + billTo: 'RFc.', + billToEmail: 'toFirst@agth.com', + billToAddress: 'Godrej garden city,Ahmedabad.', + billToPhone: 757575233, + billToFax: 76, + orders: [ + { + itemName: 'Courge', + unitPrice: 10, + units: 9, + unitTotalPrice: 90, + }, + ], + orderDate: new Date(), + totalCost: 90, + vat: 9, + grandTotal: 99, + status: 'Shipped', + completed: false, + isSelected: false, + }, + { + id: 105, + billFrom: 'Fortune Creation', + billFromEmail: 'first@xabz.com', + billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.', + billFromPhone: 979796786, + billFromFax: 13, + billTo: 'Soft solution.', + billToEmail: 'toFirst@agth.com', + billToAddress: 'Godrej garden city,Ahmedabad.', + billToPhone: 757575233, + billToFax: 76, + orders: [ + { + itemName: 'Courge', + unitPrice: 10, + units: 9, + unitTotalPrice: 90, + }, + ], + orderDate: new Date('2024-10-15'), + totalCost: 90, + vat: 9, + grandTotal: 99, + status: 'Delivered', + completed: false, + isSelected: false, + }, + { + id: 106, + billFrom: 'PineappleTimes .', + billFromEmail: 'first@xabz.com', + billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.', + billFromPhone: 979796786, + billFromFax: 13, + billTo: 'RFc.', + billToEmail: 'toFirst@agth.com', + billToAddress: 'Godrej garden city,Ahmedabad.', + billToPhone: 757575233, + billToFax: 76, + orders: [ + { + itemName: 'Courge', + unitPrice: 10, + units: 9, + unitTotalPrice: 90, + }, + ], + orderDate: new Date(), + totalCost: 90, + vat: 9, + grandTotal: 99, + status: 'Shipped', + completed: false, + isSelected: false, + }, + { + id: 107, + billFrom: 'Fortune Creation', + billFromEmail: 'first@xabz.com', + billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.', + billFromPhone: 979796786, + billFromFax: 13, + billTo: 'Soft solution.', + billToEmail: 'toFirst@agth.com', + billToAddress: 'Godrej garden city,Ahmedabad.', + billToPhone: 757575233, + billToFax: 76, + orders: [ + { + itemName: 'Courge', + unitPrice: 10, + units: 9, + unitTotalPrice: 90, + }, + ], + orderDate: new Date('2024-10-15'), + totalCost: 90, + vat: 9, + grandTotal: 99, + status: 'Delivered', + completed: false, + isSelected: false, + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/kanban/delete-dialog/delete-dialog.component.html b/theme/packages/main/src/app/pages/apps/kanban/delete-dialog/delete-dialog.component.html new file mode 100644 index 0000000..7754f7e --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/kanban/delete-dialog/delete-dialog.component.html @@ -0,0 +1,9 @@ + + + + +Are you sure you want to delete ? + + + + diff --git a/theme/packages/main/src/app/pages/apps/kanban/delete-dialog/delete-dialog.component.ts b/theme/packages/main/src/app/pages/apps/kanban/delete-dialog/delete-dialog.component.ts new file mode 100644 index 0000000..8c989c7 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/kanban/delete-dialog/delete-dialog.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; + +@Component({ + selector: 'app-delete-dialog', + templateUrl: './delete-dialog.component.html', + imports: [MatDialogModule, MatButtonModule] +}) +export class AppDeleteDialogComponent { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/apps/kanban/kanban-dialog.component.html b/theme/packages/main/src/app/pages/apps/kanban/kanban-dialog.component.html new file mode 100644 index 0000000..694d24d --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/kanban/kanban-dialog.component.html @@ -0,0 +1,95 @@ + +
+

{{ action }} Task

+ +
+
+
+
+ Title + + + +
+ @if(local_data.description) { +
+ Description + + + +
+ } + +
+ Property + + + Design + Mobile + UX Stage + Research + Data Science + Branding + + +
+ + @if(local_data.imageUrl || action=='Add'){ +
+ Image URL + + + +
+
+ Task Image +
+
+
+ } +
+
+
+ +
+ + +
diff --git a/theme/packages/main/src/app/pages/apps/kanban/kanban-dialog.component.ts b/theme/packages/main/src/app/pages/apps/kanban/kanban-dialog.component.ts new file mode 100644 index 0000000..8aa8c55 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/kanban/kanban-dialog.component.ts @@ -0,0 +1,49 @@ +import { CommonModule } from '@angular/common'; +import { Component, Inject, Optional } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { DatePipe } from '@angular/common'; +@Component({ + selector: 'app-kanban-dialog', + templateUrl: './kanban-dialog.component.html', + imports: [ + MaterialModule, + CommonModule, + TablerIconsModule, + FormsModule, + ReactiveFormsModule, + ], + providers: [DatePipe] +}) +export class AppKanbanDialogComponent { + action: string; + local_data: any; + + constructor( + public dialogRef: MatDialogRef, + @Optional() @Inject(MAT_DIALOG_DATA) public data: any, + private datePipe: DatePipe + ) { + this.local_data = { ...data }; + + if (data.action === 'Add') { + this.local_data.date = this.datePipe.transform(new Date(), 'd MMMM')!; + this.local_data.taskProperty = 'Design'; + this.local_data.imageUrl = '/assets/images/taskboard/kanban-img-1.jpg'; + } else if (data.action === 'Edit') { + this.local_data.imageUrl = data.imageUrl; + } + + this.action = this.local_data.action; + } + + doAction(): void { + this.dialogRef.close({ event: this.action, data: this.local_data }); + } + + closeDialog(): void { + this.dialogRef.close({ event: 'Cancel' }); + } +} diff --git a/theme/packages/main/src/app/pages/apps/kanban/kanban.component.html b/theme/packages/main/src/app/pages/apps/kanban/kanban.component.html new file mode 100644 index 0000000..e490aed --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/kanban/kanban.component.html @@ -0,0 +1,410 @@ + + +
+
+ Kanban + +
+ +
+
+
+
+
+
Todo
+
+
+
+ @for(task of todos; track task.id) { + +
+
{{ task.title }}
+ + + + + +
+
+ @if(task.imageUrl){ + {{ task.title }} image + } @if(task.description){ + {{ + task.description + }} + } +
+
+
+
+ + + {{ task.date }} +
+ + {{ task.taskProperty }} + +
+
+
+ } +
+
+
+
+
+
+
+
Inprogress
+
+
+ @for(task of inprogress; track task.id){ + +
+
{{ task.title }}
+ + + + + +
+
+ @if(task.imageUrl){ + {{ task.title }} image + } @if(task.description){ + {{ + task.description + }} + } +
+
+
+
+ + {{ task.date }} +
+ + {{ task.taskProperty }} + +
+
+
+ } +
+
+
+
+
+
+
Onhold
+
+
+ @for(task of onhold; track task.id){ + +
+
{{ task.title }}
+ + + + + +
+
+ @if(task.imageUrl){ + {{ task.title }} image + } @if(task.description){ + {{ + task.description + }} + } +
+
+
+
+ + {{ task.date }} +
+ + {{ task.taskProperty }} + +
+
+
+ } +
+
+
+
+
+
+
Completed
+
+
+ @for(task of completed; track task.id){ + +
+
{{ task.title }}
+ + + + + +
+
+ @if(task.imageUrl){ + {{ task.title }} image + } @if(task.description){ + {{ + task.description + }} + } +
+
+
+
+ + {{ task.date }} +
+ + {{ task.taskProperty }} + +
+
+
+ } +
+
+
+
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/apps/kanban/kanban.component.ts b/theme/packages/main/src/app/pages/apps/kanban/kanban.component.ts new file mode 100644 index 0000000..4e1a4ae --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/kanban/kanban.component.ts @@ -0,0 +1,129 @@ +import { Component } from '@angular/core'; +import { + CdkDragDrop, + DragDropModule, + moveItemInArray, + transferArrayItem, +} from '@angular/cdk/drag-drop'; +import { MatDialog } from '@angular/material/dialog'; +import { AppKanbanDialogComponent } from './kanban-dialog.component'; +import { AppOkDialogComponent } from './ok-dialog/ok-dialog.component'; +import { AppDeleteDialogComponent } from './delete-dialog/delete-dialog.component'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { KanbanService } from 'src/app/services/apps/kanban/kanban.service'; +import { Todos } from './kanban'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +// tslint:disable-next-line - Disables all + +@Component({ + selector: 'app-kanban', + templateUrl: './kanban.component.html', + imports: [ + MaterialModule, + CommonModule, + TablerIconsModule, + DragDropModule, + NgScrollbarModule, + ] +}) +export class AppKanbanComponent { + todos: Todos[] = []; + inprogress: Todos[] = []; + completed: Todos[] = []; + onhold: Todos[] = []; + + constructor( + public dialog: MatDialog, + public taskService: KanbanService, + private snackBar: MatSnackBar + ) { + this.loadTasks(); + } + + loadTasks(): void { + const allTasks = this.taskService.getAllTasks(); + + this.todos = allTasks.todos; + this.inprogress = allTasks.inProgress; + this.completed = allTasks.completed; + this.onhold = allTasks.onHold; + } + + drop(event: CdkDragDrop): void { + if (event.previousContainer === event.container) { + moveItemInArray( + event.container.data, + event.previousIndex, + event.currentIndex + ); + } else { + transferArrayItem( + event.previousContainer.data, + event.container.data, + event.previousIndex, + event.currentIndex + ); + } + } + + openDialog(action: string, obj: any): void { + obj.action = action; + + const dialogRef = this.dialog.open(AppKanbanDialogComponent, { + data: obj, + autoFocus: false, + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result.event === 'Add') { + this.taskService.addTask(result.data); + this.loadTasks(); + this.dialog.open(AppOkDialogComponent); + this.showSnackbar('Task added successfully!'); + } + if (result.event === 'Edit') { + this.taskService.editTask(result.data); + this.loadTasks(); + } + }); + } + + deleteTask(t: Todos) { + const del = this.dialog.open(AppDeleteDialogComponent); + + del.afterClosed().subscribe((result) => { + if (result === 'true') { + this.taskService.deleteTask(t.id); + this.loadTasks(); + this.showSnackbar('Task deleted successfully!'); + } + }); + } + + showSnackbar(message: string): void { + this.snackBar.open(message, 'Close', { + duration: 2000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } + //taskProperty bgcolor + getTaskClass(taskProperty: string | any): any { + return taskProperty === 'Design' + ? 'bg-success' + : taskProperty === 'Mobile' + ? 'bg-primary' + : taskProperty === 'UX Stage' + ? 'bg-warning' + : taskProperty === 'Research' + ? 'bg-error' + : taskProperty === 'Data Science' + ? 'bg-secondary' + : taskProperty === 'Branding' + ? 'bg-primary' + : ''; + } +} diff --git a/theme/packages/main/src/app/pages/apps/kanban/kanban.ts b/theme/packages/main/src/app/pages/apps/kanban/kanban.ts new file mode 100644 index 0000000..3bc466d --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/kanban/kanban.ts @@ -0,0 +1,9 @@ +export interface Todos { + id: number; + title: string; + description: string; + class?: string; + date?: string; + taskProperty?: string; + imageUrl?: string; +} diff --git a/theme/packages/main/src/app/pages/apps/kanban/kanbanData.ts b/theme/packages/main/src/app/pages/apps/kanban/kanbanData.ts new file mode 100644 index 0000000..4854b5e --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/kanban/kanbanData.ts @@ -0,0 +1,115 @@ +import { Todos } from './kanban'; + +export const todos: Todos[] = [ + { + id: 1, + title: 'Launch new template', + description: '', + date: '4 july', + taskProperty: 'Design', + imageUrl: '/assets/images/taskboard/kanban-img-1.jpg', + }, + { + id: 2, + title: 'Book a Ticket', + description: 'Blandit tempus porttitor aasfs.', + date: '24 july', + taskProperty: 'Mobile', + imageUrl: '', + }, + { + id: 3, + title: 'Task review', + description: '', + class: 'task-status-info', + date: '14 july', + taskProperty: 'UX Stage', + imageUrl: '', + }, +]; + +export const inprogress: Todos[] = [ + { + id: 201, + title: 'Website Design', + description: '', + date: '14 july', + taskProperty: 'Research', + imageUrl: '', + }, + { + id: 202, + title: 'Angular 5 material', + description:'', + class: 'task-status-danger', + date: '24 july', + taskProperty: 'Data Science', + imageUrl: '/assets/images/taskboard/kanban-img-2.jpg', + }, + { + id: 203, + title: 'Horizontal Layoutbug', + description: '', + class: 'task-status-info', + date: '10 july', + taskProperty: 'UX Stage', + imageUrl: '', + }, +]; + +export const completed: Todos[] = [ + { + id: 301, + title: 'Design work', + description:'', + date: '11 july', + taskProperty: 'Data Science', + imageUrl: '/assets/images/taskboard/kanban-img-3.jpg', + }, + { + id: 302, + title: 'Meeting with team', + description: '', + class: 'task-status-success', + date: '12 july', + taskProperty: 'Branding', + imageUrl: '', + }, + { + id: 303, + title: 'Material Pro angular', + description: '', + date: '15 july', + taskProperty: 'Research', + imageUrl: '', + }, + { + id: 304, + title: 'Learning Angular 5', + description: 'Task is now completed to learn angular5', + class: 'task-status-success', + date: '26 july', + taskProperty: 'Design', + imageUrl: '', + }, +]; + +export const onhold: Todos[] = [ + { + id: 401, + title: 'Use gradient or not', + description: 'Need approval on whether to use gradient or make it plain', + date: '12 july', + taskProperty: 'Branding', + imageUrl: '', + }, + { + id: 402, + title: 'Give review on the product', + description: '', + class: 'task-status-danger', + date: '11 july', + taskProperty: 'Mobile', + imageUrl: '/assets/images/taskboard/kanban-img-4.jpg', + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/kanban/ok-dialog/ok-dialog.component.html b/theme/packages/main/src/app/pages/apps/kanban/ok-dialog/ok-dialog.component.html new file mode 100644 index 0000000..553754b --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/kanban/ok-dialog/ok-dialog.component.html @@ -0,0 +1,8 @@ + + + + +Task Successfully Added. + + + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/kanban/ok-dialog/ok-dialog.component.ts b/theme/packages/main/src/app/pages/apps/kanban/ok-dialog/ok-dialog.component.ts new file mode 100644 index 0000000..3663dcc --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/kanban/ok-dialog/ok-dialog.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; + +@Component({ + selector: 'app-ok-dialog', + templateUrl: './ok-dialog.component.html', + imports: [MatDialogModule, MatButtonModule] +}) +export class AppOkDialogComponent { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/apps/notes/note.ts b/theme/packages/main/src/app/pages/apps/notes/note.ts new file mode 100644 index 0000000..7f76306 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/notes/note.ts @@ -0,0 +1,5 @@ +export interface Note { + color: string; + title: string; + datef: Date; +} diff --git a/theme/packages/main/src/app/pages/apps/notes/notes.component.html b/theme/packages/main/src/app/pages/apps/notes/notes.component.html new file mode 100644 index 0000000..26dfc3d --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/notes/notes.component.html @@ -0,0 +1,128 @@ + + + +
+ + + + + + +
+ +

All Notes

+ + + @if(notes().length > 0) { @for(note of notes(); track note.datef) { + + {{ note.title }} +
+ {{ + note.datef | date + }} + + + +
+
+ } } @else { +
+ No Notes Found +
+ } +
+
+
+ +
+ + +
+
+ + + @if(selectedNote()){ +
+

Edit Note

+ + + +

Change Note Color

+
+ @for(c of colors; track c.colorName) { +
+ + @if(selectedColor() === c.colorName) { +
+ check +
+ } +
+ } +
+
+ } @else{ + +
+
+ +

No note selected

+
+
+ } +
+
+
+
diff --git a/theme/packages/main/src/app/pages/apps/notes/notes.component.scss b/theme/packages/main/src/app/pages/apps/notes/notes.component.scss new file mode 100644 index 0000000..45971c1 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/notes/notes.component.scss @@ -0,0 +1,92 @@ +.note { + position: relative; + padding: 1rem 0; + width: 100%; +} + +.notes-item { + transition: all 0.1s ease-in 0s; + transform: scale(0.95); + + &.mdc-list-item:hover::before { + background-color: inherit !important; + } +} + +.notes-item.selected { + transition: all 0.1s ease-in 0s; + transform: scale(1); + + &.mdc-list-item:hover::before { + background-color: inherit !important; + } +} + +.note-title { + width: 175px; + height: 35px; + font-size: 16px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.note-title, +.note-time { + display: block; +} + +.note-content { + border: none; + resize: none; + padding: 15px; +} + +.remove-note { + margin-left: auto; +} + +.remove-note, +.notes-item { + cursor: pointer; +} + +.notes-app { + .color-button { + min-width: 20px !important; + padding: 0 !important; + } + + .mat-list-base .mat-list-item, + .mat-list-base .mat-list-option { + height: auto !important; + } + + .mat-list-base { + padding-top: 0 !important; + } + + .mat-input-element { + box-sizing: border-box; + } +} + + +.Selectbuttoncolor { + position: relative; +} + + +.checkIcon { + position: absolute; + top: 11px; + left: 8px; + color: white; + font-size: 12px; + overflow: hidden; +} + +.selectColorResizable { + width: 27px !important; + height: 27px !important; +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/notes/notes.component.ts b/theme/packages/main/src/app/pages/apps/notes/notes.component.ts new file mode 100644 index 0000000..97ae9d8 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/notes/notes.component.ts @@ -0,0 +1,140 @@ +import { Component, OnInit, signal } from '@angular/core'; +import { Note } from './note'; +import { NoteService } from 'src/app/services/apps/notes/note.service'; +import { CommonModule } from '@angular/common'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MaterialModule } from 'src/app/material.module'; +import { MatSnackBar } from '@angular/material/snack-bar'; +@Component({ + selector: 'app-notes', + templateUrl: './notes.component.html', + styleUrls: ['./notes.component.scss'], + imports: [ + CommonModule, + NgScrollbarModule, + TablerIconsModule, + FormsModule, + ReactiveFormsModule, + MaterialModule, + ] +}) +export class AppNotesComponent implements OnInit { + sidePanelOpened = signal(true); + + notes = signal([]); + + selectedNote = signal(null); + + active = signal(false); + + searchText = signal(''); + + clrName = signal('warning'); + + colors = [ + { colorName: 'primary' }, + { colorName: 'warning' }, + { colorName: 'secondary' }, + { colorName: 'error' }, + { colorName: 'success' }, + ]; + + currentNoteTitle = signal(''); + selectedColor = signal(null); + + constructor(public noteService: NoteService, private snackBar: MatSnackBar) {} + + ngOnInit(): void { + this.notes.set(this.noteService.getNotes()); + this.selectedNote.set(this.notes()[0]); + const currentNote = this.selectedNote(); + if (currentNote) { + this.selectedColor.set(currentNote.color); + this.clrName.set(currentNote.color); + this.currentNoteTitle.set(currentNote.title); + } + } + + get currentNote(): Note | null { + return this.selectedNote(); + } + + applyFilter(event: Event): void { + const filterValue = (event.target as HTMLInputElement).value; + this.notes.set(this.filter(filterValue)); + } + + filter(v: string): Note[] { + return this.noteService + .getNotes() + .filter((x) => x.title.toLowerCase().includes(v.toLowerCase())); + } + + isOver(): boolean { + return window.matchMedia(`(max-width: 960px)`).matches; + } + + onSelect(note: Note): void { + this.selectedNote.set(note); + this.clrName.set(note.color); + this.currentNoteTitle.set(note.title); + this.selectedColor.set(note.color); + } + + onSelectColor(colorName: string): void { + this.clrName.set(colorName); + this.selectedColor.set(colorName); + const currentNote = this.selectedNote(); + if (currentNote) { + currentNote.color = this.clrName(); + this.noteService.updateNote(currentNote); + } + this.active.set(!this.active()); + } + + removenote(note: Note): void { + this.noteService.removeNote(note); + this.notes.set(this.noteService.getNotes()); + + if (this.selectedNote() === note) { + this.selectedNote.set(null); + this.currentNoteTitle.set(''); + } + this.openSnackBar('Note deleted successfully!'); + } + + addNoteClick(): void { + const newNote: Note = { + color: this.clrName(), + title: 'This is a new note', + datef: new Date(), + }; + this.noteService.addNote(newNote); + this.notes.set(this.noteService.getNotes()); + + this.openSnackBar('Note added successfully!'); + } + + updateNoteTitle(newTitle: string): void { + const currentNote = this.selectedNote(); + if (currentNote) { + currentNote.title = newTitle; + this.noteService.updateNote(currentNote); + this.notes.set(this.noteService.getNotes()); + } + } + + openSnackBar( + message: string, + action: string = 'Close', + type: 'create' | 'delete' = 'create' + ): void { + this.snackBar.open(message, action, { + duration: 2000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } +} diff --git a/theme/packages/main/src/app/pages/apps/notes/notesData.ts b/theme/packages/main/src/app/pages/apps/notes/notesData.ts new file mode 100644 index 0000000..2bb49d9 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/notes/notesData.ts @@ -0,0 +1,28 @@ +import { Note } from './note'; + +export const notes: Note[] = [ + { + color: 'primary', + title: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', + datef: new Date('1/3/2024'), + }, + { + color: 'error', + title: + 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,', + datef: new Date('1/2/2024'), + }, + { + color: 'warning', + title: + 'consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?', + datef: new Date('1/1/2024'), + }, + { + color: 'success', + title: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', + datef: new Date('1/4/2024'), + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/permission/permission.component.html b/theme/packages/main/src/app/pages/apps/permission/permission.component.html new file mode 100644 index 0000000..5914a31 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/permission/permission.component.html @@ -0,0 +1,35 @@ +
+
+ + + Rollbase Access + + You can find more detail about this from here : + + ngx-permissions + + + + + Admin + Manager + Guest + + +

+ Your current role: {{ currentRole | json }} +

+ +

+ Your current permissions: {{ currentPermissions | json }} +

+
+
+
+
diff --git a/theme/packages/main/src/app/pages/apps/permission/permission.component.scss b/theme/packages/main/src/app/pages/apps/permission/permission.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/main/src/app/pages/apps/permission/permission.component.ts b/theme/packages/main/src/app/pages/apps/permission/permission.component.ts new file mode 100644 index 0000000..58c7b91 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/permission/permission.component.ts @@ -0,0 +1,49 @@ +import { CommonModule } from '@angular/common'; + +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { NgxRolesService, NgxPermissionsService } from 'ngx-permissions'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-permission', + templateUrl: './permission.component.html', + styleUrls: ['./permission.component.scss'], + imports: [MaterialModule, CommonModule, FormsModule, ReactiveFormsModule, MatButtonToggleModule], + providers: [] +}) +export class AppPermissionComponent implements OnInit { + currentRole!: string; + + currentPermissions!: string[]; + + permissionsOfRole: any = { + ADMIN: ['canAdd', 'canDelete', 'canEdit', 'canRead'], + MANAGER: ['canAdd', 'canEdit', 'canRead'], + GUEST: ['canRead'], + }; + + private readonly _destroy$ = new Subject(); + + constructor( + private rolesSrv: NgxRolesService, + private permissionsSrv: NgxPermissionsService + ) {} + + ngOnInit(): void { + this.currentRole = 'ADMIN'; + this.currentPermissions = ['canAdd', 'canDelete', 'canEdit', 'canRead']; + } + + onPermissionChange() { + this.currentPermissions = this.permissionsOfRole[this.currentRole]; + this.rolesSrv.flushRolesAndPermissions(); + this.rolesSrv.addRoleWithPermissions( + this.currentRole, + this.currentPermissions + ); + } +} diff --git a/theme/packages/main/src/app/pages/apps/profile-content/followers/followers.component.html b/theme/packages/main/src/app/pages/apps/profile-content/followers/followers.component.html new file mode 100644 index 0000000..dc63b4b --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/followers/followers.component.html @@ -0,0 +1,50 @@ +
+
+
+
+
Followers
+ +
+
{{ filteredCount }}
+
+
+ + +
+ + search + + +
+
+
+ @for(followercard of filteredFollowercards(); track followercard.id){ +
+ + +
+
+ user +
+
{{ followercard.title }}
+ {{ followercard.subtext }} +
+
+ @if (followercard.status) { + + }@else { + + } + +
+
+
+
+ } +
+ +
+
diff --git a/theme/packages/main/src/app/pages/apps/profile-content/followers/followers.component.ts b/theme/packages/main/src/app/pages/apps/profile-content/followers/followers.component.ts new file mode 100644 index 0000000..913554b --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/followers/followers.component.ts @@ -0,0 +1,65 @@ +import { CommonModule } from '@angular/common'; +import { Component, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; + + + + +interface followercards { + id: number; + imgSrc: string; + title: string; + subtext: string; + status:boolean; +} +@Component({ + selector: 'app-followers', + imports: [MaterialModule,IconModule,CommonModule, FormsModule], + templateUrl: './followers.component.html', +}) +export class FollowersComponent implements OnInit{ + + followercards: followercards[] = [ + { id: 1, imgSrc: 'assets/images/profile/user-1.jpg', title: 'Andrew Grant', subtext: 'El Salvador', status: true }, + { id: 2, imgSrc: 'assets/images/profile/user-2.jpg', title: 'Leo Pratt', subtext: 'Bulgaria', status: true }, + { id: 3, imgSrc: 'assets/images/profile/user-3.jpg', title: 'Charles Nunez', subtext: 'Nepal', status: true }, + { id: 4, imgSrc: 'assets/images/profile/user-4.jpg', title: 'Andy G. Emerson', subtext: 'Honduras', status: false }, + { id: 5, imgSrc: 'assets/images/profile/user-5.jpg', title: 'Leonard Pratt', subtext: 'Romania', status: true }, + { id: 6, imgSrc: 'assets/images/profile/user-6.jpg', title: 'C. A. Nunez', subtext: 'Bhutan', status: true }, + { id: 7, imgSrc: 'assets/images/profile/user-7.jpg', title: 'Andrew G. Riley', subtext: 'Guatemala', status: false }, + { id: 8, imgSrc: 'assets/images/profile/user-8.jpg', title: 'L. P. Walters', subtext: 'Slovenia', status: true }, + { id: 9, imgSrc: 'assets/images/profile/user-9.jpg', title: 'Charlie Nunez', subtext: 'Tibet', status: true }, + { id: 10, imgSrc: 'assets/images/profile/user-10.jpg', title: 'A. Granton', subtext: 'Nicaragua', status: false }, + { id: 11, imgSrc: 'assets/images/profile/user-1.jpg', title: 'Grant Andrews', subtext: 'Costa Rica', status: true }, + { id: 12, imgSrc: 'assets/images/profile/user-2.jpg', title: 'Leo Maxwell', subtext: 'Serbia', status: false }, + { id: 13, imgSrc: 'assets/images/profile/user-3.jpg', title: 'C. Nunez Jr.', subtext: 'Lumbini', status: true }, + { id: 14, imgSrc: 'assets/images/profile/user-4.jpg', title: 'Andres G. Vidal', subtext: 'Panama', status: true }, + { id: 15, imgSrc: 'assets/images/profile/user-5.jpg', title: 'L. P. Carter', subtext: 'Croatia', status: false }, + { id: 16, imgSrc: 'assets/images/profile/user-6.jpg', title: 'Nunez Charles', subtext: 'Kathmandu', status: true }, + { id: 17, imgSrc: 'assets/images/profile/user-7.jpg', title: 'Andrew G.', subtext: 'Belize', status: true }, + { id: 18, imgSrc: 'assets/images/profile/user-8.jpg', title: 'Leo P.', subtext: 'Macedonia', status: false }, + { id: 19, imgSrc: 'assets/images/profile/user-9.jpg', title: 'Charles N.', subtext: 'Pokhara', status: true }, + { id: 20, imgSrc: 'assets/images/profile/user-10.jpg', title: 'Leon P. Travis', subtext: 'Bosnia & Herzegovina', status: true } + ]; + + searchText: string = ''; + filteredCount: number = 0; + ngOnInit() { + this.filteredFollowercards(); + + } + filteredFollowercards() { + let result = this.followercards; + if (this.searchText) { + const searchLower = this.searchText.toLowerCase(); + result = this.followercards.filter(card => + card.title.toLowerCase().includes(searchLower) || + card.subtext.toLowerCase().includes(searchLower) + ); + } + this.filteredCount = result.length; // ✅ update the count + return result; + } +} diff --git a/theme/packages/main/src/app/pages/apps/profile-content/friends/friends.component.html b/theme/packages/main/src/app/pages/apps/profile-content/friends/friends.component.html new file mode 100644 index 0000000..bc7b9a5 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/friends/friends.component.html @@ -0,0 +1,54 @@ +
+
+
+
+
Friends
+ +
+
{{ filteredCount }}
+
+
+ + + +
+ + search + + +
+
+
+
+ @for(socialcard of filteredSocialcards; track socialcard.id) { +
+ + + + {{ + socialcard.username + }} + {{ + socialcard.post + }} + +
+ + + + +
+
+
+ } +
+
diff --git a/theme/packages/main/src/app/pages/apps/profile-content/friends/friends.component.ts b/theme/packages/main/src/app/pages/apps/profile-content/friends/friends.component.ts new file mode 100644 index 0000000..d9809c1 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/friends/friends.component.ts @@ -0,0 +1,52 @@ +import { CommonModule } from '@angular/common'; +import { Component, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; + +interface socialcards { + id: number; + imgSrc: string; + username: string; + post: string; +} +@Component({ + selector: 'app-friends', + imports: [MaterialModule,IconModule,CommonModule, FormsModule], + templateUrl: './friends.component.html', +}) +export class FriendsComponent implements OnInit{ + + socialcards: socialcards[] = [ + { id: 1, imgSrc: 'assets/images/profile/user-1.jpg', username: 'Andrew Grant', post: 'Technology Director' }, + { id: 2, imgSrc: 'assets/images/profile/user-2.jpg', username: 'Leo Pratt', post: 'Senior Tech Lead' }, + { id: 3, imgSrc: 'assets/images/profile/user-3.jpg', username: 'Charles Nunez', post: 'Digital Solutions Head' }, + { id: 4, imgSrc: 'assets/images/profile/user-4.jpg', username: 'Andy G. Emerson', post: 'Tech Infrastructure Lead' }, + { id: 5, imgSrc: 'assets/images/profile/user-5.jpg', username: 'Leonard Pratt', post: 'Chief Systems Architect' }, + { id: 6, imgSrc: 'assets/images/profile/user-6.jpg', username: 'C. A. Nunez', post: 'Innovation Manager' }, + { id: 7, imgSrc: 'assets/images/profile/user-7.jpg', username: 'Andrew G. Riley', post: 'Technical Strategy Head' }, + { id: 8, imgSrc: 'assets/images/profile/user-8.jpg', username: 'L. P. Walters', post: 'Principal Engineer' }, + { id: 9, imgSrc: 'assets/images/profile/user-9.jpg', username: 'Charlie Nunez', post: 'Technology Advisor' }, + { id: 10, imgSrc: 'assets/images/profile/user-10.jpg', username: 'A. Granton', post: 'Digital Transformation Lead' }, + { id: 12, imgSrc: 'assets/images/profile/user-2.jpg', username: 'Leo P. Maxwell', post: 'Platform Engineering Lead' }, + { id: 13, imgSrc: 'assets/images/profile/user-3.jpg', username: 'C. Nunez Jr.', post: 'Director of Tech Ops' }, + { id: 14, imgSrc: 'assets/images/profile/user-1.jpg', username: 'Grant Andrews', post: 'Tech Division Manager' }, + { id: 15, imgSrc: 'assets/images/profile/user-2.jpg', username: 'Leo P.', post: 'Solutions Architect' }, + { id: 16, imgSrc: 'assets/images/profile/user-3.jpg', username: 'Charles N.', post: 'Cloud Strategy Lead' } + ]; + + ngOnInit(): void { + this.applyFilter(); + } + searchText: string = ''; + filteredCount: number = 0; +filteredSocialcards: socialcards[] = []; +applyFilter() { + const searchLower = this.searchText.toLowerCase(); + this.filteredSocialcards = this.socialcards.filter(card => + card.username.toLowerCase().includes(searchLower) || + card.post.toLowerCase().includes(searchLower) + ); + this.filteredCount = this.filteredSocialcards.length; // ✅ update count here +} +} diff --git a/theme/packages/main/src/app/pages/apps/profile-content/gallery/gallery.component.html b/theme/packages/main/src/app/pages/apps/profile-content/gallery/gallery.component.html new file mode 100644 index 0000000..09cb789 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/gallery/gallery.component.html @@ -0,0 +1,54 @@ + diff --git a/theme/packages/main/src/app/pages/apps/profile-content/gallery/gallery.component.ts b/theme/packages/main/src/app/pages/apps/profile-content/gallery/gallery.component.ts new file mode 100644 index 0000000..7d5a502 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/gallery/gallery.component.ts @@ -0,0 +1,57 @@ +import { CommonModule } from '@angular/common'; +import { Component, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; + +interface productcards { + id: number; + imgSrc: string; + title: string; + price: string; + rprice: string; + date:string; +} + +@Component({ + selector: 'app-gallery', + imports: [MaterialModule,IconModule,CommonModule, FormsModule], + templateUrl: './gallery.component.html', +}) +export class GalleryComponent implements OnInit { + + searchText: string = ''; + +filteredCards: productcards[] = []; + + productcards: productcards[] = [ + { id: 1, imgSrc: 'assets/images/products/s1.jpg', title: 'Boat Headphone', price: '285', rprice: '375', date: 'Tue, Apr 03, 2025' }, + { id: 2, imgSrc: 'assets/images/products/s2.jpg', title: 'MacBook Air Pro', price: '285', rprice: '375', date: 'Tue, Apr 10, 2025' }, + { id: 3, imgSrc: 'assets/images/products/s3.jpg', title: 'Red Velvet Dress', price: '285', rprice: '375', date: 'Tue, Apr 15, 2025' }, + { id: 4, imgSrc: 'assets/images/products/s4.jpg', title: 'Soft Plush Teddy', price: '285', rprice: '375', date: 'Tue, Apr 12, 2025' }, + { id: 5, imgSrc: 'assets/images/products/s5.jpg', title: 'Boat Bass Booster', price: '285', rprice: '375', date: 'Tue, Apr 14, 2025' }, + { id: 6, imgSrc: 'assets/images/products/s6.jpg', title: 'MacBook Ultra Slim', price: '285', rprice: '375', date: 'Tue, Apr 18, 2025' }, + { id: 7, imgSrc: 'assets/images/products/s7.jpg', title: 'Crimson Party Dress', price: '285', rprice: '375', date: 'Tue, Apr 20, 2025' }, + { id: 8, imgSrc: 'assets/images/products/s8.jpg', title: 'Cuddly Teddy Gift', price: '285', rprice: '375', date: 'Tue, Apr 22, 2025' }, + { id: 9, imgSrc: 'assets/images/products/s9.jpg', title: 'Boat Sonic Headset', price: '285', rprice: '375', date: 'Tue, Apr 25, 2025' }, + { id: 10, imgSrc: 'assets/images/products/s10.jpg', title: 'MacBook Pro 2025', price: '285', rprice: '375', date: 'Tue, Apr 27, 2025' }, + { id: 11, imgSrc: 'assets/images/products/s1.jpg', title: 'Evening Gown - Red', price: '285', rprice: '375', date: 'Tue, Apr 29, 2025' }, + { id: 12, imgSrc: 'assets/images/products/s2.jpg', title: 'Fluffy Bear Surprise', price: '285', rprice: '375', date: 'Tue, Apr 30, 2025' }, + { id: 13, imgSrc: 'assets/images/products/s2.jpg', title: 'Boat Audio Pro', price: '285', rprice: '375', date: 'Tue, Apr 03, 2025' }, + { id: 14, imgSrc: 'assets/images/products/s3.jpg', title: 'MacBook Studio Edition', price: '285', rprice: '375', date: 'Tue, Apr 10, 2025' }, + { id: 15, imgSrc: 'assets/images/products/s4.jpg', title: 'Ruby Cocktail Dress', price: '285', rprice: '375', date: 'Tue, Apr 15, 2025' }, + { id: 16, imgSrc: 'assets/images/products/s5.jpg', title: 'Tiny Bear Hug Toy', price: '285', rprice: '375', date: 'Tue, Apr 18, 2025' } + ]; + + ngOnInit(): void { + this.filteredCards = [...this.productcards]; + } + filterCards() { + const text = this.searchText.toLowerCase(); + + this.filteredCards = this.productcards.filter(card => + card.title.toLowerCase().includes(text) || + card.date.toLowerCase().includes(text) + ); + } +} diff --git a/theme/packages/main/src/app/pages/apps/profile-content/profile-content.component.html b/theme/packages/main/src/app/pages/apps/profile-content/profile-content.component.html new file mode 100644 index 0000000..d51b004 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/profile-content.component.html @@ -0,0 +1,118 @@ +
+
+ + + Profile Cover + +
+
+
+
+ +
938
+

Posts

+
+
+ +
3,586
+

Followers

+
+
+ +
2,659
+

Following

+
+
+
+
+
+
+
+ user +
+
+
+

Mathew Anderson

+

Designer

+
+
+
+
+ +
+
+ + + + +
+ + + + + Profile + + + + + + + Followers + + + + + + + Friends + + + + + + + Gallery + + + +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/profile-content/profile-content.component.scss b/theme/packages/main/src/app/pages/apps/profile-content/profile-content.component.scss new file mode 100644 index 0000000..4fdca8d --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/profile-content.component.scss @@ -0,0 +1,44 @@ +.profileContent { + .profileCard { + + .profile-img-container { + + .profile-border-bg { + background-image: linear-gradient(#50b2fc, #f44c66); + width: 110px; + height: 110px; + + .profile-border { + width: 100px; + height: 100px; + border: 4px solid #ffffff; + } + } + } + + .profileTabs { + background-color: var(--mat-sys-surface-bright); + + .mat-mdc-tab.mdc-tab-indicator--active { + .mdc-tab__text-label { + color: var(--mat-sys-primary); + } + } + } + } +} + + +@media (max-width: 1279px) { + .order-1{ + order: 2; + } + + .order-2{ + order: 1; + } + + .order-3{ + order: 3; + } +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/profile-content/profile-content.component.ts b/theme/packages/main/src/app/pages/apps/profile-content/profile-content.component.ts new file mode 100644 index 0000000..8195031 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/profile-content.component.ts @@ -0,0 +1,22 @@ +import { Component } from '@angular/core'; + +import { ProfileComponent } from './profile/profile.component'; +import { FollowersComponent } from './followers/followers.component'; +import { FriendsComponent } from './friends/friends.component'; +import { GalleryComponent } from './gallery/gallery.component'; +import { MaterialModule } from 'src/app/material.module'; + + +import { CommonModule } from '@angular/common'; +import { IconModule } from 'src/app/icon/icon.module'; +@Component({ + selector: 'app-profile-content', + imports: [MaterialModule,ProfileComponent,FollowersComponent,FriendsComponent,GalleryComponent,CommonModule,IconModule ], + templateUrl: './profile-content.component.html', + styleUrl: './profile-content.component.scss' +}) +export class ProfileContentComponent { + pageTitle = 'UserProfile'; + selectedTab = 0; +} + diff --git a/theme/packages/main/src/app/pages/apps/profile-content/profile/profile.component.html b/theme/packages/main/src/app/pages/apps/profile-content/profile/profile.component.html new file mode 100644 index 0000000..e44e7d8 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/profile/profile.component.html @@ -0,0 +1,239 @@ +
+
+
+ + +
Introduction
+

+ Hello, I am Mathew Anderson. I love making websites and graphics. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. +

+
+ +
Sir, P P Institute Of Science
+
+
+ +
xyzjonathan@gmail.com
+
+
+ +
www.xyz.com
+
+
+ +
Newyork, USA - 100001
+
+
+
+ + + +
Photos
+
+ @for (topcard of topcards; track topcard; let i = $index) { + @if (i % 3 === 0 || (i - 1) % 3 === 0 || (i - 2) % 3 === 0) { +
+ users +
+ } + } +
+
+
+
+ +
+ + + + + + + + +
+ +
+ +
+ + + + +
+ + + +
+ + +
+
+ + + +
+
+
+ + @for(post of posts;track post.id){ + + + +
+ user +
{{ + post.profile.name + }}
+ + + {{ post.profile.time }} + +
+ +

{{ post.data.content }}

+ + + @if (hasFeaturedImages(post)) { + @for (image of getFeaturedImages(post); track i; let i = $index) { + featured image + } + } + + + + @if (hasOtherImages(post)) { +
+ @for (image of getOtherImages(post); track i; let i = $index) { +
+ regular image +
+ } +
+ } + + @if(post.data.video){ + + } + + +
+
+
+ + {{ post.data.likes.value }} +
+ +
+ + {{ post.data.comments.length }} +
+
+ + +
+ +
+
+ + + @for(comment of post.data.comments; track comment){ + + +
+ user + {{ + comment.profile.name + }} + + + {{ comment.profile.time }} + +
+

{{ comment.data.comment }}

+ +
+
+ + {{ comment.data.likes.value }} +
+ +
+ + + {{ comment.data.replies.length }} +
+
+
+ +
+ + @for (reply of comment.data.replies; track reply.id) { + + +
+ user + {{ reply.profile.name }} + + + {{ reply.profile.time }} + +
+ +

{{ reply.data.comment }}

+ + +
+ + {{ reply.data.likes.value }} +
+
+
+ } + } + + +
+ +
+
+ user + + + + +
+
+ +
+ } +
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/profile-content/profile/profile.component.ts b/theme/packages/main/src/app/pages/apps/profile-content/profile/profile.component.ts new file mode 100644 index 0000000..6bf3fab --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/profile/profile.component.ts @@ -0,0 +1,92 @@ +import { + Component, + ElementRef, + Inject, + OnInit, + ViewChild, +} from '@angular/core'; + + +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; + +import { MaterialModule } from 'src/app/material.module'; +import { IconModule } from 'src/app/icon/icon.module'; +// import { Post } from 'src/app/data-types/post.model'; +// import { mockPosts } from 'src/app/data-types/mock-posts'; +import { normalizeReplies } from 'src/app/utils/normalize-replies.util'; +import { mockPosts, Post, topcards } from '../profileData'; + +// interface topcards { +// img: string; +// } + + +@Component({ + selector: 'app-profile', + imports: [MaterialModule,IconModule], + templateUrl: './profile.component.html', +}) +export class ProfileComponent implements OnInit { + @ViewChild('fileInput') fileInput!: ElementRef; + constructor(private sanitizer: DomSanitizer) {} + topcards = topcards; + posts: Post[] = mockPosts; + transformedPosts: Post[] = []; + ngOnInit(): void { + this.groupImages(); + this.posts = normalizeReplies(mockPosts); + } + openFilePicker() { + if (this.fileInput) { + this.fileInput.nativeElement.click(); // Triggers the file picker + } + } + + // Handling file selection + onFileSelected(event: Event) { + const input = event.target as HTMLInputElement; + const files = input.files; + + if (files && files.length > 0) { + console.log('Selected file:', files[0]); + // Handle file (e.g., upload or display preview) + } + } + + groupedTopcards: any[] = []; + groupImages() { + const chunkSize = 3; + for (let i = 0; i < this.topcards.length; i += chunkSize) { + this.groupedTopcards.push(this.topcards.slice(i, i + chunkSize)); + } + } + trackByPost(index: number, post: any): string { + return post.id; // or any unique identifier from your post object + } + + hasFeaturedImages(post: Post): boolean { + return post.data.images.some( + (img) => 'featured' in img && img.featured === true + ); + } + + getFeaturedImages(post: Post): { img: string }[] { + return post.data.images.filter( + (img) => 'featured' in img && img.featured === true + ); + } + + hasOtherImages(post: Post): boolean { + return post.data.images.some((img) => !('featured' in img)); + } + + getOtherImages(post: Post): { img: string }[] { + return post.data.images.filter((img) => !('featured' in img)); + } + getSafeVideoUrl(videoUrl: string): SafeResourceUrl { + const videoId = videoUrl.split('?')[0]; // Just in case there's any query parameters + return this.sanitizer.bypassSecurityTrustResourceUrl( + 'https://www.youtube.com/embed/' + videoId + ); + } +} diff --git a/theme/packages/main/src/app/pages/apps/profile-content/profileData.ts b/theme/packages/main/src/app/pages/apps/profile-content/profileData.ts new file mode 100644 index 0000000..48f37c5 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/profile-content/profileData.ts @@ -0,0 +1,240 @@ +import Chance from 'chance'; + +export interface Post { + id: string; + profile: { + id: string; + avatar: string; + name: string; + time: string; + }; + data: { + content: string; + images: { + img: string; + featured?: boolean; + title?: string; + }[]; + video?: string; + likes: { + like: boolean; + value: number; + }; + comments: PostComment[]; + }; +} + +export interface PostComment { + id: string; + profile: { + id: string; + avatar: string; + name: string; + time: string; + }; + data: { + comment: string; + likes: { + like: boolean; + value: number; + }; + replies: PostComment[]; + }; +} + +interface topcards { + img: string; +} + +const chance = new Chance(); + +export const mockPosts: Post[] = [ + { + id: '1', + profile: { + id: '2', + avatar: 'assets/images/profile/user-10.jpg', + name: 'Macky Dawn', + time: '15 min ago', + }, + data: { + content: chance.paragraph({ sentences: 2 }), + images: [ + { + img: 'assets/images/products/s1.jpg', + featured: true, + }, + ], + likes: { + like: true, + value: 67, + }, + comments: [ + { + id: '3', + profile: { + id: '4', + avatar: 'assets/images/profile/user-3.jpg', + name: 'Deran Mac', + time: '8 min ago ', + }, + data: { + comment: chance.paragraph({ sentences: 2 }), + likes: { + like: true, + value: 55, + }, + replies: [], + }, + }, + { + id: '5', + profile: { + id: '6', + avatar: 'assets/images/profile/user-8.jpg', + name: 'Jonathan Bg', + time: '5 min ago ', + }, + data: { + comment: chance.paragraph({ sentences: 2 }), + likes: { + like: false, + value: 68, + }, + replies: [ + { + id: '7', + profile: { + id: '8', + avatar: 'assets/images/profile/user-2.jpg', + name: 'Carry minati', + time: 'just now ', + }, + data: { + comment: chance.paragraph({ sentences: 2 }), + likes: { + like: true, + value: 10, + }, + replies: [], + }, + }, + ], + }, + }, + ], + }, + }, + { + id: '9', + profile: { + id: '10', + avatar: 'assets/images/profile/user-2.jpg', + name: 'Carry Minati', + time: 'now', + }, + data: { + content: chance.paragraph({ sentences: 2 }), + images: [], + likes: { + like: true, + value: 1, + }, + comments: [], + }, + }, + { + id: '11', + profile: { + id: '12', + avatar: 'assets/images/profile/user-2.jpg', + name: 'Genelia Desouza', + time: '15 min ago ', + }, + data: { + content: chance.paragraph({ sentences: 2 }), + images: [ + { + img: 'assets/images/products/s2.jpg', + title: 'Image Title', + }, + { + img: 'assets/images/products/s4.jpg', + title: 'Painter', + }, + ], + likes: { + like: false, + value: 320, + }, + comments: [ + { + id: '13', + profile: { + id: '14', + avatar: 'assets/images/profile/user-3.jpg', + name: 'Ritesh Deshmukh', + time: '15 min ago ', + }, + data: { + comment: chance.paragraph({ sentences: 2 }), + likes: { + like: true, + value: 65, + }, + replies: [], + }, + }, + ], + }, + }, + { + id: '15', + profile: { + id: '16', + avatar: 'assets/images/profile/user-6.jpg', + name: 'Himesh R', + time: '15 min ago ', + }, + data: { + content: chance.paragraph({ sentences: 2 }), + images: [], + video: 'dQw4w9WgXcQ', + likes: { + like: true, + value: 129, + }, + comments: [], + }, + }, +]; + +export const topcards: topcards[] = [ + { + img: 'assets/images/profile/user-1.jpg', + }, + { + img: 'assets/images/profile/user-2.jpg', + }, + { + img: 'assets/images/profile/user-3.jpg', + }, + { + img: 'assets/images/profile/user-4.jpg', + }, + { + img: 'assets/images/profile/user-5.jpg', + }, + { + img: 'assets/images/profile/user-6.jpg', + }, + { + img: 'assets/images/profile/user-7.jpg', + }, + { + img: 'assets/images/profile/user-8.jpg', + }, + { + img: 'assets/images/profile/user-9.jpg', + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/task/date.service.ts b/theme/packages/main/src/app/pages/apps/task/date.service.ts new file mode 100644 index 0000000..faa1cf3 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/task/date.service.ts @@ -0,0 +1 @@ +import { Injectable } from '@angular/core'; diff --git a/theme/packages/main/src/app/pages/apps/task/task.component.html b/theme/packages/main/src/app/pages/apps/task/task.component.html new file mode 100644 index 0000000..e64b3be --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/task/task.component.html @@ -0,0 +1,289 @@ + + + +
+ @if(selectedST !== null) { +
+ + + +
+ @if(selectedST) { +
+ + @if(selectedST.status) { + + + } @if(!selectedST.status) { + + } +
+ } + +
+ +
+
+ + + + +
+ @if(selectedST) { +
+
+ + +
+
+
+ + +
+
+ +
+
+ + +
+ +
+
+
+
+
+
+ + +
+
+ +
+
+ +
+
+ } +
+ +
+ } +
+ + + + + +
+
+

Tasks

+
+ +
+ + + + + + + +
+
+ + + + + + + + + + + +
+ @for(st of sectionTask; track st.title; let i = $index) { +
+ + @if(st.sectionTaskType === 'section') { +
+
+ +
{{ st.title }}
+
+
+ } + + + + + @if(st.sectionTaskType === 'task') { +
+
+
+ + + + + + + +
+ + @if(st.status) { + + {{ + st.title + }} + + } + + + @if(!st.status) { +
+ {{ st.title }} +
+ } +
+ +
+
+ @if(st.priority === 'low') { + + low + + } @if(st.priority === 'high') { + + high + + } + +
+ + {{ st.dueDate }} +
+
+
+
+ } + + +
+ } +
diff --git a/theme/packages/main/src/app/pages/apps/task/task.component.scss b/theme/packages/main/src/app/pages/apps/task/task.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/main/src/app/pages/apps/task/task.component.spec.ts b/theme/packages/main/src/app/pages/apps/task/task.component.spec.ts new file mode 100644 index 0000000..1dd0129 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/task/task.component.spec.ts @@ -0,0 +1,28 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { FormsModule } from '@angular/forms'; + +import { AppTaskComponent } from './task.component'; + +describe('AppTaskComponent', () => { + let component: AppTaskComponent; + let fixture: ComponentFixture; + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [AppTaskComponent], + imports: [FormsModule], + }).compileComponents(); + }), + ); + + beforeEach(() => { + fixture = TestBed.createComponent(AppTaskComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + // it('should create', () => { + // expect(component).toBeTruthy(); + // }); +}); diff --git a/theme/packages/main/src/app/pages/apps/task/task.component.ts b/theme/packages/main/src/app/pages/apps/task/task.component.ts new file mode 100644 index 0000000..e7ae9f9 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/task/task.component.ts @@ -0,0 +1,134 @@ +import { Component, OnInit } from '@angular/core'; +import { TasksService } from './tasks-service.service'; +import { TaskSection } from './tasks'; + +import { moveItemInArray } from '@angular/cdk/drag-drop'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-task', + templateUrl: './task.component.html', + styleUrls: ['./task.component.scss'], + imports: [MaterialModule, CommonModule, TablerIconsModule] +}) +export class AppTaskComponent { + sectionTask: TaskSection[] | null = null; + selectedST: TaskSection | undefined = Object.create(null); + + count = 0; + totalcount: number | undefined = 0; + completedcount: number | undefined = 0; + titleTaskSection = ''; + borderClass = false; + + constructor(public ts: TasksService) { + this.sectionTask = ts.getSectionWiseTask(); + this.remainingTasks(); + this.totalcount = this.sectionTask?.filter( + (st) => st.sectionTaskType === 'task' + )?.length; + this.completedcount = this.sectionTask?.filter( + (st) => st.sectionTaskType === 'task' && st.status + )?.length; + } + + addTaskSection(funtion: string): void { + if ( + (document.getElementById('rightMenu') as HTMLFormElement).style.width === + '300px' + ) { + this.closeRightMenu(); + return; + } + (document.getElementById('rightMenu') as HTMLFormElement).style.width = + '300px'; + if (funtion === 'task') { + this.titleTaskSection = 'Task'; + + const task = new TaskSection(); + task.status = false; + task.sectionTaskType = 'task'; + task.title = 'Task'; + task.priority = 'normal'; + this.sectionTask?.splice(0, 0, task); + this.sectionTask?.push(task); + this.selectedST = this.sectionTask?.find((tk) => tk === task); + } else { + this.titleTaskSection = 'Section'; + const section: TaskSection = new TaskSection(); + section.status = false; + section.sectionTaskType = 'section'; + section.title = 'Section'; + section.priority = 'normal'; + this.sectionTask?.splice(0, 0, section); + this.sectionTask?.push(section); + this.selectedST = this.sectionTask?.find((sec) => sec === section); + } + this.remainingTasks(); + } + + sectionTaskSelected(selected: TaskSection): void { + if ( + (document.getElementById('rightMenu') as HTMLFormElement).style.width === + '300px' + ) { + this.closeRightMenu(); + return; + } + (document.getElementById('rightMenu') as HTMLFormElement).style.width = + '300px'; + if (selected.sectionTaskType === 'section') { + this.titleTaskSection = 'Section'; + } else { + this.titleTaskSection = 'Task'; + } + this.selectedST = selected; + this.selectedST.border = true; + } + + closeRightMenu(): void { + (document.getElementById('rightMenu') as HTMLFormElement).style.width = '0'; + if (this.selectedST !== undefined) { + this.selectedST.border = false; + } + this.selectedST = undefined; + } + + remainingTasks(): void { + this.count = 0; + if (this.sectionTask) { + for (const st of this.sectionTask) { + if (st.sectionTaskType === 'task') { + if (!st.status) { + this.count++; + } + } + } + } + } + + checkboxValue($event: any, st: TaskSection): void { + st.status = $event.currentTarget.checked; + this.remainingTasks(); + } + + deleteClick(object: TaskSection): void { + if (this.sectionTask !== null) { + this.sectionTask = this.sectionTask.filter((tks) => tks !== object); + } + this.remainingTasks(); + this.closeRightMenu(); + } + + drop(event: any): void { + if (this.sectionTask !== null) { + moveItemInArray( + this.sectionTask, + event.previousIndex, + event.currentIndex + ); + } + } +} diff --git a/theme/packages/main/src/app/pages/apps/task/tasks-data.ts b/theme/packages/main/src/app/pages/apps/task/tasks-data.ts new file mode 100644 index 0000000..e750fc2 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/task/tasks-data.ts @@ -0,0 +1,136 @@ +import { TaskSection } from './tasks'; + +export const sectionWiseTask: TaskSection[] = [ + { + Id: 101, + status: false, + title: 'Design the solution', + priority: 'normal', + dueDate: '25-05-2024', + notes: + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.", + sectionTaskType: 'section', + border: false, + }, + { + Id: 102, + status: true, + title: 'Identify resources to be monitored.', + priority: 'low', + dueDate: '25-05-2024', + notes: + 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using.', + sectionTaskType: 'task', + border: false, + }, + { + Id: 103, + status: false, + title: 'Define users and workflow', + priority: 'low', + dueDate: '25-05-2024', + notes: + "Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).", + sectionTaskType: 'task', + border: false, + }, + { + Id: 104, + status: false, + title: 'Identify event sources by resource type.', + priority: 'high', + dueDate: '25-05-2024', + notes: + 'Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words', + sectionTaskType: 'task', + border: false, + }, + { + Id: 105, + status: false, + title: 'Define the relationship between resources and business systems.', + priority: 'normal', + dueDate: '25-05-2024', + notes: + "If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.", + sectionTaskType: 'task', + border: false, + }, + { + Id: 106, + status: true, + title: 'Identify tasks and URLs by resource type.', + priority: 'high', + dueDate: '25-05-2024', + notes: + 'It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.', + sectionTaskType: 'task', + border: false, + }, + { + Id: 107, + status: false, + title: 'Prepare for implementation', + priority: 'normal', + dueDate: '31-05-2015', + notes: + 'The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33.', + sectionTaskType: 'section', + border: false, + }, + { + Id: 108, + status: true, + title: 'Identify the implementation team.', + priority: 'low', + dueDate: '14-01-2024', + notes: + 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using.', + sectionTaskType: 'task', + border: false, + }, + { + Id: 109, + status: false, + title: 'Order the server hardware for production assurance (QA).', + priority: 'low', + dueDate: '15-11-2024', + notes: + 'Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.', + sectionTaskType: 'task', + border: false, + }, + { + Id: 110, + status: false, + title: 'Order console machines.', + priority: 'low', + dueDate: '09-01-2015', + notes: + 'Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?', + sectionTaskType: 'task', + border: false, + }, + { + Id: 111, + status: true, + title: 'Order prerequisite software.', + priority: 'normal', + dueDate: '21-12-2016', + notes: + 'But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness.', + sectionTaskType: 'task', + border: false, + }, + { + Id: 112, + status: true, + title: 'Identify production LPARs.', + priority: 'high', + dueDate: '19-01-2024', + notes: + 'Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise', + sectionTaskType: 'task', + border: false, + }, +]; diff --git a/theme/packages/main/src/app/pages/apps/task/tasks-service.service.ts b/theme/packages/main/src/app/pages/apps/task/tasks-service.service.ts new file mode 100644 index 0000000..e48d234 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/task/tasks-service.service.ts @@ -0,0 +1,15 @@ +import { Injectable } from '@angular/core'; +import { sectionWiseTask } from './tasks-data'; + +@Injectable({ + providedIn: 'root', +}) +export class TasksService { + public sidebarShow = false; + + constructor() {} + + public getSectionWiseTask(): any { + return sectionWiseTask; + } +} diff --git a/theme/packages/main/src/app/pages/apps/task/tasks.ts b/theme/packages/main/src/app/pages/apps/task/tasks.ts new file mode 100644 index 0000000..39ec001 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/task/tasks.ts @@ -0,0 +1,10 @@ +export class TaskSection { + public Id = 202; + public status = false; + public title = ''; + public priority = ''; + public dueDate = ''; + public notes = ''; + public border = false; + public sectionTaskType = ''; +} diff --git a/theme/packages/main/src/app/pages/apps/tickets/ticket-dialog-content.html b/theme/packages/main/src/app/pages/apps/tickets/ticket-dialog-content.html new file mode 100644 index 0000000..19f96d5 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/tickets/ticket-dialog-content.html @@ -0,0 +1,132 @@ +@if(action !== 'Delete') { + +
+

{{action}} Ticket

+ +
+
+
+ @if(action === 'Update') { +
+ Ticket Id + + + +
+ } + +
+ Ticket Title + + + +
+
+ Ticket Subtext + + + +
+
+ Assign User + + + @for(user of users; track trackByUser(user)) { + +
+ {{ user.name }} + {{ user.name }} +
+
+ } +
+
+
+ @if(action === 'Update'){ +
+ Status + + + +
+ } @if(action === 'Update') { +
+ + Date + + + + +
+ } +
+
+
+} @else { +
+ Sure to delete {{local_data.title}}? +
+} +
+ + +
diff --git a/theme/packages/main/src/app/pages/apps/tickets/ticket.ts b/theme/packages/main/src/app/pages/apps/tickets/ticket.ts new file mode 100644 index 0000000..c28f82b --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/tickets/ticket.ts @@ -0,0 +1,10 @@ +export interface TicketElement { + id: number; + title: string; + subtext: string; + assignee: string; + imgSrc: string; + status: string; + date: string; + action?: string; +} diff --git a/theme/packages/main/src/app/pages/apps/tickets/tickets.component.html b/theme/packages/main/src/app/pages/apps/tickets/tickets.component.html new file mode 100644 index 0000000..f5d4a89 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/tickets/tickets.component.html @@ -0,0 +1,165 @@ + +
+
+ +

{{ totalCount }}

+
Total Tickets
+
+
+
+ +

+ {{ countTicketsByStatus("Inprogress") }} +

+
In Progress
+
+
+
+ +

+ {{ countTicketsByStatus("Open") }} +

+
Open
+
+
+
+ +

+ {{ countTicketsByStatus("Closed") }} +

+
Closed
+
+
+
+ + + + +
+
+ + + + + + + +
+
+ +
+
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Id{{ element.id }} + Title + +
{{ element.title }}
+ {{ + element.subtext + }} +
+ Assigned To + +
+ user + {{ element.assignee }} +
+
+ Status + + + {{ element.status }} + + Date + {{ element.date | date }} + + Action +
+
+ + +
+
diff --git a/theme/packages/main/src/app/pages/apps/tickets/tickets.component.ts b/theme/packages/main/src/app/pages/apps/tickets/tickets.component.ts new file mode 100644 index 0000000..f1b5f6c --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/tickets/tickets.component.ts @@ -0,0 +1,177 @@ +import { + Component, + OnInit, + ViewChild, + AfterViewInit, + Inject, +} from '@angular/core'; +import { MatTableDataSource, MatTable } from '@angular/material/table'; +import { + MatDialog, + MatDialogRef, + MAT_DIALOG_DATA, +} from '@angular/material/dialog'; +import { MatPaginator } from '@angular/material/paginator'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TicketService } from 'src/app/services/apps/ticket/ticket.service'; +import { TicketElement } from 'src/app/pages/apps/tickets/ticket'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +@Component({ + selector: 'app-ticket-list', + templateUrl: './tickets.component.html', + imports: [MaterialModule, CommonModule, TablerIconsModule], +}) +export class AppTicketlistComponent implements OnInit, AfterViewInit { + @ViewChild(MatTable, { static: true }) table: MatTable; + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; + + searchText: string = ''; + totalCount = 0; + Closed = 0; + Inprogress = 0; + Open = 0; + + displayedColumns: string[] = [ + 'id', + 'title', + 'assignee', + 'status', + 'date', + 'action', + ]; + + dataSource = new MatTableDataSource([]); + + constructor(private ticketService: TicketService, public dialog: MatDialog) {} + + ngOnInit(): void { + this.loadTickets(); // Load the initial tickets + } + + private loadTickets(): void { + const tickets = this.ticketService.tickets$; // Get tickets from the service + this.dataSource.data = tickets; // Set the dataSource to the tickets + + // Update counts based on the current tickets + this.updateCounts(); + } + + private updateCounts(): void { + this.totalCount = this.dataSource.data.length; + this.Open = this.countTicketsByStatus('open'); + this.Closed = this.countTicketsByStatus('closed'); + this.Inprogress = this.countTicketsByStatus('inprogress'); + } + + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + } + + onKeyup(event: KeyboardEvent): void { + const input = event.target as HTMLInputElement; + this.applyFilter(input.value); + } + applyFilter(filterValue: string): void { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + btnCategoryClick(val: string): number { + this.dataSource.filter = val.trim().toLowerCase(); + return this.dataSource.filteredData.length; + } + + openDialog(action: string, ticket: TicketElement | any): void { + const dialogRef = this.dialog.open(TicketDialogComponent, { + data: { action, ticket }, + autoFocus: false, + }); + + dialogRef.afterClosed().subscribe(() => { + this.loadTickets(); + }); + } + + countTicketsByStatus(status: string): number { + return this.dataSource.data.filter( + (ticket) => ticket.status.toLowerCase() === status.toLowerCase() + ).length; + } +} + +@Component({ + // tslint:disable-next-line - Disables all + selector: 'app-dialog-content', + templateUrl: 'ticket-dialog-content.html', + imports: [ + MaterialModule, + CommonModule, + TablerIconsModule, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ], +}) +export class TicketDialogComponent { + action: string; + local_data: TicketElement; + users: any[] = []; + dateControl = new FormControl(); + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + private ticketService: TicketService, + private snackBar: MatSnackBar + ) { + this.action = data.action; + this.local_data = { ...data.ticket }; + } + + ngOnInit(): void { + this.users = this.ticketService.getUsers(); // Get users from the service + + if (this.local_data.date) { + this.dateControl.setValue( + new Date(this.local_data.date).toISOString().split('T')[0] + ); // existing date + } else { + // Set to today's date if no existing date is available + this.dateControl.setValue(new Date().toISOString().split('T')[0]); + } + } + + doAction(): void { + this.local_data.date = this.dateControl.value; // Update local_data with the new date + + if (this.action === 'Update') { + this.ticketService.updateTicket(this.local_data); + this.openSnackBar('Ticket updated successfully!', 'Close'); + } else if (this.action === 'Add') { + this.ticketService.addTicket(this.local_data); + this.openSnackBar('Ticket added successfully!', 'Close'); + } else if (this.action === 'Delete') { + this.ticketService.deleteTicket(this.local_data.id); + this.openSnackBar('Ticket deleted successfully!', 'Close'); + } + this.dialogRef.close(); + } + + openSnackBar(message: string, action: string): void { + this.snackBar.open(message, action, { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } + closeDialog(): void { + this.dialogRef.close(); + } + + trackByUser(user: any): any { + return user.id; + } +} diff --git a/theme/packages/main/src/app/pages/apps/tickets/ticketsData.ts b/theme/packages/main/src/app/pages/apps/tickets/ticketsData.ts new file mode 100644 index 0000000..80a3516 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/tickets/ticketsData.ts @@ -0,0 +1,104 @@ +import {TicketElement} from 'src/app/pages/apps/tickets/ticket' + +export const tickets: TicketElement[] = [ + { + id: 1, + title: 'Sed ut perspiciatis unde omnis iste', + subtext: + 'ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos', + imgSrc: '/assets/images/profile/user-1.jpg', + assignee: 'Alice', + status: 'inprogress', + date: '2024-05-01', + }, + { + id: 2, + title: 'Xtreme theme dropdown issue', + subtext: + 'ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos', + assignee: 'Jonathan', + imgSrc: '/assets/images/profile/user-2.jpg', + status: 'open', + date: '2024-05-03', + }, + { + id: 3, + title: 'Header issue in material admin', + subtext: + 'ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos', + assignee: 'Smith', + imgSrc: '/assets/images/profile/user-3.jpg', + status: 'closed', + date: '2024-05-02', + }, + { + id: 4, + title: 'Sidebar issue in Nice admin', + subtext: + 'ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos', + assignee: 'Vincent', + imgSrc: '/assets/images/profile/user-4.jpg', + status: 'inprogress', + date: '2024-05-06', + }, + { + id: 5, + title: 'Elegant Theme Side Menu show OnClick', + subtext: + 'ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos', + assignee: 'Chris', + imgSrc: '/assets/images/profile/user-5.jpg', + status: 'open', + date: '2024-05-04', + }, + { + id: 6, + title: 'Header issue in admin pro admin', + subtext: + 'ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos', + assignee: 'James', + imgSrc: '/assets/images/profile/user-6.jpg', + status: 'closed', + date: '2024-05-03', + }, + { + id: 7, + title: 'Elegant Theme Side Menu OnClick', + subtext: + 'ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos', + assignee: 'Jonathan', + imgSrc: '/assets/images/profile/user-7.jpg', + status: 'inprogress', + date: '2024-05-05', + }, + { + id: 8, + title: 'adminpress Theme Side Menu not opening', + subtext: + 'ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos', + assignee: 'Smith', + imgSrc: '/assets/images/profile/user-8.jpg', + status: 'open', + date: '2024-05-04', + }, + { + id: 9, + title: 'Charts not proper in xtreme admin', + subtext: + 'ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos', + assignee: 'Markus', + imgSrc: '/assets/images/profile/user-9.jpg', + status: 'closed', + date: '2024-05-02', + }, + { + id: 10, + title: 'Psd not availabel with package', + subtext: + 'ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos', + assignee: 'Jane', + imgSrc: '/assets/images/profile/user-10.jpg', + status: 'closed', + date: '2024-05-03', + }, +]; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/apps/todo/todo.component.html b/theme/packages/main/src/app/pages/apps/todo/todo.component.html new file mode 100644 index 0000000..a066f63 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/todo/todo.component.html @@ -0,0 +1,221 @@ +
+
+ + + + + + + +

Todo App

+
+
+ + +
+ All +
+ {{ totalTodos() }} +
+
+
+ +
+ Incompleted +
+ {{ totalIncomplete() }} +
+
+
+ +
+ Completed +
+ {{ totalCompleted() }} +
+
+
+
+
+
+ + + + + +
+
+ + Mark All + +
+ + {{ remainingList() }} Tasks left +
+
+ +
+
+
+
+ + + +
+
+ +
+
+
+
+ + + @for(todo of todos(); track todo.message; let i = $index) { +
+
+
+ + {{ todo.message }} + +

+ {{ todo.date | date }} +

+
+
+ @if(!todo.edit) { +
+
+ + +
+
+ } + + + @if(todo.edit) { +
+ + + + + +
+ } +
+
+
+ + } +
+
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/apps/todo/todo.component.ts b/theme/packages/main/src/app/pages/apps/todo/todo.component.ts new file mode 100644 index 0000000..0fef7e0 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/todo/todo.component.ts @@ -0,0 +1,163 @@ +import { Component, OnInit, signal } from '@angular/core'; +import { + UntypedFormGroup, + UntypedFormBuilder, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { ToDo } from './todo'; +import { TodoService } from 'src/app/services/apps/todo/todo.service'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { MatDialog } from '@angular/material/dialog'; +import { AppDeleteDialogComponent } from '../kanban/delete-dialog/delete-dialog.component'; + +@Component({ + selector: 'app-todo', + templateUrl: './todo.component.html', + imports: [ + MaterialModule, + CommonModule, + TablerIconsModule, + FormsModule, + ReactiveFormsModule, + ] +}) + +export class AppTodoComponent implements OnInit { + sidePanelOpened = signal(true); + public showSidebar = signal(false); + inputFg: UntypedFormGroup; + selectedCategory = signal('all'); + todos = signal([]); + searchText = signal(null); + editSave = signal('Edit'); + + totalTodos = signal(0); + totalCompleted = signal(0); + totalIncomplete = signal(0); + constructor( + public fb: UntypedFormBuilder, + public snackBar: MatSnackBar, + public todoService: TodoService, + private dialog: MatDialog + ) { + this.todos.set(this.todoService.getTodos()); + } + + isOver(): boolean { + return window.matchMedia(`(max-width: 960px)`).matches; + } + + mobileSidebar(): void { + this.showSidebar.set(!this.showSidebar); + } + + ngOnInit(): void { + this.inputFg = this.fb.group({ + mess: [], + }); + const allTodos = this.todoService.getTodos(); + this.todos.set(allTodos); + this.totalTodos.set(allTodos.length); + this.totalCompleted.set( + allTodos.filter((todo) => todo.completionStatus).length + ); + this.totalIncomplete.set( + allTodos.filter((todo) => !todo.completionStatus).length + ); + } + + selectionlblClick(val: string): void { + this.selectedCategory.set(val); // Update the selected category + + // Filter todos based on the selected category + const filteredTodos = this.todoService.getTodos().filter((todo) => { + if (val === 'all') return true; + if (val === 'complete') return todo.completionStatus; + if (val === 'uncomplete') return !todo.completionStatus; + return true; + }); + + this.todos.set(filteredTodos); // Update the todos signal with filtered results + } + + addTodo(): void { + const message = this.inputFg.get('mess')?.value; + if (message) { + this.todoService.addTodo(message); // Call the service to add todo + this.inputFg.reset(); // Reset the input field + this.todos.set(this.todoService.getTodos()); + + this.totalTodos.set(this.todos().length); + this.totalCompleted.set( + this.todos().filter((todo) => todo.completionStatus).length + ); + this.totalIncomplete.set( + this.todos().filter((todo) => !todo.completionStatus).length + ); + this.openSnackBar('Todo successfully added!', 'Close'); + } + } + + openSnackBar(message: string, action: string): void { + this.snackBar.open(message, action, { + duration: 2000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } + + allTodos(): void { + const completionStatus = (event!.target).checked; + this.todos.update((todos) => + todos.map((todo) => ({ ...todo, completionStatus })) + ); + this.updateCounts(); + } + toggleTodoCompletion(todo: ToDo): void { + // Toggle the completion status directly + todo.completionStatus = !todo.completionStatus; + // Update the counts + this.updateCounts(); + } + private updateCounts(): void { + const allTodos = this.todos(); + this.totalTodos.set(allTodos.length); + this.totalCompleted.set( + allTodos.filter((todo) => todo.completionStatus).length + ); + this.totalIncomplete.set( + allTodos.filter((todo) => !todo.completionStatus).length + ); + } + + editTodo(todo: ToDo): void { + if (todo.edit) { + this.todoService.editTodo(todo.id, todo.message); + todo.edit = false; + this.openSnackBar('Todo successfully edited!', 'Close'); + this.updateCounts(); + } else { + todo.edit = true; + } + } + + deleteTodo(id: number): void { + const dialogRef = this.dialog.open(AppDeleteDialogComponent); + + dialogRef.afterClosed().subscribe((result: any) => { + if (result) { + this.todoService.deleteTodo(id); + this.todos.set(this.todoService.getTodos()); + this.updateCounts(); + this.openSnackBar('Todo successfully deleted!', 'Close'); + } + }); + } + remainingList(): number { + return this.todos().filter((todo) => !todo.completionStatus).length; + } +} diff --git a/theme/packages/main/src/app/pages/apps/todo/todo.ts b/theme/packages/main/src/app/pages/apps/todo/todo.ts new file mode 100644 index 0000000..27aa611 --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/todo/todo.ts @@ -0,0 +1,7 @@ +export class ToDo { + id = 0; + public message = ''; + public completionStatus = false; + public edit = false; + public date: Date | null = null; +} diff --git a/theme/packages/main/src/app/pages/apps/todo/todoData.ts b/theme/packages/main/src/app/pages/apps/todo/todoData.ts new file mode 100644 index 0000000..d3c2f4e --- /dev/null +++ b/theme/packages/main/src/app/pages/apps/todo/todoData.ts @@ -0,0 +1,39 @@ +import { ToDo } from './todo'; + +export const todos: ToDo[] = [ + { + id: 1, + message: 'I have to go office.', + completionStatus: true, + edit: false, + date: new Date('02-06-2024'), + }, + { + id: 2, + message: 'let us work hard this time ! ', + completionStatus: false, + edit: false, + date: new Date('02-08-2024'), + }, + { + id: 3, + message: 'We will win if we give our best.', + completionStatus: true, + edit: false, + date: new Date('02-10-2024'), + }, + { + id: 4, + message: 'We will leave soon.', + completionStatus: false, + edit: false, + date: new Date('02-12-2024'), + }, + { + id: 5, + message: 'I am doing my best.', + completionStatus: false, + edit: false, + date: new Date('02-15-2024'), + }, +]; diff --git a/theme/packages/main/src/app/pages/authentication/authentication.routes.ts b/theme/packages/main/src/app/pages/authentication/authentication.routes.ts new file mode 100644 index 0000000..f934795 --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/authentication.routes.ts @@ -0,0 +1,60 @@ +import { Routes } from '@angular/router'; + +import { AppBoxedForgotPasswordComponent } from './boxed-forgot-password/boxed-forgot-password.component'; +import { AppBoxedLoginComponent } from './boxed-login/boxed-login.component'; +import { AppBoxedRegisterComponent } from './boxed-register/boxed-register.component'; +import { AppBoxedTwoStepsComponent } from './boxed-two-steps/boxed-two-steps.component'; +import { AppErrorComponent } from './error/error.component'; +import { AppMaintenanceComponent } from './maintenance/maintenance.component'; +import { AppSideForgotPasswordComponent } from './side-forgot-password/side-forgot-password.component'; +import { AppSideLoginComponent } from './side-login/side-login.component'; +import { AppSideRegisterComponent } from './side-register/side-register.component'; +import { AppSideTwoStepsComponent } from './side-two-steps/side-two-steps.component'; + +export const AuthenticationRoutes: Routes = [ + { + path: '', + children: [ + { + path: 'boxed-forgot-pwd', + component: AppBoxedForgotPasswordComponent, + }, + { + path: 'boxed-login', + component: AppBoxedLoginComponent, + }, + { + path: 'boxed-register', + component: AppBoxedRegisterComponent, + }, + { + path: 'boxed-two-steps', + component: AppBoxedTwoStepsComponent, + }, + { + path: 'error', + component: AppErrorComponent, + }, + { + path: 'maintenance', + component: AppMaintenanceComponent, + }, + { + path: 'side-forgot-pwd', + component: AppSideForgotPasswordComponent, + }, + { + path: 'login', + component: AppSideLoginComponent, + }, + { + path: 'side-register', + component: AppSideRegisterComponent, + }, + { + path: 'side-two-steps', + component: AppSideTwoStepsComponent, + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/pages/authentication/boxed-forgot-password/boxed-forgot-password.component.html b/theme/packages/main/src/app/pages/authentication/boxed-forgot-password/boxed-forgot-password.component.html new file mode 100644 index 0000000..f4f437c --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/boxed-forgot-password/boxed-forgot-password.component.html @@ -0,0 +1,53 @@ +
+
+
+ + +
+ +
+ Please enter the email address associated with your account and We + will email you a link to reset your password. + +
+ Email Adddress + + + @if(f['email'].touched && f['email'].invalid) { + + @if(f['email'].errors && f['email'].errors['required']) { +
Email is required.
+ } +
+ } +
+ + + + Back to Login + + +
+
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/authentication/boxed-forgot-password/boxed-forgot-password.component.ts b/theme/packages/main/src/app/pages/authentication/boxed-forgot-password/boxed-forgot-password.component.ts new file mode 100644 index 0000000..fa47a79 --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/boxed-forgot-password/boxed-forgot-password.component.ts @@ -0,0 +1,42 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { + FormGroup, + FormControl, + Validators, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { Router, RouterModule } from '@angular/router'; +import { MaterialModule } from '../../../material.module'; +import { BrandingComponent } from '../../../layouts/full/vertical/sidebar/branding.component'; + +@Component({ + selector: 'app-boxed-forgot-password', + imports: [ + RouterModule, + MaterialModule, + FormsModule, + ReactiveFormsModule, + BrandingComponent, + ], + templateUrl: './boxed-forgot-password.component.html', +}) +export class AppBoxedForgotPasswordComponent { + options = this.settings.getOptions(); + + constructor(private settings: CoreService, private router: Router) {} + + form = new FormGroup({ + email: new FormControl('', [Validators.required]), + }); + + get f() { + return this.form.controls; + } + + submit() { + // console.log(this.form.value); + this.router.navigate(['/dashboards/dashboard1']); + } +} diff --git a/theme/packages/main/src/app/pages/authentication/boxed-login/boxed-login.component.html b/theme/packages/main/src/app/pages/authentication/boxed-login/boxed-login.component.html new file mode 100644 index 0000000..696efff --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/boxed-login/boxed-login.component.html @@ -0,0 +1,108 @@ +
+
+
+ + +
+ +
+ +
+
+ +
+
+ +
+
+ +
or sign in with
+ +
+ Username + + + @if(f['uname'].touched && f['uname'].invalid) { + + @if(f['uname'].errors && f['uname'].errors['required']) { +
Name is required.
+ } @if(f['uname'].errors && f['uname'].errors['minlength']) { +
Name should be 6 character.
+ } +
+ } +
+ + Password + + + @if(f['password'].touched && f['password'].invalid) { + + @if(f['password'].errors && f['password'].errors['required']) { +
Password is required.
+ } +
+ } +
+ +
+ Remember this Device + Forgot Password ? +
+ + +
+ New to Modernize? + + Create an account + +
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/authentication/boxed-login/boxed-login.component.ts b/theme/packages/main/src/app/pages/authentication/boxed-login/boxed-login.component.ts new file mode 100644 index 0000000..1580b64 --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/boxed-login/boxed-login.component.ts @@ -0,0 +1,43 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { + FormGroup, + FormControl, + Validators, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { Router, RouterModule } from '@angular/router'; +import { MaterialModule } from '../../../material.module'; +import { BrandingComponent } from '../../../layouts/full/vertical/sidebar/branding.component'; + +@Component({ + selector: 'app-boxed-login', + imports: [ + RouterModule, + MaterialModule, + FormsModule, + ReactiveFormsModule, + BrandingComponent, + ], + templateUrl: './boxed-login.component.html', +}) +export class AppBoxedLoginComponent { + options = this.settings.getOptions(); + + constructor(private settings: CoreService, private router: Router) {} + + form = new FormGroup({ + uname: new FormControl('', [Validators.required, Validators.minLength(6)]), + password: new FormControl('', [Validators.required]), + }); + + get f() { + return this.form.controls; + } + + submit() { + // console.log(this.form.value); + this.router.navigate(['/dashboards/dashboard1']); + } +} diff --git a/theme/packages/main/src/app/pages/authentication/boxed-register/boxed-register.component.html b/theme/packages/main/src/app/pages/authentication/boxed-register/boxed-register.component.html new file mode 100644 index 0000000..9519c2a --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/boxed-register/boxed-register.component.html @@ -0,0 +1,112 @@ +
+
+
+ + +
+ +
+ +
+
+ +
+
+ +
+
+ +
or sign up with
+ +
+ Name + + + @if(f['uname'].touched && f['uname'].invalid) { + + @if(f['uname'].errors && f['uname'].errors['required']) { +
Name is required.
+ } @if(f['uname'].errors && f['uname'].errors['minlength']) { +
Name should be 6 character.
+ } +
+ } +
+ Email Adddress + + + @if(f['email'].touched && f['email'].invalid) { + + @if(f['email'].errors && f['email'].errors['required']) { +
Email is required.
+ } +
+ } +
+ + Password + + + @if(f['password'].touched && f['password'].invalid) { + + @if(f['password'].errors && f['password'].errors['required']) { +
Password is required.
+ } +
+ } +
+ + + +
+ Already have an Account? + + + Sign In + +
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/authentication/boxed-register/boxed-register.component.ts b/theme/packages/main/src/app/pages/authentication/boxed-register/boxed-register.component.ts new file mode 100644 index 0000000..7377e15 --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/boxed-register/boxed-register.component.ts @@ -0,0 +1,44 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { + FormGroup, + FormControl, + Validators, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { Router, RouterModule } from '@angular/router'; +import { MaterialModule } from '../../../material.module'; +import { BrandingComponent } from '../../../layouts/full/vertical/sidebar/branding.component'; + +@Component({ + selector: 'app-boxed-register', + imports: [ + RouterModule, + MaterialModule, + FormsModule, + BrandingComponent, + ReactiveFormsModule, + ], + templateUrl: './boxed-register.component.html', +}) +export class AppBoxedRegisterComponent { + options = this.settings.getOptions(); + + constructor(private settings: CoreService, private router: Router) {} + + form = new FormGroup({ + uname: new FormControl('', [Validators.required, Validators.minLength(6)]), + email: new FormControl('', [Validators.required]), + password: new FormControl('', [Validators.required]), + }); + + get f() { + return this.form.controls; + } + + submit() { + // console.log(this.form.value); + this.router.navigate(['/dashboards/dashboard1']); + } +} diff --git a/theme/packages/main/src/app/pages/authentication/boxed-two-steps/boxed-two-steps.component.html b/theme/packages/main/src/app/pages/authentication/boxed-two-steps/boxed-two-steps.component.html new file mode 100644 index 0000000..577b48e --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/boxed-two-steps/boxed-two-steps.component.html @@ -0,0 +1,101 @@ +
+
+
+ + +
+ +
+ We sent a verification code to your mobile. Enter the code from the + mobile in the field below. + ******1234 + +
+ Type your 6 digits security code +
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + Verify My Account + + +
+ Didn't get the code? + Resend + +
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/authentication/boxed-two-steps/boxed-two-steps.component.ts b/theme/packages/main/src/app/pages/authentication/boxed-two-steps/boxed-two-steps.component.ts new file mode 100644 index 0000000..53fb594 --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/boxed-two-steps/boxed-two-steps.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { CoreService } from 'src/app/services/core.service'; +import { MaterialModule } from '../../../material.module'; +import { BrandingComponent } from '../../../layouts/full/vertical/sidebar/branding.component'; + +@Component({ + selector: 'app-boxed-two-steps', + imports: [RouterModule, MaterialModule, BrandingComponent], + templateUrl: './boxed-two-steps.component.html' +}) +export class AppBoxedTwoStepsComponent { + options = this.settings.getOptions(); + + constructor(private settings: CoreService) {} +} diff --git a/theme/packages/main/src/app/pages/authentication/error/error.component.html b/theme/packages/main/src/app/pages/authentication/error/error.component.html new file mode 100644 index 0000000..7bc4017 --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/error/error.component.html @@ -0,0 +1,10 @@ +
+
+
+ error-bg +

Opps!!!

+
This page you are looking for could not be found.
+ Go back to Home +
+
+
diff --git a/theme/packages/main/src/app/pages/authentication/error/error.component.ts b/theme/packages/main/src/app/pages/authentication/error/error.component.ts new file mode 100644 index 0000000..08c3d9c --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/error/error.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { MaterialModule } from '../../../material.module'; +import { MatButtonModule } from '@angular/material/button'; + +@Component({ + selector: 'app-error', + imports: [RouterModule, MaterialModule, MatButtonModule], + templateUrl: './error.component.html' +}) +export class AppErrorComponent {} diff --git a/theme/packages/main/src/app/pages/authentication/maintenance/maintenance.component.html b/theme/packages/main/src/app/pages/authentication/maintenance/maintenance.component.html new file mode 100644 index 0000000..835af6d --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/maintenance/maintenance.component.html @@ -0,0 +1,11 @@ +
+
+
+ error-bg +

Maintenance Mode!!!

+
Website is Under Construction. Check back later!
+ Go back to Home +
+
+
+ \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/authentication/maintenance/maintenance.component.ts b/theme/packages/main/src/app/pages/authentication/maintenance/maintenance.component.ts new file mode 100644 index 0000000..f3725da --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/maintenance/maintenance.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { MaterialModule } from '../../../material.module'; +import { MatButtonModule } from '@angular/material/button'; + +@Component({ + selector: 'app-maintenance', + imports: [RouterModule, MaterialModule, MatButtonModule], + templateUrl: './maintenance.component.html', +}) +export class AppMaintenanceComponent {} diff --git a/theme/packages/main/src/app/pages/authentication/side-forgot-password/side-forgot-password.component.html b/theme/packages/main/src/app/pages/authentication/side-forgot-password/side-forgot-password.component.html new file mode 100644 index 0000000..8bc5f5d --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/side-forgot-password/side-forgot-password.component.html @@ -0,0 +1,72 @@ +
+
+
+
+ + +
+ login +
+
+
+
+
+
+
+

Forgot your password?

+ Please enter the email address associated with your account and + We will email you a link to reset your password. + +
+ Email Adddress + + + @if(f['email'].touched && f['email'].invalid) { + + @if(f['email'].errors && f['email'].errors['required']) { +
Email is required.
+ } +
+ } +
+ + + + Back to Login + + +
+
+
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/authentication/side-forgot-password/side-forgot-password.component.ts b/theme/packages/main/src/app/pages/authentication/side-forgot-password/side-forgot-password.component.ts new file mode 100644 index 0000000..53d0b40 --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/side-forgot-password/side-forgot-password.component.ts @@ -0,0 +1,42 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { + FormGroup, + FormControl, + Validators, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { Router, RouterModule } from '@angular/router'; +import { MaterialModule } from '../../../material.module'; +import { BrandingComponent } from '../../../layouts/full/vertical/sidebar/branding.component'; + +@Component({ + selector: 'app-side-forgot-password', + imports: [ + RouterModule, + MaterialModule, + FormsModule, + ReactiveFormsModule, + BrandingComponent, + ], + templateUrl: './side-forgot-password.component.html', +}) +export class AppSideForgotPasswordComponent { + options = this.settings.getOptions(); + + constructor(private settings: CoreService, private router: Router) {} + + form = new FormGroup({ + email: new FormControl('', [Validators.required]), + }); + + get f() { + return this.form.controls; + } + + submit() { + // console.log(this.form.value); + this.router.navigate(['/dashboards/dashboard1']); + } +} diff --git a/theme/packages/main/src/app/pages/authentication/side-login/side-login.component.html b/theme/packages/main/src/app/pages/authentication/side-login/side-login.component.html new file mode 100644 index 0000000..2137e78 --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/side-login/side-login.component.html @@ -0,0 +1,138 @@ +
+
+
+
+ + +
+ login +
+
+
+
+
+
+
+

Welcome to Modernize

+ Your Admin Dashboard + +
+
+ +
+
+ +
+
+ +
or sign in with
+ +
+ Username + + + @if(f['uname'].touched && f['uname'].invalid) { + + @if(f['uname'].errors && f['uname'].errors['required']) { +
Name is required.
+ } @if(f['uname'].errors && f['uname'].errors['minlength']) { +
Name should be 6 character.
+ } +
+ } +
+ + + Password + + + @if(f['password'].touched && f['password'].invalid) { + + @if( f['password'].errors && f['password'].errors['required']) + { +
Password is required.
+ } +
+ } +
+ +
+ Remember this Device + Forgot Password ? +
+ + +
+ New to Modernize? + + Create an account + +
+
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/authentication/side-login/side-login.component.ts b/theme/packages/main/src/app/pages/authentication/side-login/side-login.component.ts new file mode 100644 index 0000000..978780d --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/side-login/side-login.component.ts @@ -0,0 +1,31 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { Router, RouterModule } from '@angular/router'; +import { MaterialModule } from '../../../material.module'; +import { BrandingComponent } from '../../../layouts/full/vertical/sidebar/branding.component'; + +@Component({ + selector: 'app-side-login', + imports: [RouterModule, MaterialModule, FormsModule, ReactiveFormsModule, BrandingComponent], + templateUrl: './side-login.component.html' +}) +export class AppSideLoginComponent { + options = this.settings.getOptions(); + + constructor(private settings: CoreService, private router: Router) { } + + form = new FormGroup({ + uname: new FormControl('', [Validators.required, Validators.minLength(6)]), + password: new FormControl('', [Validators.required]), + }); + + get f() { + return this.form.controls; + } + + submit() { + // console.log(this.form.value); + this.router.navigate(['/dashboards/dashboard1']); + } +} diff --git a/theme/packages/main/src/app/pages/authentication/side-register/side-register.component.html b/theme/packages/main/src/app/pages/authentication/side-register/side-register.component.html new file mode 100644 index 0000000..1d99c95 --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/side-register/side-register.component.html @@ -0,0 +1,146 @@ +
+
+
+
+ + +
+ login +
+
+
+
+
+
+
+

Welcome to Modernize

+ Your Admin Dashboard + +
+
+ +
+
+ +
+
+ +
or sign up with
+ +
+ Name + + + @if(f['uname'].touched && f['uname'].invalid) { + + @if(f['uname'].errors && f['uname'].errors['required']) { +
Name is required.
+ } @if(f['uname'].errors && f['uname'].errors['minlength']) { +
Name should be 6 character.
+ } +
+ } +
+ + Email Address + + + @if(f['email'].touched && f['email'].invalid) { + + @if(f['email'].errors && f['email'].errors['required']) { +
Email is required.
+ } +
+ } +
+ + Password + + + @if(f['password'].touched && f['password'].invalid) { + + @if( f['password'].errors && f['password'].errors['required']) + { +
Password is required.
+ } +
+ } +
+ + + +
+ Already have an Account? + + + Sign In + +
+
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/authentication/side-register/side-register.component.ts b/theme/packages/main/src/app/pages/authentication/side-register/side-register.component.ts new file mode 100644 index 0000000..26ef24c --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/side-register/side-register.component.ts @@ -0,0 +1,32 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { Router, RouterModule } from '@angular/router'; +import { MaterialModule } from '../../../material.module'; +import { BrandingComponent } from '../../../layouts/full/vertical/sidebar/branding.component'; + +@Component({ + selector: 'app-side-register', + imports: [RouterModule, MaterialModule, FormsModule, ReactiveFormsModule, BrandingComponent], + templateUrl: './side-register.component.html' +}) +export class AppSideRegisterComponent { + options = this.settings.getOptions(); + + constructor(private settings: CoreService, private router: Router) { } + + form = new FormGroup({ + uname: new FormControl('', [Validators.required, Validators.minLength(6)]), + email: new FormControl('', [Validators.required]), + password: new FormControl('', [Validators.required]), + }); + + get f() { + return this.form.controls; + } + + submit() { + // console.log(this.form.value); + this.router.navigate(['/dashboards/dashboard1']); + } +} diff --git a/theme/packages/main/src/app/pages/authentication/side-two-steps/side-two-steps.component.html b/theme/packages/main/src/app/pages/authentication/side-two-steps/side-two-steps.component.html new file mode 100644 index 0000000..60950fb --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/side-two-steps/side-two-steps.component.html @@ -0,0 +1,114 @@ +
+
+
+
+ + +
+ login +
+
+
+
+
+
+

Two Step Verification

+ We sent a verification code to your mobile. Enter the code from the + mobile in the field below. + ******1234 + +
+ Type your 6 digits security code +
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + Verify My Account + + +
+ Didn't get the code? + Resend + +
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/authentication/side-two-steps/side-two-steps.component.ts b/theme/packages/main/src/app/pages/authentication/side-two-steps/side-two-steps.component.ts new file mode 100644 index 0000000..a5f0d83 --- /dev/null +++ b/theme/packages/main/src/app/pages/authentication/side-two-steps/side-two-steps.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { CoreService } from 'src/app/services/core.service'; +import { MaterialModule } from '../../../material.module'; +import { BrandingComponent } from '../../../layouts/full/vertical/sidebar/branding.component'; + +@Component({ + selector: 'app-side-two-steps', + imports: [RouterModule, MaterialModule, BrandingComponent], + templateUrl: './side-two-steps.component.html', +}) +export class AppSideTwoStepsComponent { + options = this.settings.getOptions(); + + constructor(private settings: CoreService) {} +} diff --git a/theme/packages/main/src/app/pages/charts/area/area.component.html b/theme/packages/main/src/app/pages/charts/area/area.component.html new file mode 100644 index 0000000..070e758 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/area/area.component.html @@ -0,0 +1,28 @@ + + +

+ Area Chart +

+
+ + +
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/area/area.component.ts b/theme/packages/main/src/app/pages/charts/area/area.component.ts new file mode 100644 index 0000000..9d71286 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/area/area.component.ts @@ -0,0 +1,124 @@ +import { Component, ViewChild } from '@angular/core'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { AREA_CHART_HTML_SNIPPET } from './code/area-html-snippet'; +import { AREA_CHART_TS_SNIPPET } from './code/area-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; + +export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; +}; + +@Component({ + selector: 'app-area', + imports: [NgApexchartsModule, MaterialModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './area.component.html' +}) +export class AppAreaChartComponent { + // 1 [Area with Datepicker] + codeForAreaChart = AREA_CHART_HTML_SNIPPET; + codeForAreaChartTs = AREA_CHART_TS_SNIPPET; + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + + public areaChartOptions: Partial | any; + constructor() { + //Area chart. + this.areaChartOptions = { + series: [ + { + name: 'Site A', + data: [0, 300, 100, 200, 1200, 100, 500, 100], + }, + { + name: 'Site B', + data: [0, 500, 600, 800, 2800, 900, 800, 2200], + }, + ], + chart: { + fontFamily: 'inherit', + foreColor: '#a1aab2', + height: 300, + type: 'area', + toolbar: { + show: false, + }, + }, + dataLabels: { + enabled: false, + }, + markers: { + size: 3, + }, + stroke: { + curve: 'smooth', + width: '2', + }, + colors: ['#398bf7', '#06d79c'], + legend: { + show: false, + }, + grid: { + show: true, + strokeDashArray: 0, + borderColor: 'rgba(0,0,0,0.1)', + xaxis: { + lines: { + show: true, + }, + }, + yaxis: { + lines: { + show: true, + }, + }, + }, + xaxis: { + type: 'category', + categories: ['Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'], + }, + tooltip: { + theme: 'dark', + }, + }; + } +} diff --git a/theme/packages/main/src/app/pages/charts/area/code/area-html-snippet.ts b/theme/packages/main/src/app/pages/charts/area/code/area-html-snippet.ts new file mode 100644 index 0000000..fcae896 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/area/code/area-html-snippet.ts @@ -0,0 +1,6 @@ +export const AREA_CHART_HTML_SNIPPET = ` + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/area/code/area-ts-snippet.ts b/theme/packages/main/src/app/pages/charts/area/code/area-ts-snippet.ts new file mode 100644 index 0000000..a8b5a38 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/area/code/area-ts-snippet.ts @@ -0,0 +1,114 @@ +export const AREA_CHART_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, + } from 'ng-apexcharts'; + import { MaterialModule } from '../../../material.module'; + + export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; + }; + + /** + * @title Area Chart */ + */ + @Component({ + selector: 'app-area', + imports: [NgApexchartsModule, MaterialModule], + templateUrl: './area.component.html' + }) + export class AppAreaChartComponent { + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public areaChartOptions: Partial | any; + + constructor() { + //Area chart. + this.areaChartOptions = { + series: [ + { + name: 'Site A', + data: [0, 300, 100, 200, 1200, 100, 500, 100], + }, + { + name: 'Site B', + data: [0, 500, 600, 800, 2800, 900, 800, 2200], + }, + ], + chart: { + fontFamily: 'inherit', + foreColor: '#a1aab2', + height: 300, + type: 'area', + toolbar: { + show: false, + }, + }, + dataLabels: { + enabled: false, + }, + markers: { + size: 3, + }, + stroke: { + curve: 'smooth', + width: '2', + }, + colors: ['#398bf7', '#06d79c'], + legend: { + show: false, + }, + grid: { + show: true, + strokeDashArray: 0, + borderColor: 'rgba(0,0,0,0.1)', + xaxis: { + lines: { + show: true, + }, + }, + yaxis: { + lines: { + show: true, + }, + }, + }, + xaxis: { + type: 'category', + categories: ['Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'], + }, + tooltip: { + theme: 'dark', + }, + }; + } + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/candlestick/candlestick.component.html b/theme/packages/main/src/app/pages/charts/candlestick/candlestick.component.html new file mode 100644 index 0000000..493b58c --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/candlestick/candlestick.component.html @@ -0,0 +1,30 @@ + + +

+ Candlestick Chart +

+
+ + +
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/candlestick/candlestick.component.ts b/theme/packages/main/src/app/pages/charts/candlestick/candlestick.component.ts new file mode 100644 index 0000000..4132146 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/candlestick/candlestick.component.ts @@ -0,0 +1,297 @@ +import { Component, ViewChild } from '@angular/core'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { CANDLESTICK_CHART_HTML_SNIPPET } from './code/candlestick-html-snippet'; +import { CANDLESTICK_CHART_TS_SNIPPET } from './code/candlestick-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; + +export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; +}; + +@Component({ + selector: 'app-candlestick', + imports: [NgApexchartsModule, MaterialModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './candlestick.component.html' +}) +export class AppCandlestickChartComponent { + // 1 [Candlestick with Datepicker] + codeForCandlestickChart = CANDLESTICK_CHART_HTML_SNIPPET; + codeForCandlestickChartTs = CANDLESTICK_CHART_TS_SNIPPET; + + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public candlestickChartOptions: Partial | any; + + constructor() { + //doughnut chart. + this.candlestickChartOptions = { + series: [ + { + data: [ + { + x: new Date(1538778600000), + y: [6629.81, 6650.5, 6623.04, 6633.33], + }, + { + x: new Date(1538780400000), + y: [6632.01, 6643.59, 6620, 6630.11], + }, + { + x: new Date(1538782200000), + y: [6630.71, 6648.95, 6623.34, 6635.65], + }, + { + x: new Date(1538784000000), + y: [6635.65, 6651, 6629.67, 6638.24], + }, + { x: new Date(1538785800000), y: [6638.24, 6640, 6620, 6624.47] }, + { + x: new Date(1538787600000), + y: [6624.53, 6636.03, 6621.68, 6624.31], + }, + { x: new Date(1538789400000), y: [6624.61, 6632.2, 6617, 6626.02] }, + { + x: new Date(1538791200000), + y: [6627, 6627.62, 6584.22, 6603.02], + }, + { + x: new Date(1538793000000), + y: [6605, 6608.03, 6598.95, 6604.01], + }, + { + x: new Date(1538794800000), + y: [6604.5, 6614.4, 6602.26, 6608.02], + }, + { + x: new Date(1538796600000), + y: [6608.02, 6610.68, 6601.99, 6608.91], + }, + { + x: new Date(1538798400000), + y: [6608.91, 6618.99, 6608.01, 6612], + }, + { x: new Date(1538800200000), y: [6612, 6615.13, 6605.09, 6612] }, + { + x: new Date(1538802000000), + y: [6612, 6624.12, 6608.43, 6622.95], + }, + { + x: new Date(1538803800000), + y: [6623.91, 6623.91, 6615, 6615.67], + }, + { x: new Date(1538805600000), y: [6618.69, 6618.74, 6610, 6610.4] }, + { x: new Date(1538807400000), y: [6611, 6622.78, 6610.4, 6614.9] }, + { + x: new Date(1538809200000), + y: [6614.9, 6626.2, 6613.33, 6623.45], + }, + { + x: new Date(1538811000000), + y: [6623.48, 6627, 6618.38, 6620.35], + }, + { + x: new Date(1538812800000), + y: [6619.43, 6620.35, 6610.05, 6615.53], + }, + { + x: new Date(1538814600000), + y: [6615.53, 6617.93, 6610, 6615.19], + }, + { x: new Date(1538816400000), y: [6615.19, 6621.6, 6608.2, 6620] }, + { + x: new Date(1538818200000), + y: [6619.54, 6625.17, 6614.15, 6620], + }, + { + x: new Date(1538820000000), + y: [6620.33, 6634.15, 6617.24, 6624.61], + }, + { + x: new Date(1538821800000), + y: [6625.95, 6626, 6611.66, 6617.58], + }, + { + x: new Date(1538823600000), + y: [6619, 6625.97, 6595.27, 6598.86], + }, + { + x: new Date(1538825400000), + y: [6598.86, 6598.88, 6570, 6587.16], + }, + { x: new Date(1538827200000), y: [6588.86, 6600, 6580, 6593.4] }, + { + x: new Date(1538829000000), + y: [6593.99, 6598.89, 6585, 6587.81], + }, + { + x: new Date(1538830800000), + y: [6587.81, 6592.73, 6567.14, 6578], + }, + { + x: new Date(1538832600000), + y: [6578.35, 6581.72, 6567.39, 6579], + }, + { + x: new Date(1538834400000), + y: [6579.38, 6580.92, 6566.77, 6575.96], + }, + { + x: new Date(1538836200000), + y: [6575.96, 6589, 6571.77, 6588.92], + }, + { + x: new Date(1538838000000), + y: [6588.92, 6594, 6577.55, 6589.22], + }, + { + x: new Date(1538839800000), + y: [6589.3, 6598.89, 6589.1, 6596.08], + }, + { x: new Date(1538841600000), y: [6597.5, 6600, 6588.39, 6596.25] }, + { + x: new Date(1538843400000), + y: [6598.03, 6600, 6588.73, 6595.97], + }, + { + x: new Date(1538845200000), + y: [6595.97, 6602.01, 6588.17, 6602], + }, + { x: new Date(1538847000000), y: [6602, 6607, 6596.51, 6599.95] }, + { + x: new Date(1538848800000), + y: [6600.63, 6601.21, 6590.39, 6591.02], + }, + { x: new Date(1538850600000), y: [6591.02, 6603.08, 6591, 6591] }, + { x: new Date(1538852400000), y: [6591, 6601.32, 6585, 6592] }, + { + x: new Date(1538854200000), + y: [6593.13, 6596.01, 6590, 6593.34], + }, + { + x: new Date(1538856000000), + y: [6593.34, 6604.76, 6582.63, 6593.86], + }, + { + x: new Date(1538857800000), + y: [6593.86, 6604.28, 6586.57, 6600.01], + }, + { + x: new Date(1538859600000), + y: [6601.81, 6603.21, 6592.78, 6596.25], + }, + { x: new Date(1538861400000), y: [6596.25, 6604.2, 6590, 6602.99] }, + { + x: new Date(1538863200000), + y: [6602.99, 6606, 6584.99, 6587.81], + }, + { + x: new Date(1538865000000), + y: [6587.81, 6595, 6583.27, 6591.96], + }, + { + x: new Date(1538866800000), + y: [6591.97, 6596.07, 6585, 6588.39], + }, + { + x: new Date(1538868600000), + y: [6587.6, 6598.21, 6587.6, 6594.27], + }, + { x: new Date(1538870400000), y: [6596.44, 6601, 6590, 6596.55] }, + { + x: new Date(1538872200000), + y: [6598.91, 6605, 6596.61, 6600.02], + }, + { + x: new Date(1538874000000), + y: [6600.55, 6605, 6589.14, 6593.01], + }, + { x: new Date(1538875800000), y: [6593.15, 6605, 6592, 6603.06] }, + { + x: new Date(1538877600000), + y: [6603.07, 6604.5, 6599.09, 6603.89], + }, + { x: new Date(1538879400000), y: [6604.44, 6604.44, 6600, 6603.5] }, + { + x: new Date(1538881200000), + y: [6603.5, 6603.99, 6597.5, 6603.86], + }, + { x: new Date(1538883000000), y: [6603.85, 6605, 6600, 6604.07] }, + { x: new Date(1538884800000), y: [6604.98, 6606, 6604.07, 6606] }, + ], + }, + ], + chart: { + height: 350, + fontFamily: "'Plus Jakarta Sans', sans-serif", + foreColor: '#adb0bb', + type: 'candlestick', + toolbar: { + show: false, + }, + }, + xaxis: { + type: 'datetime', + }, + yaxis: { + tooltip: { + enabled: true, + }, + }, + plotOptions: { + candlestick: { + colors: { + upward: '#5D87FF', + downward: '#49BEFF', + }, + }, + }, + tooltip: { + theme: 'dark', + }, + grid: { + show: false, + }, + }; + } +} diff --git a/theme/packages/main/src/app/pages/charts/candlestick/code/candlestick-html-snippet.ts b/theme/packages/main/src/app/pages/charts/candlestick/code/candlestick-html-snippet.ts new file mode 100644 index 0000000..8791a25 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/candlestick/code/candlestick-html-snippet.ts @@ -0,0 +1,8 @@ +export const CANDLESTICK_CHART_HTML_SNIPPET = ` + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/candlestick/code/candlestick-ts-snippet.ts b/theme/packages/main/src/app/pages/charts/candlestick/code/candlestick-ts-snippet.ts new file mode 100644 index 0000000..5160eee --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/candlestick/code/candlestick-ts-snippet.ts @@ -0,0 +1,285 @@ +export const CANDLESTICK_CHART_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, + } from 'ng-apexcharts'; + import { MaterialModule } from '../../../material.module'; + + export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; + }; + + /** + * @title Candlestick Chart */ + */ + @Component({ + selector: 'app-candlestick', + imports: [NgApexchartsModule, MaterialModule], + templateUrl: './candlestick.component.html' + }) + export class AppCandlestickChartComponent { + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public candlestickChartOptions: Partial | any; + + constructor() { + //doughnut chart. + this.candlestickChartOptions = { + series: [ + { + data: [ + { + x: new Date(1538778600000), + y: [6629.81, 6650.5, 6623.04, 6633.33], + }, + { + x: new Date(1538780400000), + y: [6632.01, 6643.59, 6620, 6630.11], + }, + { + x: new Date(1538782200000), + y: [6630.71, 6648.95, 6623.34, 6635.65], + }, + { + x: new Date(1538784000000), + y: [6635.65, 6651, 6629.67, 6638.24], + }, + { x: new Date(1538785800000), y: [6638.24, 6640, 6620, 6624.47] }, + { + x: new Date(1538787600000), + y: [6624.53, 6636.03, 6621.68, 6624.31], + }, + { x: new Date(1538789400000), y: [6624.61, 6632.2, 6617, 6626.02] }, + { + x: new Date(1538791200000), + y: [6627, 6627.62, 6584.22, 6603.02], + }, + { + x: new Date(1538793000000), + y: [6605, 6608.03, 6598.95, 6604.01], + }, + { + x: new Date(1538794800000), + y: [6604.5, 6614.4, 6602.26, 6608.02], + }, + { + x: new Date(1538796600000), + y: [6608.02, 6610.68, 6601.99, 6608.91], + }, + { + x: new Date(1538798400000), + y: [6608.91, 6618.99, 6608.01, 6612], + }, + { x: new Date(1538800200000), y: [6612, 6615.13, 6605.09, 6612] }, + { + x: new Date(1538802000000), + y: [6612, 6624.12, 6608.43, 6622.95], + }, + { + x: new Date(1538803800000), + y: [6623.91, 6623.91, 6615, 6615.67], + }, + { x: new Date(1538805600000), y: [6618.69, 6618.74, 6610, 6610.4] }, + { x: new Date(1538807400000), y: [6611, 6622.78, 6610.4, 6614.9] }, + { + x: new Date(1538809200000), + y: [6614.9, 6626.2, 6613.33, 6623.45], + }, + { + x: new Date(1538811000000), + y: [6623.48, 6627, 6618.38, 6620.35], + }, + { + x: new Date(1538812800000), + y: [6619.43, 6620.35, 6610.05, 6615.53], + }, + { + x: new Date(1538814600000), + y: [6615.53, 6617.93, 6610, 6615.19], + }, + { x: new Date(1538816400000), y: [6615.19, 6621.6, 6608.2, 6620] }, + { + x: new Date(1538818200000), + y: [6619.54, 6625.17, 6614.15, 6620], + }, + { + x: new Date(1538820000000), + y: [6620.33, 6634.15, 6617.24, 6624.61], + }, + { + x: new Date(1538821800000), + y: [6625.95, 6626, 6611.66, 6617.58], + }, + { + x: new Date(1538823600000), + y: [6619, 6625.97, 6595.27, 6598.86], + }, + { + x: new Date(1538825400000), + y: [6598.86, 6598.88, 6570, 6587.16], + }, + { x: new Date(1538827200000), y: [6588.86, 6600, 6580, 6593.4] }, + { + x: new Date(1538829000000), + y: [6593.99, 6598.89, 6585, 6587.81], + }, + { + x: new Date(1538830800000), + y: [6587.81, 6592.73, 6567.14, 6578], + }, + { + x: new Date(1538832600000), + y: [6578.35, 6581.72, 6567.39, 6579], + }, + { + x: new Date(1538834400000), + y: [6579.38, 6580.92, 6566.77, 6575.96], + }, + { + x: new Date(1538836200000), + y: [6575.96, 6589, 6571.77, 6588.92], + }, + { + x: new Date(1538838000000), + y: [6588.92, 6594, 6577.55, 6589.22], + }, + { + x: new Date(1538839800000), + y: [6589.3, 6598.89, 6589.1, 6596.08], + }, + { x: new Date(1538841600000), y: [6597.5, 6600, 6588.39, 6596.25] }, + { + x: new Date(1538843400000), + y: [6598.03, 6600, 6588.73, 6595.97], + }, + { + x: new Date(1538845200000), + y: [6595.97, 6602.01, 6588.17, 6602], + }, + { x: new Date(1538847000000), y: [6602, 6607, 6596.51, 6599.95] }, + { + x: new Date(1538848800000), + y: [6600.63, 6601.21, 6590.39, 6591.02], + }, + { x: new Date(1538850600000), y: [6591.02, 6603.08, 6591, 6591] }, + { x: new Date(1538852400000), y: [6591, 6601.32, 6585, 6592] }, + { + x: new Date(1538854200000), + y: [6593.13, 6596.01, 6590, 6593.34], + }, + { + x: new Date(1538856000000), + y: [6593.34, 6604.76, 6582.63, 6593.86], + }, + { + x: new Date(1538857800000), + y: [6593.86, 6604.28, 6586.57, 6600.01], + }, + { + x: new Date(1538859600000), + y: [6601.81, 6603.21, 6592.78, 6596.25], + }, + { x: new Date(1538861400000), y: [6596.25, 6604.2, 6590, 6602.99] }, + { + x: new Date(1538863200000), + y: [6602.99, 6606, 6584.99, 6587.81], + }, + { + x: new Date(1538865000000), + y: [6587.81, 6595, 6583.27, 6591.96], + }, + { + x: new Date(1538866800000), + y: [6591.97, 6596.07, 6585, 6588.39], + }, + { + x: new Date(1538868600000), + y: [6587.6, 6598.21, 6587.6, 6594.27], + }, + { x: new Date(1538870400000), y: [6596.44, 6601, 6590, 6596.55] }, + { + x: new Date(1538872200000), + y: [6598.91, 6605, 6596.61, 6600.02], + }, + { + x: new Date(1538874000000), + y: [6600.55, 6605, 6589.14, 6593.01], + }, + { x: new Date(1538875800000), y: [6593.15, 6605, 6592, 6603.06] }, + { + x: new Date(1538877600000), + y: [6603.07, 6604.5, 6599.09, 6603.89], + }, + { x: new Date(1538879400000), y: [6604.44, 6604.44, 6600, 6603.5] }, + { + x: new Date(1538881200000), + y: [6603.5, 6603.99, 6597.5, 6603.86], + }, + { x: new Date(1538883000000), y: [6603.85, 6605, 6600, 6604.07] }, + { x: new Date(1538884800000), y: [6604.98, 6606, 6604.07, 6606] }, + ], + }, + ], + chart: { + height: 350, + fontFamily: "'Plus Jakarta Sans', sans-serif", + foreColor: '#adb0bb', + type: 'candlestick', + toolbar: { + show: false, + }, + }, + xaxis: { + type: 'datetime', + }, + yaxis: { + tooltip: { + enabled: true, + }, + }, + plotOptions: { + candlestick: { + colors: { + upward: '#5D87FF', + downward: '#49BEFF', + }, + }, + }, + tooltip: { + theme: 'dark', + }, + grid: { + show: false, + }, + }; + } + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/charts.routes.ts b/theme/packages/main/src/app/pages/charts/charts.routes.ts new file mode 100644 index 0000000..0151b23 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/charts.routes.ts @@ -0,0 +1,95 @@ +import { Routes } from '@angular/router'; + +// components +import { AppAreaChartComponent } from './area/area.component'; +import { AppCandlestickChartComponent } from './candlestick/candlestick.component'; +import { AppColumnChartComponent } from './column/column.component'; +import { AppDoughnutpieChartComponent } from './doughnut-pie/doughnut-pie.component'; +import { AppGredientChartComponent } from './gredient/gredient.component'; +import { AppLineChartComponent } from './line/line.component'; +import { AppRadialRadarChartComponent } from './radial-radar/radial-radar.component'; + +export const ChartsRoutes: Routes = [ + { + path: '', + children: [ + { + path: 'area', + component: AppAreaChartComponent, + data: { + title: 'Area Chart', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Area Chart' }, + ], + }, + }, + { + path: 'candlestick', + component: AppCandlestickChartComponent, + data: { + title: 'Candlestick', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Candlestick' }, + ], + }, + }, + { + path: 'column', + component: AppColumnChartComponent, + data: { + title: 'Column Chart', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Column Chart' }, + ], + }, + }, + { + path: 'doughnut-pie', + component: AppDoughnutpieChartComponent, + data: { + title: 'Doughnut-Pie Chart', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Doughnut-Pie Chart' }, + ], + }, + }, + { + path: 'gredient', + component: AppGredientChartComponent, + data: { + title: 'Gredient Chart', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Gredient Chart' }, + ], + }, + }, + { + path: 'line', + component: AppLineChartComponent, + data: { + title: 'Line Chart', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Line Chart' }, + ], + }, + }, + { + path: 'radial-radar', + component: AppRadialRadarChartComponent, + data: { + title: 'Radial-Radar Chart', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Radial-Radar Chart' }, + ], + }, + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/pages/charts/column/code/column-html-snippet.ts b/theme/packages/main/src/app/pages/charts/column/code/column-html-snippet.ts new file mode 100644 index 0000000..b675244 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/column/code/column-html-snippet.ts @@ -0,0 +1,7 @@ +export const COLUMN_CHART_HTML_SNIPPET = ` + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/column/code/column-ts-snippet.ts b/theme/packages/main/src/app/pages/charts/column/code/column-ts-snippet.ts new file mode 100644 index 0000000..e509d3b --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/column/code/column-ts-snippet.ts @@ -0,0 +1,122 @@ +export const COLUMN_CHART_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, + } from 'ng-apexcharts'; + import { MaterialModule } from '../../../material.module'; + + export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; + }; + + /** + * @title column Chart */ + */ + @Component({ + selector: 'app-column', + imports: [NgApexchartsModule, MaterialModule], + templateUrl: './column.component.html' + }) + export class AppColumnChartComponent { + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public columnChartOptions: Partial | any; + constructor() { + //Column chart. + this.columnChartOptions = { + series: [ + { + name: 'A', + data: [400, 120, 140, 130, 200, 150, 140, 130, 300, 120, 140, 150], + }, + { + name: 'B', + data: [200, 188, 242, 300, 200, 400, 230, 300, 200, 400, 180, 300], + }, + { + name: 'C', + data: [100, 200, 400, 600, 100, 200, 400, 370, 240, 200, 280, 330], + }, + ], + chart: { + fontFamily: 'DM Sans,sans-serif', + foreColor: '#a1aab2', + height: 300, + type: 'bar', + stacked: true, + toolbar: { + show: false, + }, + }, + plotOptions: { + bar: { + columnWidth: '40%', + barHeight: '40%', + }, + }, + dataLabels: { + enabled: false, + }, + markers: { + size: 3, + }, + stroke: { + curve: 'straight', + width: '0', + }, + colors: ['#398bf7', '#06d79c'], + legend: { + show: true, + }, + grid: { + show: true, + strokeDashArray: 0, + borderColor: 'rgba(0,0,0,0.1)', + xaxis: { + lines: { + show: true, + }, + }, + yaxis: { + lines: { + show: true, + }, + }, + }, + xaxis: { + type: 'category', + categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'], + }, + tooltip: { + theme: 'dark', + }, + }; + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/column/column.component.html b/theme/packages/main/src/app/pages/charts/column/column.component.html new file mode 100644 index 0000000..f5a7d63 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/column/column.component.html @@ -0,0 +1,29 @@ + + +

+ Column Chart +

+
+ + +
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/column/column.component.ts b/theme/packages/main/src/app/pages/charts/column/column.component.ts new file mode 100644 index 0000000..7bf267c --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/column/column.component.ts @@ -0,0 +1,138 @@ +import { Component, ViewChild } from '@angular/core'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { COLUMN_CHART_HTML_SNIPPET } from './code/column-html-snippet'; +import { COLUMN_CHART_TS_SNIPPET } from './code/column-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; + +export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; +}; + +@Component({ + selector: 'app-column', + imports: [NgApexchartsModule, MaterialModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './column.component.html' +}) + +export class AppColumnChartComponent { + + // 1 [column with Datepicker] + codeForColumnChart = COLUMN_CHART_HTML_SNIPPET; + codeForColumnChartTs = COLUMN_CHART_TS_SNIPPET; + + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public columnChartOptions: Partial | any; + constructor() { + //Column chart. + this.columnChartOptions = { + series: [ + { + name: 'A', + data: [400, 120, 140, 130, 200, 150, 140, 130, 300, 120, 140, 150], + }, + { + name: 'B', + data: [200, 188, 242, 300, 200, 400, 230, 300, 200, 400, 180, 300], + }, + { + name: 'C', + data: [100, 200, 400, 600, 100, 200, 400, 370, 240, 200, 280, 330], + }, + ], + chart: { + fontFamily: 'DM Sans,sans-serif', + foreColor: '#a1aab2', + height: 300, + type: 'bar', + stacked: true, + toolbar: { + show: false, + }, + }, + plotOptions: { + bar: { + columnWidth: '40%', + barHeight: '40%', + }, + }, + dataLabels: { + enabled: false, + }, + markers: { + size: 3, + }, + stroke: { + curve: 'straight', + width: '0', + }, + colors: ['#398bf7', '#06d79c'], + legend: { + show: true, + }, + grid: { + show: true, + strokeDashArray: 0, + borderColor: 'rgba(0,0,0,0.1)', + xaxis: { + lines: { + show: true, + }, + }, + yaxis: { + lines: { + show: true, + }, + }, + }, + xaxis: { + type: 'category', + categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'], + }, + tooltip: { + theme: 'dark', + }, + }; + } +} diff --git a/theme/packages/main/src/app/pages/charts/doughnut-pie/code/doughnut-pie-html-snippet.ts b/theme/packages/main/src/app/pages/charts/doughnut-pie/code/doughnut-pie-html-snippet.ts new file mode 100644 index 0000000..76554fa --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/doughnut-pie/code/doughnut-pie-html-snippet.ts @@ -0,0 +1,15 @@ +export const DOUGHNUT_CHART_HTML_SNIPPET = ` + +`; + +export const PIE_CHART_HTML_SNIPPET = ` + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/doughnut-pie/code/doughnut-pie-ts-snippet.ts b/theme/packages/main/src/app/pages/charts/doughnut-pie/code/doughnut-pie-ts-snippet.ts new file mode 100644 index 0000000..d4f09b4 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/doughnut-pie/code/doughnut-pie-ts-snippet.ts @@ -0,0 +1,172 @@ +export const DOUGHNUT_CHART_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, + } from 'ng-apexcharts'; + import { MaterialModule } from '../../../material.module'; + + export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; + }; + + /** + * @title doughnut Chart */ + */ + @Component({ + selector: 'app-doughnut-pie', + imports: [NgApexchartsModule, MaterialModule], + templateUrl: './doughnut-pie.component.html' + }) + export class AppDoughnutpieChartComponent { + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public doughnutChartOptions: Partial | any; + + constructor() { + this.doughnutChartOptions = { + series: [45, 15, 27, 18, 35], + chart: { + id: 'donut-chart', + type: 'donut', + height: 350, + fontFamily: "'Plus Jakarta Sans', sans-serif", + foreColor: '#adb0bb', + }, + dataLabels: { + enabled: false, + }, + plotOptions: { + pie: { + donut: { + size: '70px', + }, + }, + }, + legend: { + show: true, + position: 'bottom', + width: '50px', + }, + colors: ['#5D87FF', '#ECF2FF', '#49BEFF', '#E8F7FF', '#FFAE1F'], + tooltip: { + theme: 'dark', + fillSeriesColor: false, + }, + }; + } +`; + + +export const PIE_CHART_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, + } from 'ng-apexcharts'; + import { MaterialModule } from '../../../material.module'; + + export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; + }; + + /** + * @title doughnut Chart */ + */ + @Component({ + selector: 'app-doughnut-pie', + imports: [NgApexchartsModule, MaterialModule], + templateUrl: './doughnut-pie.component.html' + }) + export class AppDoughnutpieChartComponent { + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public pieChartOptions: Partial | any; + + constructor() { + this.pieChartOptions = { + series: [45, 15, 27, 18, 35], + chart: { + id: 'pie-chart', + type: 'pie', + height: 350, + fontFamily: "'Plus Jakarta Sans', sans-serif", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + }, + dataLabels: { + enabled: false, + }, + plotOptions: { + pie: { + donut: { + size: '70px', + }, + }, + }, + legend: { + show: true, + position: 'bottom', + width: '50px', + }, + colors: ['#5D87FF', '#ECF2FF', '#49BEFF', '#E8F7FF', '#FFAE1F'], + tooltip: { + fillSeriesColor: false, + }, + }; + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/doughnut-pie/doughnut-pie.component.html b/theme/packages/main/src/app/pages/charts/doughnut-pie/doughnut-pie.component.html new file mode 100644 index 0000000..5b26d76 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/doughnut-pie/doughnut-pie.component.html @@ -0,0 +1,64 @@ +
+
+ + +

+ Doughnut +

+
+ + +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
+ + +

+ Pie +

+
+ + +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/doughnut-pie/doughnut-pie.component.ts b/theme/packages/main/src/app/pages/charts/doughnut-pie/doughnut-pie.component.ts new file mode 100644 index 0000000..44a3210 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/doughnut-pie/doughnut-pie.component.ts @@ -0,0 +1,138 @@ +import { Component, ViewChild } from '@angular/core'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { DOUGHNUT_CHART_HTML_SNIPPET, PIE_CHART_HTML_SNIPPET } from './code/doughnut-pie-html-snippet'; +import { DOUGHNUT_CHART_TS_SNIPPET, PIE_CHART_TS_SNIPPET } from './code/doughnut-pie-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; + +export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; +}; + +@Component({ + selector: 'app-doughnut-pie', + imports: [NgApexchartsModule, MaterialModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './doughnut-pie.component.html' +}) +export class AppDoughnutpieChartComponent { + + // 1 [Doughnut with Datepicker] + codeForDoughnutChart = DOUGHNUT_CHART_HTML_SNIPPET; + codeForDoughnutChartTs = DOUGHNUT_CHART_TS_SNIPPET; + + // 2 [Pie with Datepicker] + codeForPieChart = PIE_CHART_HTML_SNIPPET; + codeForPieChartTs = PIE_CHART_TS_SNIPPET; + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public doughnutChartOptions: Partial | any; + public pieChartOptions: Partial | any; + + constructor() { + //doughnut chart. + this.doughnutChartOptions = { + series: [45, 15, 27, 18, 35], + chart: { + id: 'donut-chart', + type: 'donut', + height: 350, + fontFamily: "'Plus Jakarta Sans', sans-serif", + foreColor: '#adb0bb', + }, + dataLabels: { + enabled: false, + }, + plotOptions: { + pie: { + donut: { + size: '70px', + }, + }, + }, + legend: { + show: true, + position: 'bottom', + width: '50px', + }, + colors: ['#5D87FF', '#ECF2FF', '#49BEFF', '#E8F7FF', '#FFAE1F'], + tooltip: { + theme: 'dark', + fillSeriesColor: false, + }, + }; + + //pie chart. + this.pieChartOptions = { + series: [45, 15, 27, 18, 35], + chart: { + id: 'pie-chart', + type: 'pie', + height: 350, + fontFamily: "'Plus Jakarta Sans', sans-serif", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + }, + dataLabels: { + enabled: false, + }, + plotOptions: { + pie: { + donut: { + size: '70px', + }, + }, + }, + legend: { + show: true, + position: 'bottom', + width: '50px', + }, + colors: ['#5D87FF', '#ECF2FF', '#49BEFF', '#E8F7FF', '#FFAE1F'], + tooltip: { + fillSeriesColor: false, + }, + }; + } +} diff --git a/theme/packages/main/src/app/pages/charts/gredient/code/gredient-html-snippet.ts b/theme/packages/main/src/app/pages/charts/gredient/code/gredient-html-snippet.ts new file mode 100644 index 0000000..bfbedc5 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/gredient/code/gredient-html-snippet.ts @@ -0,0 +1,7 @@ +export const GREDIENT_CHART_HTML_SNIPPET = ` + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/gredient/code/gredient-ts-snippet.ts b/theme/packages/main/src/app/pages/charts/gredient/code/gredient-ts-snippet.ts new file mode 100644 index 0000000..3b888e6 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/gredient/code/gredient-ts-snippet.ts @@ -0,0 +1,148 @@ +export const GREDIENT_CHART_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, + } from 'ng-apexcharts'; + import { MaterialModule } from '../../../material.module'; + + export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; + }; + + /** + * @title Gredient Chart */ + */ + @Component({ + selector: 'app-gredient', + imports: [NgApexchartsModule, MaterialModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './gredient.component.html' + }) + export class AppGredientChartComponent { + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public gredientChartOptions: Partial | any; + + constructor() { + //Column chart. + this.gredientChartOptions = { + series: [ + { + name: 'Likes', + data: [4, 3, 10, 9, 35, 19, 22, 9, 12, 7, 19, 5, 13, 9, 17, 2, 7, 5], + }, + ], + chart: { + height: 350, + type: 'line', + fontFamily: "'Plus Jakarta Sans', sans-serif", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + dropShadow: { + enabled: true, + color: 'rgba(0,0,0,0.2)', + top: 12, + left: 4, + blur: 3, + opacity: 0.4, + }, + }, + stroke: { + width: 7, + curve: 'smooth', + }, + + xaxis: { + type: 'datetime', + categories: [ + '1/11/2000', + '2/11/2000', + '3/11/2000', + '4/11/2000', + '5/11/2000', + '6/11/2000', + '7/11/2000', + '8/11/2000', + '9/11/2000', + '10/11/2000', + '11/11/2000', + '12/11/2000', + '1/11/2001', + '2/11/2001', + '3/11/2001', + '4/11/2001', + '5/11/2001', + '6/11/2001', + ], + }, + fill: { + type: 'gradient', + gradient: { + shade: 'dark', + gradientToColors: ['#5D87FF'], + shadeIntensity: 1, + type: 'horizontal', + opacityFrom: 1, + opacityTo: 0.9, + stops: [0, 100, 100, 100], + }, + }, + markers: { + size: 4, + opacity: 0.9, + colors: ['#5D87FF'], + strokeColor: '#fff', + strokeWidth: 2, + + hover: { + size: 7, + }, + }, + yaxis: { + min: 0, + max: 40, + }, + tooltip: { + theme: 'dark', + }, + grid: { + show: false, + }, + }; + } + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/gredient/gredient.component.html b/theme/packages/main/src/app/pages/charts/gredient/gredient.component.html new file mode 100644 index 0000000..d52bb63 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/gredient/gredient.component.html @@ -0,0 +1,29 @@ + + +

+ Gredient Chart +

+
+ + +
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/gredient/gredient.component.ts b/theme/packages/main/src/app/pages/charts/gredient/gredient.component.ts new file mode 100644 index 0000000..ed90ad9 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/gredient/gredient.component.ts @@ -0,0 +1,153 @@ +import { Component, ViewChild } from '@angular/core'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { GREDIENT_CHART_HTML_SNIPPET } from './code/gredient-html-snippet'; +import { GREDIENT_CHART_TS_SNIPPET } from './code/gredient-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; + +export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; +}; +@Component({ + selector: 'app-gredient', + imports: [NgApexchartsModule, MaterialModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './gredient.component.html' +}) +export class AppGredientChartComponent { + + // 1 [Gredient with Datepicker] + codeForGredientChart = GREDIENT_CHART_HTML_SNIPPET; + codeForGredientChartTs = GREDIENT_CHART_TS_SNIPPET; + + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public gredientChartOptions: Partial | any; + constructor() { + //Column chart. + this.gredientChartOptions = { + series: [ + { + name: 'Likes', + data: [4, 3, 10, 9, 35, 19, 22, 9, 12, 7, 19, 5, 13, 9, 17, 2, 7, 5], + }, + ], + chart: { + height: 350, + type: 'line', + fontFamily: "'Plus Jakarta Sans', sans-serif", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + dropShadow: { + enabled: true, + color: 'rgba(0,0,0,0.2)', + top: 12, + left: 4, + blur: 3, + opacity: 0.4, + }, + }, + stroke: { + width: 7, + curve: 'smooth', + }, + + xaxis: { + type: 'datetime', + categories: [ + '1/11/2000', + '2/11/2000', + '3/11/2000', + '4/11/2000', + '5/11/2000', + '6/11/2000', + '7/11/2000', + '8/11/2000', + '9/11/2000', + '10/11/2000', + '11/11/2000', + '12/11/2000', + '1/11/2001', + '2/11/2001', + '3/11/2001', + '4/11/2001', + '5/11/2001', + '6/11/2001', + ], + }, + fill: { + type: 'gradient', + gradient: { + shade: 'dark', + gradientToColors: ['#5D87FF'], + shadeIntensity: 1, + type: 'horizontal', + opacityFrom: 1, + opacityTo: 0.9, + stops: [0, 100, 100, 100], + }, + }, + markers: { + size: 4, + opacity: 0.9, + colors: ['#5D87FF'], + strokeColor: '#fff', + strokeWidth: 2, + + hover: { + size: 7, + }, + }, + yaxis: { + min: 0, + max: 40, + }, + tooltip: { + theme: 'dark', + }, + grid: { + show: false, + }, + }; + } +} diff --git a/theme/packages/main/src/app/pages/charts/line/code/line-html-snippet.ts b/theme/packages/main/src/app/pages/charts/line/code/line-html-snippet.ts new file mode 100644 index 0000000..d762306 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/line/code/line-html-snippet.ts @@ -0,0 +1,6 @@ +export const LINE_CHART_HTML_SNIPPET = ` + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/line/code/line-ts-snippet.ts b/theme/packages/main/src/app/pages/charts/line/code/line-ts-snippet.ts new file mode 100644 index 0000000..f6ab016 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/line/code/line-ts-snippet.ts @@ -0,0 +1,130 @@ +export const LINE_CHART_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, + } from 'ng-apexcharts'; + import { MaterialModule } from '../../../material.module'; + + + export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; + }; + + /** + * @title Basic Line Chart */ + */ + @Component({ + selector: 'app-line', + imports: [NgApexchartsModule, MaterialModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './line.component.html' + }) + export class AppLineChartComponent { + constructor() {} + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public lineChartOptions: Partial | any; + + constructor() { + // Line chart. + this.lineChartOptions = { + series: [ + { + name: 'Site A', + data: [5, 6, 3, 7, 9, 10, 14, 12, 11, 9, 8, 7, 10, 6, 12, 10, 8], + }, + { + name: 'Site B', + data: [1, 2, 8, 3, 4, 5, 7, 6, 5, 6, 4, 3, 3, 12, 5, 6, 3], + }, + ], + chart: { + height: 300, + type: 'line', + fontFamily: 'DM Sans,sans-serif', + foreColor: '#a1aab2', + toolbar: { + show: false, + }, + }, + dataLabels: { + enabled: false, + }, + markers: { + size: 3, + strokeColors: 'transparent', + }, + stroke: { + curve: 'straight', + width: '2', + }, + colors: ['#06d79c', '#398bf7'], + legend: { + show: false, + }, + grid: { + show: true, + strokeDashArray: 0, + borderColor: 'rgba(0,0,0,0.1)', + }, + xaxis: { + type: 'category', + categories: [ + '0', + '2', + '4', + '6', + '8', + '10', + '12', + '14', + '16', + '18', + '20', + '22', + '24', + '26', + '28', + '30', + '32', + ], + }, + tooltip: { + theme: 'dark', + }, + }; + } + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/line/line.component.html b/theme/packages/main/src/app/pages/charts/line/line.component.html new file mode 100644 index 0000000..726ccca --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/line/line.component.html @@ -0,0 +1,28 @@ + + +

+ Line Chart +

+
+ + +
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/line/line.component.ts b/theme/packages/main/src/app/pages/charts/line/line.component.ts new file mode 100644 index 0000000..9d94374 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/line/line.component.ts @@ -0,0 +1,136 @@ +import { Component, ViewChild } from '@angular/core'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { LINE_CHART_HTML_SNIPPET } from './code/line-html-snippet'; +import { LINE_CHART_TS_SNIPPET } from './code/line-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; + + +export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; +}; +@Component({ + selector: 'app-line', + imports: [NgApexchartsModule, MaterialModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './line.component.html' +}) +export class AppLineChartComponent { + + // 1 [Basic with Datepicker] + codeForLineChart = LINE_CHART_HTML_SNIPPET; + codeForLineChartTs = LINE_CHART_TS_SNIPPET; + + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public lineChartOptions: Partial | any; + + constructor() { + // Line chart. + this.lineChartOptions = { + series: [ + { + name: 'Site A', + data: [5, 6, 3, 7, 9, 10, 14, 12, 11, 9, 8, 7, 10, 6, 12, 10, 8], + }, + { + name: 'Site B', + data: [1, 2, 8, 3, 4, 5, 7, 6, 5, 6, 4, 3, 3, 12, 5, 6, 3], + }, + ], + chart: { + height: 300, + type: 'line', + fontFamily: 'DM Sans,sans-serif', + foreColor: '#a1aab2', + toolbar: { + show: false, + }, + }, + dataLabels: { + enabled: false, + }, + markers: { + size: 3, + strokeColors: 'transparent', + }, + stroke: { + curve: 'straight', + width: '2', + }, + colors: ['#06d79c', '#398bf7'], + legend: { + show: false, + }, + grid: { + show: true, + strokeDashArray: 0, + borderColor: 'rgba(0,0,0,0.1)', + }, + xaxis: { + type: 'category', + categories: [ + '0', + '2', + '4', + '6', + '8', + '10', + '12', + '14', + '16', + '18', + '20', + '22', + '24', + '26', + '28', + '30', + '32', + ], + }, + tooltip: { + theme: 'dark', + }, + }; + } +} diff --git a/theme/packages/main/src/app/pages/charts/radial-radar/code/radial-radar-html-snippet.ts b/theme/packages/main/src/app/pages/charts/radial-radar/code/radial-radar-html-snippet.ts new file mode 100644 index 0000000..c905ac9 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/radial-radar/code/radial-radar-html-snippet.ts @@ -0,0 +1,12 @@ +export const RADIALBAR_CHART_HTML_SNIPPET = ` + +`; + +export const RADAR_CHART_HTML_SNIPPET = ` + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/radial-radar/code/radial-radar-ts-snippet.ts b/theme/packages/main/src/app/pages/charts/radial-radar/code/radial-radar-ts-snippet.ts new file mode 100644 index 0000000..df08a20 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/radial-radar/code/radial-radar-ts-snippet.ts @@ -0,0 +1,166 @@ +export const RADIALBAR_CHART_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, + } from 'ng-apexcharts'; + import { MaterialModule } from '../../../material.module'; + + export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; + }; + + /** + * @title Radialbar Chart */ + */ + @Component({ + selector: 'app-radial-radar', + imports: [NgApexchartsModule, MaterialModule], + templateUrl: './radial-radar.component.html' + }) + export class AppRadialRadarChartComponent { + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public radialbarChartOptions: Partial | any; + + constructor() { + this.radialbarChartOptions = { + series: [44, 55, 67, 83], + chart: { + id: 'radial-chart', + type: 'radialBar', + height: 350, + fontFamily: "'Plus Jakarta Sans', sans-serif", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + }, + colors: ['#5D87FF', '#49BEFF', '#13DEB9', '#FFAE1F'], + plotOptions: { + radialBar: { + dataLabels: { + name: { + fontSize: '22px', + }, + value: { + fontSize: '16px', + }, + total: { + show: true, + label: 'Total', + formatter() { + return 249; + }, + }, + }, + }, + }, + tooltip: { + theme: 'dark', + }, + }; + } +`; + +export const RADAR_CHART_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, + } from 'ng-apexcharts'; + import { MaterialModule } from '../../../material.module'; + + export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; + }; + + /** + * @title Radar Chart */ + */ + @Component({ + selector: 'app-radial-radar', + imports: [NgApexchartsModule, MaterialModule], + templateUrl: './radial-radar.component.html' + }) + export class AppRadialRadarChartComponent { + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public radarChartOptions: Partial | any; + + constructor() { + this.radarChartOptions = { + series: [ + { + name: 'Sales', + data: [80, 50, 30, 40, 100, 20], + }, + ], + chart: { + id: 'pie-chart', + type: 'radar', + fontFamily: "'Plus Jakarta Sans', sans-serif", + toolbar: { + show: false, + }, + }, + colors: ['#5D87FF'], + labels: ['January', 'February', 'March', 'April', 'May', 'June'], + tooltip: { + theme: 'dark', + }, + }; + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/radial-radar/radial-radar.component.html b/theme/packages/main/src/app/pages/charts/radial-radar/radial-radar.component.html new file mode 100644 index 0000000..9dc4574 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/radial-radar/radial-radar.component.html @@ -0,0 +1,63 @@ +
+
+ + +

+ Radialbar +

+
+ + +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
+ + +

+ Radar +

+
+ + +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/charts/radial-radar/radial-radar.component.ts b/theme/packages/main/src/app/pages/charts/radial-radar/radial-radar.component.ts new file mode 100644 index 0000000..d59f555 --- /dev/null +++ b/theme/packages/main/src/app/pages/charts/radial-radar/radial-radar.component.ts @@ -0,0 +1,134 @@ +import { Component, ViewChild } from '@angular/core'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { RADAR_CHART_HTML_SNIPPET, RADIALBAR_CHART_HTML_SNIPPET } from './code/radial-radar-html-snippet'; +import { RADAR_CHART_TS_SNIPPET, RADIALBAR_CHART_TS_SNIPPET } from './code/radial-radar-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, +} from 'ng-apexcharts'; +import { MaterialModule } from '../../../material.module'; + +export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; +}; + +@Component({ + selector: 'app-radial-radar', + imports: [NgApexchartsModule, MaterialModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './radial-radar.component.html' +}) +export class AppRadialRadarChartComponent { + + // 1 [Radialbar with Datepicker] + codeForRadialbarChart = RADIALBAR_CHART_HTML_SNIPPET; + codeForRadialbarChartTs = RADIALBAR_CHART_TS_SNIPPET; + + // 2 [Radar with Datepicker] + codeForRadarChart = RADAR_CHART_HTML_SNIPPET; + codeForRadarChartTs = RADAR_CHART_TS_SNIPPET; + + + @ViewChild('chart') chart: ChartComponent = Object.create(null); + public radialbarChartOptions: Partial | any; + public radarChartOptions: Partial | any; + + constructor() { + //radialbar chart. + this.radialbarChartOptions = { + series: [44, 55, 67, 83], + chart: { + id: 'radial-chart', + type: 'radialBar', + height: 350, + fontFamily: "'Plus Jakarta Sans', sans-serif", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + }, + colors: ['#5D87FF', '#49BEFF', '#13DEB9', '#FFAE1F'], + plotOptions: { + radialBar: { + dataLabels: { + name: { + fontSize: '22px', + }, + value: { + fontSize: '16px', + }, + total: { + show: true, + label: 'Total', + formatter() { + return 249; + }, + }, + }, + }, + }, + tooltip: { + theme: 'dark', + }, + }; + + //radialbar chart. + this.radarChartOptions = { + series: [ + { + name: 'Sales', + data: [80, 50, 30, 40, 100, 20], + }, + ], + chart: { + id: 'pie-chart', + type: 'radar', + fontFamily: "'Plus Jakarta Sans', sans-serif", + toolbar: { + show: false, + }, + }, + colors: ['#5D87FF'], + labels: ['January', 'February', 'March', 'April', 'May', 'June'], + tooltip: { + theme: 'dark', + }, + }; + } +} diff --git a/theme/packages/main/src/app/pages/dashboards/dashboard1/dashboard1.component.html b/theme/packages/main/src/app/pages/dashboards/dashboard1/dashboard1.component.html new file mode 100644 index 0000000..3122409 --- /dev/null +++ b/theme/packages/main/src/app/pages/dashboards/dashboard1/dashboard1.component.html @@ -0,0 +1,42 @@ + + +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
diff --git a/theme/packages/main/src/app/pages/dashboards/dashboard1/dashboard1.component.ts b/theme/packages/main/src/app/pages/dashboards/dashboard1/dashboard1.component.ts new file mode 100644 index 0000000..080b031 --- /dev/null +++ b/theme/packages/main/src/app/pages/dashboards/dashboard1/dashboard1.component.ts @@ -0,0 +1,37 @@ +import { Component } from '@angular/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +// components +import { AppTopCardsComponent } from '../../../components/dashboard1/top-cards/top-cards.component'; +import { AppRevenueUpdatesComponent } from '../../../components/dashboard1/revenue-updates/revenue-updates.component'; +import { AppYearlyBreakupComponent } from '../../../components/dashboard1/yearly-breakup/yearly-breakup.component'; +import { AppMonthlyEarningsComponent } from '../../../components/dashboard1/monthly-earnings/monthly-earnings.component'; +import { AppEmployeeSalaryComponent } from '../../../components/dashboard1/employee-salary/employee-salary.component'; +import { AppCustomersComponent } from '../../../components/dashboard1/customers/customers.component'; +import { AppSocialCardComponent } from '../../../components/dashboard1/social-card/social-card.component'; +import { AppSellingProductComponent } from '../../../components/dashboard1/selling-product/selling-product.component'; +import { AppWeeklyStatsComponent } from '../../../components/dashboard1/weekly-stats/weekly-stats.component'; +import { AppTopProjectsComponent } from '../../../components/dashboard1/top-projects/top-projects.component'; +import { AppProjectsComponent } from '../../../components/dashboard1/projects/projects.component'; + +@Component({ + selector: 'app-dashboard1', + imports: [ + TablerIconsModule, + AppTopCardsComponent, + AppRevenueUpdatesComponent, + AppYearlyBreakupComponent, + AppMonthlyEarningsComponent, + AppEmployeeSalaryComponent, + AppCustomersComponent, + AppSocialCardComponent, + AppSellingProductComponent, + AppWeeklyStatsComponent, + AppTopProjectsComponent, + AppProjectsComponent + ], + templateUrl: './dashboard1.component.html' +}) +export class AppDashboard1Component { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/dashboards/dashboard2/dashboard2.component.html b/theme/packages/main/src/app/pages/dashboards/dashboard2/dashboard2.component.html new file mode 100644 index 0000000..ad78da6 --- /dev/null +++ b/theme/packages/main/src/app/pages/dashboards/dashboard2/dashboard2.component.html @@ -0,0 +1,49 @@ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
diff --git a/theme/packages/main/src/app/pages/dashboards/dashboard2/dashboard2.component.ts b/theme/packages/main/src/app/pages/dashboards/dashboard2/dashboard2.component.ts new file mode 100644 index 0000000..03a323f --- /dev/null +++ b/theme/packages/main/src/app/pages/dashboards/dashboard2/dashboard2.component.ts @@ -0,0 +1,39 @@ +import { Component } from '@angular/core'; + +// components +import { AppWelcomeCardComponent } from '../../../components/dashboard2/welcome-card/welcome-card.component'; +import { AppPaymentsComponent } from '../../../components/dashboard2/payments/payments.component'; +import { AppProductsComponent } from '../../../components/dashboard2/products/products.component'; +import { AppRevenueUpdatesTwoComponent } from '../../../components/dashboard2/revenue-updates/revenue-updates.component'; +import { AppSalesOverviewComponent } from '../../../components/dashboard2/sales-overview/sales-overview.component'; +import { AppTotalEarningsComponent } from '../../../components/dashboard2/total-earnings/total-earnings.component'; +import { AppSalesProfitComponent } from '../../../components/dashboard2/sales-profit/sales-profit.component'; +import { AppMonthlyEarningsTwoComponent } from '../../../components/dashboard2/monthly-earnings/monthly-earnings.component'; +import { AppWeeklyStatsComponent } from '../../../components/dashboard1/weekly-stats/weekly-stats.component'; +import { AppYearlySalesComponent } from '../../../components/dashboard2/yearly-sales/yearly-sales.component'; +import { AppPaymentGatewaysComponent } from '../../../components/dashboard2/payment-gateways/payment-gateways.component'; +import { AppRecentTransactionsComponent } from '../../../components/dashboard2/recent-transactions/recent-transactions.component'; +import { AppTopProjectsComponent } from '../../../components/dashboard2/top-projects/top-projects.component'; + +@Component({ + selector: 'app-dashboard2', + imports: [ + AppWelcomeCardComponent, + AppPaymentsComponent, + AppProductsComponent, + AppRevenueUpdatesTwoComponent, + AppSalesOverviewComponent, + AppTotalEarningsComponent, + AppSalesProfitComponent, + AppMonthlyEarningsTwoComponent, + AppWeeklyStatsComponent, + AppYearlySalesComponent, + AppPaymentGatewaysComponent, + AppRecentTransactionsComponent, + AppTopProjectsComponent, + ], + templateUrl: './dashboard2.component.html', +}) +export class AppDashboard2Component { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/dashboards/dashboards.module.ts b/theme/packages/main/src/app/pages/dashboards/dashboards.module.ts new file mode 100644 index 0000000..3a54de8 --- /dev/null +++ b/theme/packages/main/src/app/pages/dashboards/dashboards.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { DashboardsRoutes } from './dashboards.routing'; + +import { AppDashboard1Component } from './dashboard1/dashboard1.component'; +import { AppDashboard2Component } from './dashboard2/dashboard2.component'; + +@NgModule({ + imports: [ + RouterModule.forChild(DashboardsRoutes), + AppDashboard1Component, + AppDashboard2Component, + ], +}) +export class DashboardsModule {} diff --git a/theme/packages/main/src/app/pages/dashboards/dashboards.routes.ts b/theme/packages/main/src/app/pages/dashboards/dashboards.routes.ts new file mode 100644 index 0000000..b8a44c7 --- /dev/null +++ b/theme/packages/main/src/app/pages/dashboards/dashboards.routes.ts @@ -0,0 +1,35 @@ +import { Routes } from '@angular/router'; + +// dashboards +import { AppDashboard1Component } from './dashboard1/dashboard1.component'; +import { AppDashboard2Component } from './dashboard2/dashboard2.component'; + +export const DashboardsRoutes: Routes = [ + { + path: '', + children: [ + { + path: 'dashboard1', + component: AppDashboard1Component, + data: { + title: 'Analytical', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Analytical' }, + ], + }, + }, + { + path: 'dashboard2', + component: AppDashboard2Component, + data: { + title: 'eCommerce', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'eCommerce' }, + ], + }, + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/pages/datatable/datatable.routes.ts b/theme/packages/main/src/app/pages/datatable/datatable.routes.ts new file mode 100644 index 0000000..31779cc --- /dev/null +++ b/theme/packages/main/src/app/pages/datatable/datatable.routes.ts @@ -0,0 +1,22 @@ +import { Routes } from '@angular/router'; + +import { AppKichenSinkComponent } from './kichen-sink/kichen-sink.component'; + +export const DatatablesRoutes: Routes = [ + { + path: '', + children: [ + { + path: 'kichen-sink', + component: AppKichenSinkComponent, + data: { + title: 'Datatable', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Datatable' }, + ], + }, + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/pages/datatable/kichen-sink/add/add.component.html b/theme/packages/main/src/app/pages/datatable/kichen-sink/add/add.component.html new file mode 100644 index 0000000..f5ca708 --- /dev/null +++ b/theme/packages/main/src/app/pages/datatable/kichen-sink/add/add.component.html @@ -0,0 +1,7 @@ +
+

Employee Successfully Added.

+

You can find your employee at last of table.

+
+ + + diff --git a/theme/packages/main/src/app/pages/datatable/kichen-sink/add/add.component.ts b/theme/packages/main/src/app/pages/datatable/kichen-sink/add/add.component.ts new file mode 100644 index 0000000..4f92965 --- /dev/null +++ b/theme/packages/main/src/app/pages/datatable/kichen-sink/add/add.component.ts @@ -0,0 +1,14 @@ +import { CommonModule, DatePipe } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; + +@Component({ + selector: 'app-add', + imports: [MatDialogModule, CommonModule, MatButtonModule], + templateUrl: './add.component.html', + providers: [DatePipe] +}) +export class AppAddKichenSinkComponent { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink-dialog-content.html b/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink-dialog-content.html new file mode 100644 index 0000000..5e3442c --- /dev/null +++ b/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink-dialog-content.html @@ -0,0 +1,147 @@ +

{{action}}

+ +@if(action !== 'Delete') { + +
+
+ + +
+
+
+ Name + + + +
+
+ Position + + + +
+
+ Email + + + +
+
+ Mobile Number + + + +
+
+ Date of Birth + + + +
+
+ Salary + + + +
+
+ Projects + + + +
+
+ + +
+
+} @else { +
+

Sure to delete {{local_data.Name}} ?

+
+
+ + +
+} diff --git a/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink.component.html b/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink.component.html new file mode 100644 index 0000000..545175f --- /dev/null +++ b/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink.component.html @@ -0,0 +1,123 @@ + + +
+
+ + + + + + +
+
+ +
+
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#{{ element.id }}Name +
+ +
+

+ {{ element.Name }} +

+ {{ element.Position }} +
+
+
+ Email + {{ element.Email }} + Mobile + + {{ element.Mobile }} + + Date of Joining + + {{ element.DateOfJoining | date : "fullDate" }} + + Salary + + {{ element.Salary }} + + Projects + + {{ element.Projects }} + + Action +
+ +
+
+
diff --git a/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink.component.ts b/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink.component.ts new file mode 100644 index 0000000..cc382ea --- /dev/null +++ b/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink.component.ts @@ -0,0 +1,303 @@ +import { + Component, + Inject, + Optional, + ViewChild, + AfterViewInit, +} from '@angular/core'; +import { + MatTableDataSource, + MatTable, + MatTableModule, +} from '@angular/material/table'; +import { MatPaginator } from '@angular/material/paginator'; +import { + MatDialog, + MatDialogRef, + MAT_DIALOG_DATA, + MatDialogModule, +} from '@angular/material/dialog'; +import { CommonModule, DatePipe } from '@angular/common'; +import { AppAddKichenSinkComponent } from './add/add.component'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatCardModule } from '@angular/material/card'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { NgxPaginationModule } from 'ngx-pagination'; +import { MatNativeDateModule } from '@angular/material/core'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { MaterialModule } from 'src/app/material.module'; + +export interface Employee { + id: number; + Name: string; + Position: string; + Email: string; + Mobile: number; + DateOfJoining: Date; + Salary: number; + Projects: number; + imagePath: string; +} + +const employees = [ + { + id: 1, + Name: 'Johnathan Deo', + Position: 'Seo Expert', + Email: 'r@gmail.com', + Mobile: 9786838, + DateOfJoining: new Date('01-2-2020'), + Salary: 12000, + Projects: 10, + imagePath: 'assets/images/profile/user-2.jpg', + }, + { + id: 2, + Name: 'Mark Zukerburg', + Position: 'Web Developer', + Email: 'mark@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('04-2-2020'), + Salary: 12000, + Projects: 10, + imagePath: 'assets/images/profile/user-3.jpg', + }, + { + id: 3, + Name: 'Sam smith', + Position: 'Web Designer', + Email: 'sam@gmail.com', + Mobile: 7788838, + DateOfJoining: new Date('02-2-2020'), + Salary: 12000, + Projects: 10, + imagePath: 'assets/images/profile/user-4.jpg', + }, + { + id: 4, + Name: 'John Deo', + Position: 'Tester', + Email: 'john@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('03-2-2020'), + Salary: 12000, + Projects: 11, + imagePath: 'assets/images/profile/user-5.jpg', + }, + { + id: 5, + Name: 'Genilia', + Position: 'Actor', + Email: 'genilia@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('05-2-2020'), + Salary: 12000, + Projects: 19, + imagePath: 'assets/images/profile/user-6.jpg', + }, + { + id: 6, + Name: 'Jack Sparrow', + Position: 'Content Writer', + Email: 'jac@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('05-21-2020'), + Salary: 12000, + Projects: 5, + imagePath: 'assets/images/profile/user-7.jpg', + }, + { + id: 7, + Name: 'Tom Cruise', + Position: 'Actor', + Email: 'tom@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('02-15-2019'), + Salary: 12000, + Projects: 9, + imagePath: 'assets/images/profile/user-3.jpg', + }, + { + id: 8, + Name: 'Hary Porter', + Position: 'Actor', + Email: 'hary@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('07-3-2019'), + Salary: 12000, + Projects: 7, + imagePath: 'assets/images/profile/user-6.jpg', + }, + { + id: 9, + Name: 'Kristen Ronaldo', + Position: 'Player', + Email: 'kristen@gmail.com', + Mobile: 8786838, + DateOfJoining: new Date('01-15-2019'), + Salary: 12000, + Projects: 1, + imagePath: 'assets/images/profile/user-5.jpg', + }, +]; + +@Component({ + templateUrl: './kichen-sink.component.html', + imports: [ + MaterialModule, + TablerIconsModule, + MatNativeDateModule, + NgScrollbarModule, + CommonModule, + ], + providers: [DatePipe] +}) +export class AppKichenSinkComponent implements AfterViewInit { + @ViewChild(MatTable, { static: true }) table: MatTable = + Object.create(null); + searchText: any; + displayedColumns: string[] = [ + '#', + 'name', + 'email', + 'mobile', + 'date of joining', + 'salary', + 'projects', + 'action', + ]; + dataSource = new MatTableDataSource(employees); + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator = + Object.create(null); + + constructor(public dialog: MatDialog, public datePipe: DatePipe) {} + + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + } + + applyFilter(filterValue: string): void { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + openDialog(action: string, obj: any): void { + obj.action = action; + const dialogRef = this.dialog.open(AppKichenSinkDialogContentComponent, { + data: obj, + }); + dialogRef.afterClosed().subscribe((result) => { + if (result.event === 'Add') { + this.addRowData(result.data); + } else if (result.event === 'Update') { + this.updateRowData(result.data); + } else if (result.event === 'Delete') { + this.deleteRowData(result.data); + } + }); + } + + // tslint:disable-next-line - Disables all + addRowData(row_obj: Employee): void { + this.dataSource.data.unshift({ + id: employees.length + 1, + Name: row_obj.Name, + Position: row_obj.Position, + Email: row_obj.Email, + Mobile: row_obj.Mobile, + + DateOfJoining: new Date(), + Salary: row_obj.Salary, + Projects: row_obj.Projects, + imagePath: row_obj.imagePath, + }); + this.dialog.open(AppAddKichenSinkComponent); + this.table.renderRows(); + } + + // tslint:disable-next-line - Disables all + updateRowData(row_obj: Employee): boolean | any { + this.dataSource.data = this.dataSource.data.filter((value: any) => { + if (value.id === row_obj.id) { + value.Name = row_obj.Name; + value.Position = row_obj.Position; + value.Email = row_obj.Email; + value.Mobile = row_obj.Mobile; + value.DateOfJoining = row_obj.DateOfJoining; + value.Salary = row_obj.Salary; + value.Projects = row_obj.Projects; + value.imagePath = row_obj.imagePath; + } + return true; + }); + } + + // tslint:disable-next-line - Disables all + deleteRowData(row_obj: Employee): boolean | any { + this.dataSource.data = this.dataSource.data.filter((value: any) => { + return value.id !== row_obj.id; + }); + } +} + +@Component({ + // tslint:disable-next-line: component-selector + selector: 'app-dialog-content', + imports: [MatDialogModule, FormsModule, MaterialModule], + providers: [DatePipe], + templateUrl: 'kichen-sink-dialog-content.html' +}) +// tslint:disable-next-line: component-class-suffix +export class AppKichenSinkDialogContentComponent { + action: string; + // tslint:disable-next-line - Disables all + local_data: any; + selectedImage: any = ''; + joiningDate: any = ''; + + constructor( + public datePipe: DatePipe, + public dialogRef: MatDialogRef, + // @Optional() is used to prevent error if no data is passed + @Optional() @Inject(MAT_DIALOG_DATA) public data: Employee + ) { + this.local_data = { ...data }; + this.action = this.local_data.action; + if (this.local_data.DateOfJoining !== undefined) { + this.joiningDate = this.datePipe.transform( + new Date(this.local_data.DateOfJoining), + 'yyyy-MM-dd' + ); + } + if (this.local_data.imagePath === undefined) { + this.local_data.imagePath = 'assets/images/profile/user-1.jpg'; + } + } + + doAction(): void { + this.dialogRef.close({ event: this.action, data: this.local_data }); + } + closeDialog(): void { + this.dialogRef.close({ event: 'Cancel' }); + } + + selectFile(event: any): void { + if (!event.target.files[0] || event.target.files[0].length === 0) { + // this.msg = 'You must select an image'; + return; + } + const mimeType = event.target.files[0].type; + if (mimeType.match(/image\/*/) == null) { + // this.msg = "Only images are supported"; + return; + } + // tslint:disable-next-line - Disables all + const reader = new FileReader(); + reader.readAsDataURL(event.target.files[0]); + // tslint:disable-next-line - Disables all + reader.onload = (_event) => { + // tslint:disable-next-line - Disables all + this.local_data.imagePath = reader.result; + }; + } +} diff --git a/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink.ts b/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink.ts new file mode 100644 index 0000000..f20bd3a --- /dev/null +++ b/theme/packages/main/src/app/pages/datatable/kichen-sink/kichen-sink.ts @@ -0,0 +1,10 @@ +export interface Employee { + id: number; + creator: string; + title: string; + assignee: string; + status: string; + labelbg: string; + product: string; + date: string; +} diff --git a/theme/packages/main/src/app/pages/forms/form-editor/form-editor.component.html b/theme/packages/main/src/app/pages/forms/form-editor/form-editor.component.html new file mode 100644 index 0000000..8ebd610 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-editor/form-editor.component.html @@ -0,0 +1,8 @@ + + +
+ + +
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-editor/form-editor.component.ts b/theme/packages/main/src/app/pages/forms/form-editor/form-editor.component.ts new file mode 100644 index 0000000..130e645 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-editor/form-editor.component.ts @@ -0,0 +1,34 @@ +import { Component } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; +import { NgxEditorComponent, NgxEditorMenuComponent, Editor, Toolbar } from 'ngx-editor'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-form-editor', + imports: [MatCardModule, NgxEditorComponent, NgxEditorMenuComponent, FormsModule], + templateUrl: './form-editor.component.html' +}) +export class AppFormEditorComponent { + + html = ''; + editor: Editor; + ngOnInit(): void { + this.editor = new Editor(); + } + + ngOnDestroy(): void { + this.editor.destroy(); + } + + toolbar: Toolbar = [ + ['bold', 'italic'], + ['underline'], + ['ordered_list', 'bullet_list'], + [{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }], + ['link', 'image'], + ['text_color', 'background_color'], + ['align_left', 'align_center', 'align_right', 'align_justify'], + ]; + + constructor() { } +} diff --git a/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/autocomplete.component.html b/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/autocomplete.component.html new file mode 100644 index 0000000..ade1eff --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/autocomplete.component.html @@ -0,0 +1,187 @@ + +
+ Autocomplete +
+ +
+
+ + +

+ First autocomplete option +

+
+
+ + Number + + + @for(firstoption of filteredOptions | async; track + firstoption) { + + {{ firstoption }} + + } + + +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Option Group +

+
+
+ + States Group + + + @for(group of stateGroupOptions | async; track group) { + + @for(name of group.names; track name) { + + {{ name }} + + } + + } + + +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Filter +

+
+
+ + Number + + + @for(searchoption of searchfilteredOptions | async; track + searchoption) { + + {{ searchoption }} + + } + + +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Overview +

+
+
+ + State + + + @for(state of filteredStates | async; track state.name) { + + + + {{ state.name }} | + Population: {{ state.population }} + + } + + + +
+ + + Disable Input? + +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/autocomplete.component.ts b/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/autocomplete.component.ts new file mode 100644 index 0000000..2ed8a44 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/autocomplete.component.ts @@ -0,0 +1,288 @@ +import { Component, OnInit } from '@angular/core'; +import { + FormBuilder, + FormControl, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { Observable } from 'rxjs'; +import { startWith, map } from 'rxjs/operators'; +import { MaterialModule } from '../../../../material.module'; +import { CommonModule } from '@angular/common'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { FILTER_TS_SNIPPET, FIRST_AUTOCOMPLETE_OPTION_TS_SNIPPET, OPTION_GROUP_TS_SNIPPET, OVERVIEW_TS_SNIPPET } from './code/autocomplete-ts-snippet'; +import { FILTER_HTML_SNIPPET, FIRST_AUTOCOMPLETE_OPTION_HTML_SNIPPET, OPTION_GROUP_HTML_SNIPPET, OVERVIEW_HTML_SNIPPET } from './code/autocomplete-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +// option group +export interface StateGroup { + letter: string; + names: string[]; +} + +export const _filter = (opt: string[], value: string): string[] => { + const filterValue = value.toLowerCase(); + + return opt.filter((item) => item.toLowerCase().includes(filterValue)); +}; + +// display option +export interface User { + name: string; +} + +// state + +export interface State { + flag: string; + name: string; + population: string; +} + +@Component({ + selector: 'app-autocomplete', + imports: [MaterialModule, FormsModule, ReactiveFormsModule, CommonModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './autocomplete.component.html' +}) +export class AppAutocompleteComponent implements OnInit { + + // 1 [First with Autocomplete] + codeForFirstAutocompleteOption = FIRST_AUTOCOMPLETE_OPTION_HTML_SNIPPET; + codeForFirstAutocompleteOptionTs = FIRST_AUTOCOMPLETE_OPTION_TS_SNIPPET; + + // 2 [Option Group with Autocomplete] + codeForOptionGroup = OPTION_GROUP_HTML_SNIPPET; + codeForOptionGroupTs = OPTION_GROUP_TS_SNIPPET; + + // 3 [Filter with Autocomplete] + codeForFilter = FILTER_HTML_SNIPPET; + codeForFilterTs = FILTER_TS_SNIPPET; + + // 4 [overview with Autocomplete] + codeForOverview = OVERVIEW_HTML_SNIPPET; + codeForOverviewTs = OVERVIEW_TS_SNIPPET; + + + // first option + firstControl = new FormControl(''); + firstoption: string[] = ['One', 'Two', 'Three']; + filteredOptions: Observable; + + // option group + stateForm = this._formBuilder.group({ + stateGroup: '', + }); + + stateGroups: StateGroup[] = [ + { + letter: 'A', + names: ['Alabama', 'Alaska', 'Arizona', 'Arkansas'], + }, + { + letter: 'C', + names: ['California', 'Colorado', 'Connecticut'], + }, + { + letter: 'D', + names: ['Delaware'], + }, + { + letter: 'F', + names: ['Florida'], + }, + { + letter: 'G', + names: ['Georgia'], + }, + { + letter: 'H', + names: ['Hawaii'], + }, + { + letter: 'I', + names: ['Idaho', 'Illinois', 'Indiana', 'Iowa'], + }, + { + letter: 'K', + names: ['Kansas', 'Kentucky'], + }, + { + letter: 'L', + names: ['Louisiana'], + }, + { + letter: 'M', + names: [ + 'Maine', + 'Maryland', + 'Massachusetts', + 'Michigan', + 'Minnesota', + 'Mississippi', + 'Missouri', + 'Montana', + ], + }, + { + letter: 'N', + names: [ + 'Nebraska', + 'Nevada', + 'New Hampshire', + 'New Jersey', + 'New Mexico', + 'New York', + 'North Carolina', + 'North Dakota', + ], + }, + { + letter: 'O', + names: ['Ohio', 'Oklahoma', 'Oregon'], + }, + { + letter: 'P', + names: ['Pennsylvania'], + }, + { + letter: 'R', + names: ['Rhode Island'], + }, + { + letter: 'S', + names: ['South Carolina', 'South Dakota'], + }, + { + letter: 'T', + names: ['Tennessee', 'Texas'], + }, + { + letter: 'U', + names: ['Utah'], + }, + { + letter: 'V', + names: ['Vermont', 'Virginia'], + }, + { + letter: 'W', + names: ['Washington', 'West Virginia', 'Wisconsin', 'Wyoming'], + }, + ]; + + stateGroupOptions: Observable; + + // filter option + filterControl = new FormControl(''); + searchoption: string[] = ['One', 'Two', 'Three']; + searchfilteredOptions: Observable; + + // state + stateCtrl = new FormControl(''); + filteredStates: Observable; + + states: State[] = [ + { + name: 'Arkansas', + population: '2.978M', + // https://commons.wikimedia.org/wiki/File:Flag_of_Arkansas.svg + flag: 'https://upload.wikimedia.org/wikipedia/commons/9/9d/Flag_of_Arkansas.svg', + }, + { + name: 'California', + population: '39.14M', + // https://commons.wikimedia.org/wiki/File:Flag_of_California.svg + flag: 'https://upload.wikimedia.org/wikipedia/commons/0/01/Flag_of_California.svg', + }, + { + name: 'Florida', + population: '20.27M', + // https://commons.wikimedia.org/wiki/File:Flag_of_Florida.svg + flag: 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Flag_of_Florida.svg', + }, + { + name: 'Texas', + population: '27.47M', + // https://commons.wikimedia.org/wiki/File:Flag_of_Texas.svg + flag: 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Flag_of_Texas.svg', + }, + ]; + + constructor(private _formBuilder: FormBuilder) { + this.filteredStates = this.stateCtrl.valueChanges.pipe( + startWith(''), + map((state) => (state ? this._filterStates(state) : this.states.slice())) + ); + } + + private _filterStates(value: string): State[] { + const filterValue = value.toLowerCase(); + + return this.states.filter((state) => + state.name.toLowerCase().includes(filterValue) + ); + } + + ngOnInit() { + // first option + this.filteredOptions = this.firstControl.valueChanges.pipe( + startWith(''), + map((value) => this._filter(value || '')) + ); + + // option group + this.stateGroupOptions = this.stateForm + .get('stateGroup')! + .valueChanges.pipe( + startWith(''), + map((value) => this._filterGroup(value || '')) + ); + + // filter option + this.searchfilteredOptions = this.filterControl.valueChanges.pipe( + startWith(''), + map((value) => this._searchfilter(value || '')) + ); + } + + // first option + private _filter(value: string): string[] { + const filterValue = value.toLowerCase(); + + return this.firstoption.filter((option) => + option.toLowerCase().includes(filterValue) + ); + } + + // option group + private _filterGroup(value: string): StateGroup[] { + if (value) { + return this.stateGroups + .map((group) => ({ + letter: group.letter, + names: _filter(group.names, value), + })) + .filter((group) => group.names.length > 0); + } + + return this.stateGroups; + } + + // filter option + private _searchfilter(value: string): string[] { + const searchfilterValue = value.toLowerCase(); + + return this.searchoption.filter((searchoption) => + searchoption.toLowerCase().includes(searchfilterValue) + ); + } +} diff --git a/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/code/autocomplete-html-snippet.ts b/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/code/autocomplete-html-snippet.ts new file mode 100644 index 0000000..7850b6f --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/code/autocomplete-html-snippet.ts @@ -0,0 +1,78 @@ +export const FIRST_AUTOCOMPLETE_OPTION_HTML_SNIPPET = `
+ + Number + + + @for(firstoption of filteredOptions | async; track + firstoption) { + + {{ firstoption }} + + } + + +
+`; + +export const OPTION_GROUP_HTML_SNIPPET = `
+ + States Group + + + @for(group of stateGroupOptions | async; track group) { + + @for(name of group.names; track name) { + + {{ name }} + + } + + } + + +
+`; + +export const FILTER_HTML_SNIPPET = `
+ + Number + + + @for(searchoption of searchfilteredOptions | async; track + searchoption) { + + {{ searchoption }} + + } + + +
+`; + +export const OVERVIEW_HTML_SNIPPET = `
+ + State + + + @for(state of filteredStates | async; track state.name) { + + + + {{ state.name }} | + Population: {{ state.population }} + + } + + + +
+ + + Disable Input? + +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/code/autocomplete-ts-snippet.ts b/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/code/autocomplete-ts-snippet.ts new file mode 100644 index 0000000..920ef27 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/autocomplete/code/autocomplete-ts-snippet.ts @@ -0,0 +1,348 @@ +export const FIRST_AUTOCOMPLETE_OPTION_TS_SNIPPET = ` import {Component, OnInit} from '@angular/core'; + import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {Observable} from 'rxjs'; + import {map, startWith} from 'rxjs/operators'; + import {AsyncPipe} from '@angular/common'; + import {MatAutocompleteModule} from '@angular/material/autocomplete'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + /** + * @title Highlight the first autocomplete option + */ + @Component({ + selector: 'app-autocomplete', + imports: [ + FormsModule, + MatFormFieldModule, + MatInputModule, + MatAutocompleteModule, + ReactiveFormsModule, + AsyncPipe, + ], + templateUrl: './autocomplete.component.html' + }) + export class AppAutocompleteComponent implements OnInit { + + firstControl = new FormControl(''); + firstoption: string[] = ['One', 'Two', 'Three']; + filteredOptions: Observable; + + ngOnInit() { + // first option + this.filteredOptions = this.firstControl.valueChanges.pipe( + startWith(''), + map((value) => this._filter(value || '')) + ); + } + + private _filter(value: string): string[] { + const filterValue = value.toLowerCase(); + + return this.firstoption.filter((option) => + option.toLowerCase().includes(filterValue) + ); + } + } +`; + +export const OPTION_GROUP_TS_SNIPPET = ` import {Component, OnInit, inject} from '@angular/core'; + import {FormBuilder, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {Observable} from 'rxjs'; + import {startWith, map} from 'rxjs/operators'; + import {AsyncPipe} from '@angular/common'; + import {MatAutocompleteModule} from '@angular/material/autocomplete'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + // option group + export interface StateGroup { + letter: string; + names: string[]; + } + + export const _filter = (opt: string[], value: string): string[] => { + const filterValue = value.toLowerCase(); + + return opt.filter((item) => item.toLowerCase().includes(filterValue)); + }; + + /** + * @title Option groups autocomplete + */ + @Component({ + selector: 'app-autocomplete', + imports: [ + FormsModule, + ReactiveFormsModule, + MatFormFieldModule, + MatInputModule, + MatAutocompleteModule, + AsyncPipe, + ], + templateUrl: './autocomplete.component.html' + }) + export class AppAutocompleteComponent implements OnInit { + + // option group + stateForm = this._formBuilder.group({ + stateGroup: '', + }); + + stateGroups: StateGroup[] = [ + { + letter: 'A', + names: ['Alabama', 'Alaska', 'Arizona', 'Arkansas'], + }, + { + letter: 'C', + names: ['California', 'Colorado', 'Connecticut'], + }, + { + letter: 'D', + names: ['Delaware'], + }, + { + letter: 'F', + names: ['Florida'], + }, + { + letter: 'G', + names: ['Georgia'], + }, + { + letter: 'H', + names: ['Hawaii'], + }, + { + letter: 'I', + names: ['Idaho', 'Illinois', 'Indiana', 'Iowa'], + }, + { + letter: 'K', + names: ['Kansas', 'Kentucky'], + }, + { + letter: 'L', + names: ['Louisiana'], + }, + { + letter: 'M', + names: [ + 'Maine', + 'Maryland', + 'Massachusetts', + 'Michigan', + 'Minnesota', + 'Mississippi', + 'Missouri', + 'Montana', + ], + }, + { + letter: 'N', + names: [ + 'Nebraska', + 'Nevada', + 'New Hampshire', + 'New Jersey', + 'New Mexico', + 'New York', + 'North Carolina', + 'North Dakota', + ], + }, + { + letter: 'O', + names: ['Ohio', 'Oklahoma', 'Oregon'], + }, + { + letter: 'P', + names: ['Pennsylvania'], + }, + { + letter: 'R', + names: ['Rhode Island'], + }, + { + letter: 'S', + names: ['South Carolina', 'South Dakota'], + }, + { + letter: 'T', + names: ['Tennessee', 'Texas'], + }, + { + letter: 'U', + names: ['Utah'], + }, + { + letter: 'V', + names: ['Vermont', 'Virginia'], + }, + { + letter: 'W', + names: ['Washington', 'West Virginia', 'Wisconsin', 'Wyoming'], + }, + ]; + + stateGroupOptions: Observable; + + ngOnInit() { + // option group + this.stateGroupOptions = this.stateForm + .get('stateGroup')! + .valueChanges.pipe( + startWith(''), + map((value) => this._filterGroup(value || '')) + ); + } + + // option group + private _filterGroup(value: string): StateGroup[] { + if (value) { + return this.stateGroups + .map((group) => ({ + letter: group.letter, + names: _filter(group.names, value), + })) + .filter((group) => group.names.length > 0); + } + + return this.stateGroups; + } + + } +`; + +export const FILTER_TS_SNIPPET = ` import {Component, OnInit} from '@angular/core'; + import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {Observable} from 'rxjs'; + import {map, startWith} from 'rxjs/operators'; + import {AsyncPipe} from '@angular/common'; + import {MatAutocompleteModule} from '@angular/material/autocomplete'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + /** + * @title Filter autocomplete + */ + @Component({ + selector: 'app-autocomplete', + imports: [ + FormsModule, + MatFormFieldModule, + MatInputModule, + MatAutocompleteModule, + ReactiveFormsModule, + AsyncPipe, + ], + templateUrl: './autocomplete.component.html' + }) + export class AppAutocompleteComponent implements OnInit { + + // filter option + filterControl = new FormControl(''); + searchoption: string[] = ['One', 'Two', 'Three']; + searchfilteredOptions: Observable; + + ngOnInit() { + // filter option + this.searchfilteredOptions = this.filterControl.valueChanges.pipe( + startWith(''), + map((value) => this._searchfilter(value || '')) + ); + } + + // filter option + private _searchfilter(value: string): string[] { + const searchfilterValue = value.toLowerCase(); + + return this.searchoption.filter((searchoption) => + searchoption.toLowerCase().includes(searchfilterValue) + ); + } + } +`; + +export const OVERVIEW_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {Observable} from 'rxjs'; + import {map, startWith} from 'rxjs/operators'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {AsyncPipe} from '@angular/common'; + import {MatAutocompleteModule} from '@angular/material/autocomplete'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + export interface State { + flag: string; + name: string; + population: string; + } + + /** + * @title Autocomplete overview + */ + @Component({ + selector: 'app-autocomplete', + imports: [ + FormsModule, + MatFormFieldModule, + MatInputModule, + MatAutocompleteModule, + ReactiveFormsModule, + MatSlideToggleModule, + AsyncPipe, + ], + templateUrl: './autocomplete.component.html' + }) + export class AppAutocompleteComponent implements OnInit { + + // state + stateCtrl = new FormControl(''); + filteredStates: Observable; + + states: State[] = [ + { + name: 'Arkansas', + population: '2.978M', + // https://commons.wikimedia.org/wiki/File:Flag_of_Arkansas.svg + flag: 'https://upload.wikimedia.org/wikipedia/commons/9/9d/Flag_of_Arkansas.svg', + }, + { + name: 'California', + population: '39.14M', + // https://commons.wikimedia.org/wiki/File:Flag_of_California.svg + flag: 'https://upload.wikimedia.org/wikipedia/commons/0/01/Flag_of_California.svg', + }, + { + name: 'Florida', + population: '20.27M', + // https://commons.wikimedia.org/wiki/File:Flag_of_Florida.svg + flag: 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Flag_of_Florida.svg', + }, + { + name: 'Texas', + population: '27.47M', + // https://commons.wikimedia.org/wiki/File:Flag_of_Texas.svg + flag: 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Flag_of_Texas.svg', + }, + ]; + + constructor(private _formBuilder: FormBuilder) { + this.filteredStates = this.stateCtrl.valueChanges.pipe( + startWith(''), + map((state) => (state ? this._filterStates(state) : this.states.slice())) + ); + } + + private _filterStates(value: string): State[] { + const filterValue = value.toLowerCase(); + + return this.states.filter((state) => + state.name.toLowerCase().includes(filterValue) + ); + } + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/button/button.component.html b/theme/packages/main/src/app/pages/forms/form-elements/button/button.component.html new file mode 100644 index 0000000..012ef95 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/button/button.component.html @@ -0,0 +1,502 @@ + +
+ Buttons +
+ +
+
+ + +

+ Basic +

+
+
+ + + Link +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Raised +

+
+
+ + + Link +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Outlined +

+
+
+ + + + + + + Link +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Flat +

+
+
+ + + + + + + Link +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Icon +

+
+
+ + + + + +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Fab +

+
+
+ + + + + + + + + + + +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Mini Fab +

+
+
+ + + + + + + + + + + +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Extended Fab +

+
+
+ + + + + + + +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+
+
+ + +
+ Button Toggle +
+ +
+
+ + +

+ Basic +

+
+ + Bold + Italic + Underline + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Multiple Select +

+
+ + Flour + Eggs + Sugar + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Reactive Form +

+
+ + Bold + Italic + Underline + +

+ Chosen value is : {{ fontStyleControl.value }} +

+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Exclusive selection +

+
+ + + format_align_left + + + format_align_center + + + format_align_right + + + format_align_justify + + +
+ Selected value: {{ group.value }} +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/button/button.component.ts b/theme/packages/main/src/app/pages/forms/form-elements/button/button.component.ts new file mode 100644 index 0000000..0bd00f7 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/button/button.component.ts @@ -0,0 +1,79 @@ +import { Component } from '@angular/core'; +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MaterialModule } from '../../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BUTTONS_TS_SNIPPET, TOGGLE_BUTTONS_TS_SNIPPET } from './code/button-ts-snippet'; +import { BASIC_BUTTONS_HTML_SNIPPET, BASIC_TOGGLE_BUTTONS_HTML_SNIPPET, EXCLUSIVE_SELECTION_TOGGLE_BUTTONS_HTML_SNIPPET, EXTENDED_FAB_BUTTONS_HTML_SNIPPET, FAB_BUTTONS_HTML_SNIPPET, FLAT_BUTTONS_HTML_SNIPPET, ICON_BUTTONS_HTML_SNIPPET, MINI_FAB_BUTTONS_HTML_SNIPPET, MULTIPLE_SELECT_TOGGLE_BUTTONS_HTML_SNIPPET, OUTLINED_BUTTONS_HTML_SNIPPET, RAISED_BUTTONS_HTML_SNIPPET, REACTIVE_FORM_TOGGLE_BUTTONS_HTML_SNIPPET } from './code/button-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +@Component({ + selector: 'app-button', + imports: [FormsModule, ReactiveFormsModule, MaterialModule, TablerIconsModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './button.component.html' +}) +export class AppButtonComponent { + constructor() {} + + // 1 [Basic with Buttons] + codeForBasicButtons = BASIC_BUTTONS_HTML_SNIPPET; + codeForBasicButtonsTs = BUTTONS_TS_SNIPPET; + + // 2 [Raised with Buttons] + codeForRaisedButtons = RAISED_BUTTONS_HTML_SNIPPET; + codeForRaisedButtonsTs = BUTTONS_TS_SNIPPET; + + // 3 [Outlined with Buttons] + codeForOutlinedButtons = OUTLINED_BUTTONS_HTML_SNIPPET; + codeForOutlinedButtonsTs = BUTTONS_TS_SNIPPET; + + // 4 [Flat with Buttons] + codeForFlatButtons = FLAT_BUTTONS_HTML_SNIPPET; + codeForFlatButtonsTs = BUTTONS_TS_SNIPPET; + + // 5 [Icon with Buttons] + codeForIconButtons = ICON_BUTTONS_HTML_SNIPPET; + codeForIconButtonsTs = BUTTONS_TS_SNIPPET; + + // 6 [Fab with Buttons] + codeForFabButtons = FAB_BUTTONS_HTML_SNIPPET; + codeForFabButtonsTs = BUTTONS_TS_SNIPPET; + + // 7 [Mini Fab with Buttons] + codeForMiniFabButtons = MINI_FAB_BUTTONS_HTML_SNIPPET; + codeForMiniFabButtonsTs = BUTTONS_TS_SNIPPET; + + // 8 [Extended Fab with Buttons] + codeForExtendedFabButtons = EXTENDED_FAB_BUTTONS_HTML_SNIPPET; + codeForExtendedFabButtonsTs = BUTTONS_TS_SNIPPET; + + // 9 [Basic with Buttons] + codeForBasicToggleButtons = BASIC_TOGGLE_BUTTONS_HTML_SNIPPET; + codeForBasicToggleButtonsTs = TOGGLE_BUTTONS_TS_SNIPPET; + + // 10 [Multiple Select with Buttons] + codeForMultipleSelectToggleButtons = MULTIPLE_SELECT_TOGGLE_BUTTONS_HTML_SNIPPET; + codeForMultipleSelectToggleButtonsTs = TOGGLE_BUTTONS_TS_SNIPPET; + + // 11 [Reactive Form with Buttons] + codeForReactiveFormToggleButtons = REACTIVE_FORM_TOGGLE_BUTTONS_HTML_SNIPPET; + codeForReactiveFormToggleButtonsTs = TOGGLE_BUTTONS_TS_SNIPPET; + + // 12 [Exclusive selection with Buttons] + codeForExclusiveSelectionToggleButtons = EXCLUSIVE_SELECTION_TOGGLE_BUTTONS_HTML_SNIPPET; + codeForExclusiveSelectionToggleButtonsTs = TOGGLE_BUTTONS_TS_SNIPPET; + + // reactive form + fontStyleControl = new FormControl(''); + fontStyle?: string; +} diff --git a/theme/packages/main/src/app/pages/forms/form-elements/button/code/button-html-snippet.ts b/theme/packages/main/src/app/pages/forms/form-elements/button/code/button-html-snippet.ts new file mode 100644 index 0000000..813a660 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/button/code/button-html-snippet.ts @@ -0,0 +1,190 @@ +export const BASIC_BUTTONS_HTML_SNIPPET = `
+ + + Link +
+`; + +export const RAISED_BUTTONS_HTML_SNIPPET = `
+ + + Link +
+`; + +export const OUTLINED_BUTTONS_HTML_SNIPPET = `
+ + + + + + + Link +
+`; + +export const FLAT_BUTTONS_HTML_SNIPPET = `
+ + + + + + + Link +
+`; + +export const ICON_BUTTONS_HTML_SNIPPET = `
+ + + + + +
+`; + +export const FAB_BUTTONS_HTML_SNIPPET = `
+ + + + + + + + + + + +
+`; + +export const MINI_FAB_BUTTONS_HTML_SNIPPET = `
+ + + + + + + + + + + +
+`; + +export const EXTENDED_FAB_BUTTONS_HTML_SNIPPET = `
+ + + + + + + +
+`; + +export const BASIC_TOGGLE_BUTTONS_HTML_SNIPPET = ` + Bold + Italic + Underline + +`; + +export const MULTIPLE_SELECT_TOGGLE_BUTTONS_HTML_SNIPPET = ` + Flour + Eggs + Sugar + +`; + +export const REACTIVE_FORM_TOGGLE_BUTTONS_HTML_SNIPPET = ` + Bold + Italic + Underline + +

+ Chosen value is : {{ fontStyleControl.value }} +

+`; + +export const EXCLUSIVE_SELECTION_TOGGLE_BUTTONS_HTML_SNIPPET = ` + + format_align_left + + + format_align_center + + + format_align_right + + + format_align_justify + + +
+ Selected value: {{ group.value }} +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/button/code/button-ts-snippet.ts b/theme/packages/main/src/app/pages/forms/form-elements/button/code/button-ts-snippet.ts new file mode 100644 index 0000000..2ddf523 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/button/code/button-ts-snippet.ts @@ -0,0 +1,39 @@ +export const BUTTONS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatButtonModule} from '@angular/material/button'; + import {MatIconModule} from '@angular/material/icon'; + import { TablerIconsModule } from 'angular-tabler-icons'; + + /** + * @title Basic buttons + */ + @Component({ + selector: 'app-button', + imports: [MatButtonModule, MatIconModule, TablerIconsModule], + templateUrl: './button.component.html' + }) + export class AppButtonComponent { + constructor() {} + } +`; + +export const TOGGLE_BUTTONS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatButtonToggleModule} from '@angular/material/button-toggle'; + import {MatIconModule} from '@angular/material/icon'; + import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; + + /** + * @title Basic button-toggles + */ + @Component({ + selector: 'app-button', + imports: [MatButtonToggleModule, MatIconModule, FormsModule, ReactiveFormsModule], + templateUrl: './button.component.html' + }) + export class AppButtonComponent { + constructor() {} + + // reactive form + fontStyleControl = new FormControl(''); + fontStyle?: string; + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/checkbox/checkbox.component.html b/theme/packages/main/src/app/pages/forms/form-elements/checkbox/checkbox.component.html new file mode 100644 index 0000000..9924136 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/checkbox/checkbox.component.html @@ -0,0 +1,145 @@ + +
+ Checkbox +
+ + + +

+ Basic +

+
+
+ Check me! + Disabled +
+ +
+ + + {{task().name}} + + + +
+ @for (subtask of task().subtasks; track subtask; let i = $index) { +
+ + {{subtask.name}} + +
+ } +
+
+
+ +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Configuration +

+
+
+ + + After + Before + +
+ +
+ Checked + Indeterminate + Disabled +
+ +
+

Result

+ + I'm a checkbox + +
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Reactive Form +

+
+
+

Select your toppings:

+

+ Pepperoni +

+

+ Extra Cheese +

+

+ Mushroom +

+
+
+

You chose:

+ {{ toppings.value | json }} +
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/checkbox/checkbox.component.ts b/theme/packages/main/src/app/pages/forms/form-elements/checkbox/checkbox.component.ts new file mode 100644 index 0000000..64cdc3e --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/checkbox/checkbox.component.ts @@ -0,0 +1,91 @@ +import { Component, computed, signal } from '@angular/core'; +import { ThemePalette } from '@angular/material/core'; +import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MaterialModule } from '../../../../material.module'; +import { CommonModule } from '@angular/common'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_CHECKBOX_TS_SNIPPET, CONFIGURABLE_CHECKBOX_TS_SNIPPET, REACTIVE_FORM_CHECKBOX_TS_SNIPPET } from './code/checkbox-ts-snippet'; +import { BASIC_CHECKBOX_HTML_SNIPPET, CONFIGURABLE_CHECKBOX_HTML_SNIPPET, REACTIVE_FORM_CHECKBOX_HTML_SNIPPET } from './code/checkbox-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +export interface Task { + name: string; + completed: boolean; + subtasks?: Task[]; +} + +@Component({ + selector: 'app-checkbox', + imports: [MaterialModule, FormsModule, ReactiveFormsModule, CommonModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './checkbox.component.html' +}) +export class AppCheckboxComponent { + + // 1 [Basic with Checkbox] + codeForBasicCheckbox = BASIC_CHECKBOX_HTML_SNIPPET; + codeForBasicCheckboxTs = BASIC_CHECKBOX_TS_SNIPPET; + + // 2 [Configurable with Checkbox] + codeForConfigurableCheckbox = CONFIGURABLE_CHECKBOX_HTML_SNIPPET; + codeForConfigurableCheckboxTs = CONFIGURABLE_CHECKBOX_TS_SNIPPET; + + // 2 [Reactive Form with Checkbox] + codeForReactiveFormCheckbox = REACTIVE_FORM_CHECKBOX_HTML_SNIPPET; + codeForReactiveFormCheckboxTs = REACTIVE_FORM_CHECKBOX_TS_SNIPPET; + + // reactive form + toppings = this._formBuilder.group({ + pepperoni: false, + extracheese: false, + mushroom: false, + }); + + constructor(private _formBuilder: FormBuilder) {} + + // config + checked = false; + indeterminate = false; + labelPosition: 'before' | 'after' = 'after'; + disabled = false; + + // basic + readonly task = signal({ + name: 'Parent task', + completed: false, + subtasks: [ + {name: 'Child task 1', completed: false}, + {name: 'Child task 2', completed: false}, + {name: 'Child task 3', completed: false}, + ], + }); + + readonly partiallyComplete = computed(() => { + const task = this.task(); + if (!task.subtasks) { + return false; + } + return task.subtasks.some(t => t.completed) && !task.subtasks.every(t => t.completed); + }); + + update(completed: boolean, index?: number) { + this.task.update(task => { + if (index === undefined) { + task.completed = completed; + task.subtasks?.forEach(t => (t.completed = completed)); + } else { + task.subtasks![index].completed = completed; + task.completed = task.subtasks?.every(t => t.completed) ?? true; + } + return {...task}; + }); + } +} diff --git a/theme/packages/main/src/app/pages/forms/form-elements/checkbox/code/checkbox-html-snippet.ts b/theme/packages/main/src/app/pages/forms/form-elements/checkbox/code/checkbox-html-snippet.ts new file mode 100644 index 0000000..f6043f7 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/checkbox/code/checkbox-html-snippet.ts @@ -0,0 +1,71 @@ +export const BASIC_CHECKBOX_HTML_SNIPPET = `
+ Check me! + Disabled +
+ +
+ + + {{task().name}} + + + +
+ @for (subtask of task().subtasks; track subtask; let i = $index) { +
+ + {{subtask.name}} + +
+ } +
+
+
+ +`; + +export const CONFIGURABLE_CHECKBOX_HTML_SNIPPET = `
+ + + After + Before + +
+ +
+ Checked + Indeterminate + Disabled +
+ +
+

Result

+ + I'm a checkbox + +
+`; + +export const REACTIVE_FORM_CHECKBOX_HTML_SNIPPET = `
+

Select your toppings:

+

+ Pepperoni +

+

+ Extra Cheese +

+

+ Mushroom +

+
+
+

You chose:

+ {{ toppings.value | json }} +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/checkbox/code/checkbox-ts-snippet.ts b/theme/packages/main/src/app/pages/forms/form-elements/checkbox/code/checkbox-ts-snippet.ts new file mode 100644 index 0000000..7e61b1d --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/checkbox/code/checkbox-ts-snippet.ts @@ -0,0 +1,100 @@ +export const BASIC_CHECKBOX_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component, computed, signal} from '@angular/core'; + import { ThemePalette } from '@angular/material/core'; + import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; + import { CommonModule } from '@angular/common'; + + export interface Task { + name: string; + completed: boolean; + subtasks?: Task[]; + } + + /** + * @title Basic checkboxes + */ + @Component({ + selector: 'app-checkbox', + imports: [MaterialModule, FormsModule, ReactiveFormsModule, CommonModule], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './checkbox.component.html' + }) + export class AppCheckboxComponent { + readonly task = signal({ + name: 'Parent task', + completed: false, + subtasks: [ + {name: 'Child task 1', completed: false}, + {name: 'Child task 2', completed: false}, + {name: 'Child task 3', completed: false}, + ], + }); + + readonly partiallyComplete = computed(() => { + const task = this.task(); + if (!task.subtasks) { + return false; + } + return task.subtasks.some(t => t.completed) && !task.subtasks.every(t => t.completed); + }); + + update(completed: boolean, index?: number) { + this.task.update(task => { + if (index === undefined) { + task.completed = completed; + task.subtasks?.forEach(t => (t.completed = completed)); + } else { + task.subtasks![index].completed = completed; + task.completed = task.subtasks?.every(t => t.completed) ?? true; + } + return {...task}; + }); + } + } +`; + +export const CONFIGURABLE_CHECKBOX_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { ThemePalette } from '@angular/material/core'; + import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; + import { CommonModule } from '@angular/common'; + + /** + * @title Configurable checkbox + */ + @Component({ + selector: 'app-checkbox', + imports: [MaterialModule, FormsModule, ReactiveFormsModule, CommonModule], + templateUrl: './checkbox.component.html' + }) + export class AppCheckboxComponent { + constructor() {} + + checked = false; + indeterminate = false; + labelPosition: 'before' | 'after' = 'after'; + disabled = false; + } +`; + +export const REACTIVE_FORM_CHECKBOX_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { ThemePalette } from '@angular/material/core'; + import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; + import { CommonModule } from '@angular/common'; + + /** + * @title Configurable checkbox + */ + @Component({ + selector: 'app-checkbox', + imports: [MaterialModule, FormsModule, ReactiveFormsModule, CommonModule], + templateUrl: './checkbox.component.html' + }) + export class AppCheckboxComponent { + constructor() {} + + toppings = this._formBuilder.group({ + pepperoni: false, + extracheese: false, + mushroom: false, + }); + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/datepicker/code/datepicker-html-snippet.ts b/theme/packages/main/src/app/pages/forms/form-elements/datepicker/code/datepicker-html-snippet.ts new file mode 100644 index 0000000..f886bd9 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/datepicker/code/datepicker-html-snippet.ts @@ -0,0 +1,223 @@ +export const BASIC_DATEPICKER_HTML_SNIPPET = ` + Choose a date + + MM/DD/YYYY + + + +`; + +export const CUSTOM_SELECTIONS_DATEPICKER_HTML_SNIPPET = ` + Enter a date range + + + + + MM/DD/YYYY – MM/DD/YYYY + + + +`; + +export const FORM_INTEGRATION_DATEPICKER_HTML_SNIPPET = ` + Enter a date range + + + + + MM/DD/YYYY – MM/DD/YYYY + + + @if(range.controls.start.hasError('matStartDateInvalid')) { + Invalid start date + } @if(range.controls.end.hasError('matEndDateInvalid')) { + Invalid end date + } + +
+

+ Selected range: {{ range.value | json }} +

+
+`; + +export const ACTION_BUTTONS_DATEPICKER_HTML_SNIPPET = ` + Choose a date + + MM/DD/YYYY + + + + + + + + + + + Enter a date range + + + + + MM/DD/YYYY – MM/DD/YYYY + + + + + + + + +`; + +export const DATE_RANGE_PICKER_DATEPICKER_HTML_SNIPPET = ` + First campaign + + + + + MM/DD/YYYY – MM/DD/YYYY + + + + + + Second campaign + + + + + + MM/DD/YYYY – MM/DD/YYYY + + +`; + +export const OPEN_METHOD_DATEPICKER_HTML_SNIPPET = ` + Choose a date + + MM/DD/YYYY + + + +`; + +export const CUSTOM_ICON_DATEPICKER_HTML_SNIPPET = ` + Choose a date + + MM/DD/YYYY + + keyboard_arrow_down + + + +`; + +export const CUSTOM_DATE_CLASSES_DATEPICKER_HTML_SNIPPET = ` + Choose a date + + MM/DD/YYYY + + + +`; + +export const PALLETE_COLORS_DATEPICKER_HTML_SNIPPET = ` + Inherited calendar color + + MM/DD/YYYY + + + + + + Custom calendar color + + MM/DD/YYYY + + + +`; + +export const CHANGE_EVENTS_DATEPICKER_HTML_SNIPPET = ` + Input & change events + + MM/DD/YYYY + + + + +
+

Logs:

+ @for(e of events; track e) { +
{{ e }}
+ } +
+`; + +export const DISABLED_DATEPICKER_HTML_SNIPPET = `

+ + Completely disabled + + MM/DD/YYYY + + + +

+ +

+ + Popup disabled + + MM/DD/YYYY + + + +

+ +

+ + Input disabled + + MM/DD/YYYY + + + +

+`; + +export const INLINE_DATEPICKER_HTML_SNIPPET = ` + + +

+ Selected date: {{ selected }} +

+`; + +export const START_DATE_DATEPICKER_HTML_SNIPPET = ` + Choose a date + + MM/DD/YYYY + + + +`; + +export const TOUCH_UI_DATEPICKER_HTML_SNIPPET = ` + Choose a date + + MM/DD/YYYY + + + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/datepicker/code/datepicker-ts-snippet.ts b/theme/packages/main/src/app/pages/forms/form-elements/datepicker/code/datepicker-ts-snippet.ts new file mode 100644 index 0000000..a898981 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/datepicker/code/datepicker-ts-snippet.ts @@ -0,0 +1,272 @@ +export const BASIC_DATEPICKER_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component} from '@angular/core'; + import {MatDatepickerModule} from '@angular/material/datepicker'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + import {provideNativeDateAdapter} from '@angular/material/core'; + + /** + * @title Basic datepicker */ + */ + @Component({ + selector: 'app-datepicker', + imports: [MatFormFieldModule, MatInputModule, MatDatepickerModule], + templateUrl: './datepicker.component.html', + styleUrls: ['datepicker.component.scss'], + }) + export class AppDatepickerComponent { + constructor() {} + } +`; + +export const CUSTOM_SELECTIONS_DATEPICKER_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component, Injectable, inject} from '@angular/core'; + import {DateAdapter, provideNativeDateAdapter} from '@angular/material/core'; + import { + DateRange, + MAT_DATE_RANGE_SELECTION_STRATEGY, + MatDateRangeSelectionStrategy, + MatDatepickerModule, + } from '@angular/material/datepicker'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + @Injectable() + export class FiveDayRangeSelectionStrategy + implements MatDateRangeSelectionStrategy { + constructor(private _dateAdapter: DateAdapter) { } + + selectionFinished(date: D | null): DateRange { + return this._createFiveDayRange(date); + } + + createPreview(activeDate: D | null): DateRange { + return this._createFiveDayRange(activeDate); + } + + private _createFiveDayRange(date: D | null): DateRange { + if (date) { + const start = this._dateAdapter.addCalendarDays(date, -2); + const end = this._dateAdapter.addCalendarDays(date, 2); + return new DateRange(start, end); + } + + return new DateRange(null, null); + } + } + + /** + * @title Date range picker with a custom selection strategy */ + */ + @Component({ + selector: 'app-datepicker', + imports: [MatFormFieldModule, MatInputModule, MatDatepickerModule], + templateUrl: './datepicker.component.html', + styleUrls: ['datepicker.component.scss'], + providers: [ + { + provide: MAT_DATE_RANGE_SELECTION_STRATEGY, + useClass: FiveDayRangeSelectionStrategy, + }, + provideNativeDateAdapter(), + ], + imports: [MatFormFieldModule, MatDatepickerModule], + changeDetection: ChangeDetectionStrategy.OnPush, + }) + export class AppDatepickerComponent { + constructor() {} + } +`; + +export const FORM_INTEGRATION_DATEPICKER_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component} from '@angular/core'; + import {JsonPipe} from '@angular/common'; + import {ChangeDetectionStrategy, Component} from '@angular/core'; + import {FormControl, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {provideNativeDateAdapter} from '@angular/material/core'; + import {MatDatepickerModule} from '@angular/material/datepicker'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + /** + * @title Date range picker forms integration */ + */ + @Component({ + selector: 'app-datepicker', + imports: [MatFormFieldModule, MatDatepickerModule, FormsModule, ReactiveFormsModule, JsonPipe], + templateUrl: './datepicker.component.html', + styleUrls: ['datepicker.component.scss'], + }) + export class AppDatepickerComponent { + constructor() {} + + range = new FormGroup({ + start: new FormControl(null), + end: new FormControl(null), + }); + } +`; + +export const ACTION_BUTTONS_DATEPICKER_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component} from '@angular/core'; + import {MatButtonModule} from '@angular/material/button'; + import {MatDatepickerModule} from '@angular/material/datepicker'; + import {MatInputModule} from '@angular/material/input'; + import {MatIconModule} from '@angular/material/icon'; + import {MatFormFieldModule} from '@angular/material/form-field'; + import {provideNativeDateAdapter} from '@angular/material/core'; + + /** + * @title Datepicker action buttons */ + */ + @Component({ + selector: 'app-datepicker', + imports: [MatFormFieldModule, MatInputModule, MatDatepickerModule, MatButtonModule, MatIconModule], + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [provideNativeDateAdapter()], + templateUrl: './datepicker.component.html', + styleUrls: ['datepicker.component.scss'], + }) + export class AppDatepickerComponent { + constructor() {} + } +`; + +export const DATE_RANGE_PICKER_DATEPICKER_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component} from '@angular/core'; + import {FormControl, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {provideNativeDateAdapter} from '@angular/material/core'; + import {MatDatepickerModule} from '@angular/material/datepicker'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + const today = new Date(); + const month = today.getMonth(); + const year = today.getFullYear(); + + /** + * @title Datepicker action buttons */ + */ + @Component({ + selector: 'app-datepicker', + providers: [provideNativeDateAdapter()], + imports: [MatFormFieldModule, MatDatepickerModule, FormsModule, ReactiveFormsModule], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './datepicker.component.html', + styleUrls: ['datepicker.component.scss'], + }) + export class AppDatepickerComponent { + constructor() {} + + campaignOne = new FormGroup({ + start: new FormControl(new Date(year, month, 13)), + end: new FormControl(new Date(year, month, 16)), + }); + campaignTwo = new FormGroup({ + start: new FormControl(new Date(year, month, 15)), + end: new FormControl(new Date(year, month, 19)), + }); + } +`; + +export const CUSTOM_DATE_CLASSES_DATEPICKER_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/core'; + import {provideNativeDateAdapter} from '@angular/material/core'; + import {MatCalendarCellClassFunction, MatDatepickerModule} from '@angular/material/datepicker'; + import {MatFormFieldModule} from '@angular/material/form-field'; + import {MatInputModule} from '@angular/material/input'; + + /** + * @title Datepicker with custom date classes */ + */ + @Component({ + selector: 'app-datepicker', + encapsulation: ViewEncapsulation.None, + providers: [provideNativeDateAdapter()], + imports: [MatFormFieldModule, MatInputModule, MatDatepickerModule], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './datepicker.component.html', + styleUrls: ['datepicker.component.scss'], + }) + export class AppDatepickerComponent { + constructor() {} + + dateClass: MatCalendarCellClassFunction = (cellDate, view) => { + // Only highligh dates inside the month view. + if (view === 'month') { + const date = cellDate.getDate(); + + // Highlight the 1st and 20th day of each month. + return date === 1 || date === 20 ? 'example-custom-date-class' : ''; + } + + return ''; + }; + } +`; + +export const CHANGE_EVENTS_DATEPICKER_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component, signal} from '@angular/core'; + import {provideNativeDateAdapter} from '@angular/material/core'; + import {MatDatepickerInputEvent, MatDatepickerModule} from '@angular/material/datepicker'; + import {MatFormFieldModule} from '@angular/material/form-field'; + import {MatInputModule} from '@angular/material/input'; + + /** + * @title Datepicker input and change events */ + */ + @Component({ + selector: 'app-datepicker', + providers: [provideNativeDateAdapter()], + imports: [MatFormFieldModule, MatInputModule, MatDatepickerModule], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './datepicker.component.html', + styleUrls: ['datepicker.component.scss'], + }) + export class AppDatepickerComponent { + constructor() {} + + events: string[] = []; + + addEvent(type: string, event: MatDatepickerInputEvent) { + this.events.push('{type}: {event.value}'); + } + } +`; + +export const INLINE_DATEPICKER_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component, model} from '@angular/core'; + import {MatCardModule} from '@angular/material/card'; + import {provideNativeDateAdapter} from '@angular/material/core'; + import {MatDatepickerModule} from '@angular/material/datepicker'; + + /** + * @title Datepicker inline calendar example */ + */ + @Component({ + selector: 'app-datepicker', + providers: [provideNativeDateAdapter()], + imports: [MatCardModule, MatDatepickerModule], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './datepicker.component.html', + styleUrls: ['datepicker.component.scss'], + }) + export class AppDatepickerComponent { + constructor() {} + + selected: Date | null; + } +`; + +export const START_DATE_DATEPICKER_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component} from '@angular/core'; + import {provideNativeDateAdapter} from '@angular/material/core'; + import {MatDatepickerModule} from '@angular/material/datepicker'; + import {MatFormFieldModule} from '@angular/material/form-field'; + import {MatInputModule} from '@angular/material/input'; + + /** + * @title Datepicker start date */ + */ + @Component({ + selector: 'app-datepicker', + providers: [provideNativeDateAdapter()], + imports: [MatFormFieldModule, MatInputModule, MatDatepickerModule], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './datepicker.component.html', + styleUrls: ['datepicker.component.scss'], + }) + export class AppDatepickerComponent { + constructor() {} + + startDate = new Date(1990, 0, 1); + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/datepicker/datepicker.component.html b/theme/packages/main/src/app/pages/forms/form-elements/datepicker/datepicker.component.html new file mode 100644 index 0000000..c901721 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/datepicker/datepicker.component.html @@ -0,0 +1,582 @@ + +
+ Datepicker +
+ +
+
+ + +

+ Basic +

+
+ + Choose a date + + MM/DD/YYYY + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Custom Selection +

+
+ + Enter a date range + + + + + MM/DD/YYYY – MM/DD/YYYY + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Forms integration +

+
+ + Enter a date range + + + + + MM/DD/YYYY – MM/DD/YYYY + + + @if(range.controls.start.hasError('matStartDateInvalid')) { + Invalid start date + } @if(range.controls.end.hasError('matEndDateInvalid')) { + Invalid end date + } + +
+

+ Selected range: {{ range.value | json }} +

+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Action buttons +

+
+ + Choose a date + + MM/DD/YYYY + + + + + + + + + + + Enter a date range + + + + + MM/DD/YYYY – MM/DD/YYYY + + + + + + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Date range picker +

+
+ + First campaign + + + + + MM/DD/YYYY – MM/DD/YYYY + + + + + + Second campaign + + + + + + MM/DD/YYYY – MM/DD/YYYY + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Open Method +

+
+ + Choose a date + + MM/DD/YYYY + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Custom Icon +

+
+ + Choose a date + + MM/DD/YYYY + + keyboard_arrow_down + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Custom Date Classes +

+
+ + Choose a date + + MM/DD/YYYY + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Pallete Colors +

+
+ + Inherited calendar color + + MM/DD/YYYY + + + + + + Custom calendar color + + MM/DD/YYYY + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Change Events +

+
+ + Input & change events + + MM/DD/YYYY + + + + +
+

Logs:

+ @for(e of events; track e) { +
{{ e }}
+ } +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Disabled +

+
+

+ + Completely disabled + + MM/DD/YYYY + + + +

+ +

+ + Popup disabled + + MM/DD/YYYY + + + +

+ +

+ + Input disabled + + MM/DD/YYYY + + + +

+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Inline +

+
+ + + +

+ Selected date: {{ selected }} +

+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Start Date +

+
+ + Choose a date + + MM/DD/YYYY + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Touch Ui +

+
+ + Choose a date + + MM/DD/YYYY + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/datepicker/datepicker.component.scss b/theme/packages/main/src/app/pages/forms/form-elements/datepicker/datepicker.component.scss new file mode 100644 index 0000000..5a776d8 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/datepicker/datepicker.component.scss @@ -0,0 +1,8 @@ +button.example-custom-date-class { + background: orange; + border-radius: 100%; +} + +.demo-inline-calendar-card { + width: 300px; + } \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/datepicker/datepicker.component.ts b/theme/packages/main/src/app/pages/forms/form-elements/datepicker/datepicker.component.ts new file mode 100644 index 0000000..69504f3 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/datepicker/datepicker.component.ts @@ -0,0 +1,186 @@ +import { Component, Injectable, ViewEncapsulation } from '@angular/core'; +import { + FormGroup, + FormControl, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { DateAdapter, provideNativeDateAdapter } from '@angular/material/core'; +import { + MatDateRangeSelectionStrategy, + DateRange, + MAT_DATE_RANGE_SELECTION_STRATEGY, + MatDatepickerModule, +} from '@angular/material/datepicker'; +import { MatCalendarCellClassFunction } from '@angular/material/datepicker'; +import { MatDatepickerInputEvent } from '@angular/material/datepicker'; +import { MaterialModule } from '../../../../material.module'; +import { CommonModule } from '@angular/common'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { ACTION_BUTTONS_DATEPICKER_TS_SNIPPET, BASIC_DATEPICKER_TS_SNIPPET, CHANGE_EVENTS_DATEPICKER_TS_SNIPPET, CUSTOM_DATE_CLASSES_DATEPICKER_TS_SNIPPET, CUSTOM_SELECTIONS_DATEPICKER_TS_SNIPPET, DATE_RANGE_PICKER_DATEPICKER_TS_SNIPPET, FORM_INTEGRATION_DATEPICKER_TS_SNIPPET, INLINE_DATEPICKER_TS_SNIPPET, START_DATE_DATEPICKER_TS_SNIPPET } from './code/datepicker-ts-snippet'; +import { ACTION_BUTTONS_DATEPICKER_HTML_SNIPPET, BASIC_DATEPICKER_HTML_SNIPPET, CHANGE_EVENTS_DATEPICKER_HTML_SNIPPET, CUSTOM_DATE_CLASSES_DATEPICKER_HTML_SNIPPET, CUSTOM_ICON_DATEPICKER_HTML_SNIPPET, CUSTOM_SELECTIONS_DATEPICKER_HTML_SNIPPET, DATE_RANGE_PICKER_DATEPICKER_HTML_SNIPPET, DISABLED_DATEPICKER_HTML_SNIPPET, FORM_INTEGRATION_DATEPICKER_HTML_SNIPPET, INLINE_DATEPICKER_HTML_SNIPPET, OPEN_METHOD_DATEPICKER_HTML_SNIPPET, PALLETE_COLORS_DATEPICKER_HTML_SNIPPET, START_DATE_DATEPICKER_HTML_SNIPPET, TOUCH_UI_DATEPICKER_HTML_SNIPPET } from './code/datepicker-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +const today = new Date(); +const month = today.getMonth(); +const year = today.getFullYear(); + +@Injectable() +export class FiveDayRangeSelectionStrategy + implements MatDateRangeSelectionStrategy { + constructor(private _dateAdapter: DateAdapter) { } + + selectionFinished(date: D | null): DateRange { + return this._createFiveDayRange(date); + } + + createPreview(activeDate: D | null): DateRange { + return this._createFiveDayRange(activeDate); + } + + private _createFiveDayRange(date: D | null): DateRange { + if (date) { + const start = this._dateAdapter.addCalendarDays(date, -2); + const end = this._dateAdapter.addCalendarDays(date, 2); + return new DateRange(start, end); + } + + return new DateRange(null, null); + } +} + +@Component({ + selector: 'app-datepicker', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + CommonModule, + MatFormFieldModule, + MatDatepickerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './datepicker.component.html', + styleUrls: ['datepicker.component.scss'], + encapsulation: ViewEncapsulation.None, + providers: [ + provideNativeDateAdapter(), + { + provide: MAT_DATE_RANGE_SELECTION_STRATEGY, + useClass: FiveDayRangeSelectionStrategy, + }, + ] +}) +export class AppDatepickerComponent { + + // 1 [Basic with Datepicker] + codeForBasicDatepicker = BASIC_DATEPICKER_HTML_SNIPPET; + codeForBasicDatepickerTs = BASIC_DATEPICKER_TS_SNIPPET; + + // 2 [Custom Selection with Datepicker] + codeForCustomSelectionDatepicker = CUSTOM_SELECTIONS_DATEPICKER_HTML_SNIPPET; + codeForCustomSelectionDatepickerTs = CUSTOM_SELECTIONS_DATEPICKER_TS_SNIPPET; + + // 3 [Forms integration with Datepicker] + codeForFormsIntegrationDatepicker = FORM_INTEGRATION_DATEPICKER_HTML_SNIPPET; + codeForFormsIntegrationDatepickerTs = FORM_INTEGRATION_DATEPICKER_TS_SNIPPET; + + // 4 [Action buttons with Datepicker] + codeForActionButtonsDatepicker = ACTION_BUTTONS_DATEPICKER_HTML_SNIPPET; + codeForActionButtonsDatepickerTs = ACTION_BUTTONS_DATEPICKER_TS_SNIPPET; + + // 5 [Date range picker with Datepicker] + codeForDateRangePickerDatepicker = DATE_RANGE_PICKER_DATEPICKER_HTML_SNIPPET; + codeForDateRangePickerDatepickerTs = DATE_RANGE_PICKER_DATEPICKER_TS_SNIPPET; + + // 6 [Open Method with Datepicker] + codeForOpenMethodDatepicker = OPEN_METHOD_DATEPICKER_HTML_SNIPPET; + codeForOpenMethodDatepickerTs = ACTION_BUTTONS_DATEPICKER_TS_SNIPPET; + + // 7 [Custom Icon with Datepicker] + codeForCustomIconDatepicker = CUSTOM_ICON_DATEPICKER_HTML_SNIPPET; + codeForCustomIconDatepickerTs = ACTION_BUTTONS_DATEPICKER_TS_SNIPPET; + + // 8 [Custom Date Classes with Datepicker] + codeForCustomDateClassesDatepicker = CUSTOM_DATE_CLASSES_DATEPICKER_HTML_SNIPPET; + codeForCustomDateClassesDatepickerTs = CUSTOM_DATE_CLASSES_DATEPICKER_TS_SNIPPET; + + // 9 [Pallete Colors with Datepicker] + codeForPalleteColorsDatepicker = PALLETE_COLORS_DATEPICKER_HTML_SNIPPET; + codeForPalleteColorsDatepickerTs = ACTION_BUTTONS_DATEPICKER_TS_SNIPPET; + + // 10 [Change Events with Datepicker] + codeForChangeEventsDatepicker = CHANGE_EVENTS_DATEPICKER_HTML_SNIPPET; + codeForChangeEventsDatepickerTs = CHANGE_EVENTS_DATEPICKER_TS_SNIPPET; + + // 11 [Disabled with Datepicker] + codeForDisabledDatepicker = DISABLED_DATEPICKER_HTML_SNIPPET; + codeForDisabledDatepickerTs = BASIC_DATEPICKER_TS_SNIPPET; + + // 12 [Inline with Datepicker] + codeForInlineDatepicker = INLINE_DATEPICKER_HTML_SNIPPET; + codeForInlineDatepickerTs = INLINE_DATEPICKER_TS_SNIPPET; + + // 13 [Start Date with Datepicker] + codeForStartDateDatepicker = START_DATE_DATEPICKER_HTML_SNIPPET; + codeForStartDateDatepickerTs = START_DATE_DATEPICKER_TS_SNIPPET; + + // 14 [touch UI with Datepicker] + codeForTouchUIDatepicker = TOUCH_UI_DATEPICKER_HTML_SNIPPET; + codeForTouchUIDatepickerTs = ACTION_BUTTONS_DATEPICKER_TS_SNIPPET; + + + // inline + selected: Date | null; + + // start date + startDate = new Date(1990, 0, 1); + + // date range picker + campaignOne = new FormGroup({ + start: new FormControl(new Date(year, month, 13)), + end: new FormControl(new Date(year, month, 16)), + }); + campaignTwo = new FormGroup({ + start: new FormControl(new Date(year, month, 15)), + end: new FormControl(new Date(year, month, 19)), + }); + + // form integration + + range = new FormGroup({ + start: new FormControl(null), + end: new FormControl(null), + }); + + // custom date classes + dateClass: MatCalendarCellClassFunction = (cellDate, view) => { + // Only highligh dates inside the month view. + if (view === 'month') { + const date = cellDate.getDate(); + + // Highlight the 1st and 20th day of each month. + return date === 1 || date === 20 ? 'example-custom-date-class' : ''; + } + + return ''; + }; + + // change events + events: string[] = []; + + addEvent(type: string, event: MatDatepickerInputEvent) { + this.events.push(`${type}: ${event.value}`); + } + + constructor() { } +} diff --git a/theme/packages/main/src/app/pages/forms/form-elements/index.ts b/theme/packages/main/src/app/pages/forms/form-elements/index.ts new file mode 100644 index 0000000..0de3dad --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/index.ts @@ -0,0 +1,5 @@ +export * from './autocomplete/autocomplete.component'; +export * from './button/button.component'; +export * from './checkbox/checkbox.component'; +export * from './radio/radio.component'; +export * from './datepicker/datepicker.component'; diff --git a/theme/packages/main/src/app/pages/forms/form-elements/radio/code/radio-html-snippet.ts b/theme/packages/main/src/app/pages/forms/form-elements/radio/code/radio-html-snippet.ts new file mode 100644 index 0000000..d3d087b --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/radio/code/radio-html-snippet.ts @@ -0,0 +1,21 @@ +export const BASIC_RADIO_HTML_SNIPPET = ` + Option 1 + Option 2 + +`; + +export const NG_NODEL_RADIO_HTML_SNIPPET = ` + + @for(season of seasons; track season) { + + {{ season }} + + } + +
+
+ Your favorite season is: {{ favoriteSeason }} +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/radio/code/radio-ts-snippet.ts b/theme/packages/main/src/app/pages/forms/form-elements/radio/code/radio-ts-snippet.ts new file mode 100644 index 0000000..0a9abfe --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/radio/code/radio-ts-snippet.ts @@ -0,0 +1,35 @@ +export const BASIC_RADIO_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatRadioModule} from '@angular/material/radio'; + + /** + * @title Basic radios + */ + @Component({ + selector: 'app-radio', + imports: [MatRadioModule], + templateUrl: './radio.component.html' + }) + export class AppRadioComponent { + constructor() {} + } +`; + +export const NG_NODEL_RADIO_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {FormsModule} from '@angular/forms'; + import {MatRadioModule} from '@angular/material/radio'; + + /** + * @title Radios with ngModel + */ + @Component({ + selector: 'app-radio', + imports: [MatRadioModule, FormsModule], + templateUrl: './radio.component.html' + }) + export class AppRadioComponent { + constructor() {} + + favoriteSeason: string; + seasons: string[] = ['Winter', 'Spring', 'Summer', 'Autumn']; + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/radio/radio.component.html b/theme/packages/main/src/app/pages/forms/form-elements/radio/radio.component.html new file mode 100644 index 0000000..f4491f7 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/radio/radio.component.html @@ -0,0 +1,73 @@ + +
+ Radio +
+ + + +

+ Basic +

+
+ + Option 1 + Option 2 + +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ ngModel +

+
+ + + @for(season of seasons; track season) { + + {{ season }} + + } + +
+
+ Your favorite season is: {{ favoriteSeason }} +
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-elements/radio/radio.component.ts b/theme/packages/main/src/app/pages/forms/form-elements/radio/radio.component.ts new file mode 100644 index 0000000..b7ab7f2 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-elements/radio/radio.component.ts @@ -0,0 +1,37 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../../material.module'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_RADIO_TS_SNIPPET, NG_NODEL_RADIO_TS_SNIPPET } from './code/radio-ts-snippet'; +import { BASIC_RADIO_HTML_SNIPPET, NG_NODEL_RADIO_HTML_SNIPPET } from './code/radio-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-radio', + imports: [MaterialModule, FormsModule, ReactiveFormsModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './radio.component.html' +}) +export class AppRadioComponent { + constructor() {} + + // 1 [Basic with Radio] + codeForBasicRadio = BASIC_RADIO_HTML_SNIPPET; + codeForBasicRadioTs = BASIC_RADIO_TS_SNIPPET; + + // 2 [ngModel with Radio] + codeForngModelRadio = NG_NODEL_RADIO_HTML_SNIPPET; + codeForngModelRadioTs = NG_NODEL_RADIO_TS_SNIPPET; + + // ngModel + favoriteSeason: string; + seasons: string[] = ['Winter', 'Spring', 'Summer', 'Autumn']; +} diff --git a/theme/packages/main/src/app/pages/forms/form-horizontal/code/form-horizontal-html-snippet.ts b/theme/packages/main/src/app/pages/forms/form-horizontal/code/form-horizontal-html-snippet.ts new file mode 100644 index 0000000..09b74ce --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-horizontal/code/form-horizontal-html-snippet.ts @@ -0,0 +1,971 @@ +export const BASIC_LAYOUT_HTML_SNIPPET = `
+
+
+ Name +
+
+ + + +
+
+
+
+ Company +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Phone No +
+
+ + + +
+
+
+
+ Message + +
+
+ + + +
+
+
+
+ +
+
+
+`; + +export const BASIC_WITH_ICONS_HTML_SNIPPET = `
+
+
+ Name +
+
+ + + + + + +
+
+
+
+ Company +
+
+ + + + + + +
+
+
+
+ Email +
+
+ + + + + + +
+
+
+
+ Phone No +
+
+ + + + + + +
+
+
+
+ Message + +
+
+ + + + + + +
+
+
+
+ +
+
+
+`; + +export const FORM_SEPARATOR_HTML_SNIPPET = ` + +

Account Details

+ +
+
+ Username + +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+ +

Personal Info

+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + Africa + United Kingdom + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+ + +
+
+
+
+`; + +export const FORM_LABEL_ALIGN_HTML_SNIPPET = ` + +

Account Details

+ +
+
+ Username + +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+ +

Personal Info

+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + Africa + United Kingdom + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+ + +
+
+
+
+`; + +export const COLLAPSE_FORM_HTML_SNIPPET = ` + + + Delivery Address + + + +
+
+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Address + +
+
+ + + +
+
+
+
+ City + +
+
+ + + +
+
+
+
+ Address Type + +
+
+ + Home (All day delivery) + Office (Delivery between 10 AM - 5 PM) + +
+
+
+
+
+
+ Phone + +
+
+ + + +
+
+
+
+ Pincode + +
+
+ + + +
+
+
+
+ Landmark + +
+
+ + + +
+
+
+
+ + + + +
+ + + + Delivery Options + + + + + Standard 3-5 Days + Express + Overnight + + + + + + + + + + + Payment Method + + + + + Credit/Debit/ATM Card + + Cash on Delivery + + +
+
+ + Card Number + + + +
+
+ + Name + + + +
+
+ + Exp. Date + + + +
+
+ + CCV Code + + + + + + +
+
+
+
+ + + + + +
+
+`; + +export const FORM_WITH_TABS_HTML_SNIPPET = ` + + + +
+
+
+
+ First Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + France + Africa + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+
+
+ Last Name + +
+
+ + + +
+
+
+
+ Language + +
+
+ + + English + French + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+
+ + +
+
+
+ + +
+
+
+
+ Username + +
+
+ + + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+
+
+
+ Email + +
+
+ + + @exmaple.com + +
+
+
+
+ Confirm + +
+
+ + + + +
+
+
+
+
+ + +
+
+
+ + +
+
+
+
+ Twitter + +
+
+ + + +
+
+
+
+
+
+ Facebook + +
+
+ + + +
+
+
+
+
+
+ Google + +
+
+ + + +
+
+
+
+
+
+ Linkedin + +
+
+ + + +
+
+
+
+
+
+ Instagram + +
+
+ + + +
+
+
+
+
+
+ Quora + +
+
+ + + +
+
+
+
+
+ + +
+
+
+
+
+`; diff --git a/theme/packages/main/src/app/pages/forms/form-horizontal/code/form-horizontal-ts-snippet.ts b/theme/packages/main/src/app/pages/forms/form-horizontal/code/form-horizontal-ts-snippet.ts new file mode 100644 index 0000000..4505dda --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-horizontal/code/form-horizontal-ts-snippet.ts @@ -0,0 +1,121 @@ +export const BASIC_LAYOUT_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; + +@Component({ + selector: 'app-form-horizontal', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + ], + templateUrl: './form-horizontal.component.html', +}) +export class AppFormHorizontalComponent { + constructor() {} + +} + +`; + +export const BASIC_WITH_ICONS_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-form-horizontal', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + TablerIconsModule + ], + templateUrl: './form-horizontal.component.html', +}) +export class AppFormHorizontalComponent { + constructor() {} + +} + +`; + +export const FORM_SEPARATOR_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { provideNativeDateAdapter } from '@angular/material/core'; + +@Component({ + selector: 'app-form-horizontal', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + TablerIconsModule, + MatDatepickerModule + ], + templateUrl: './form-horizontal.component.html', + providers: [provideNativeDateAdapter()], +}) +export class AppFormHorizontalComponent { + constructor() {} + +} + +`; + +export const COLLAPSE_FORM_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { provideNativeDateAdapter } from '@angular/material/core'; + +@Component({ + selector: 'app-form-horizontal', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + TablerIconsModule, + MatDatepickerModule + ], + templateUrl: './form-horizontal.component.html', + providers: [provideNativeDateAdapter()], +}) +export class AppFormHorizontalComponent { + constructor() {} + + step = 0; + + setStep(index: number) { + this.step = index; + } + + nextStep() { + this.step++; + } + + prevStep() { + this.step--; + } + + panelOpenState = false; + +} + +`; diff --git a/theme/packages/main/src/app/pages/forms/form-horizontal/form-horizontal.component.html b/theme/packages/main/src/app/pages/forms/form-horizontal/form-horizontal.component.html new file mode 100644 index 0000000..9ce7cc9 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-horizontal/form-horizontal.component.html @@ -0,0 +1,1108 @@ +
+
+ + + + + +

Basic Layout

+
+
+
+
+ Name +
+
+ + + +
+
+
+
+ Company +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Phone No +
+
+ + + +
+
+
+
+ Message + +
+
+ + + +
+
+
+
+ +
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
+ + + + + +

Basic with Icons

+
+
+
+
+ Name +
+
+ + + + + + +
+
+
+
+ Company +
+
+ + + + + + +
+
+
+
+ Email +
+
+ + + + + + +
+
+
+
+ Phone No +
+
+ + + + + + +
+
+
+
+ Message + +
+
+ + + + + + +
+
+
+
+ +
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
+ + + + + +

Form Separator

+
+ + +

Account Details

+ +
+
+ Username + +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+ +

Personal Info

+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + Africa + United Kingdom + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+ + +
+
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
+ + + + + +

Form Label Alignment

+
+ + +

Account Details

+ +
+
+ Username + +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+ +

Personal Info

+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + Africa + United Kingdom + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+ + +
+
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
+ +

Collapsible Section

+ + + + + +
+ + + + Delivery Address + + + +
+
+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Address + +
+
+ + + +
+
+
+
+ City + +
+
+ + + +
+
+
+
+ Address Type + +
+
+ + Home (All day delivery) + Office (Delivery between 10 AM - 5 PM) + +
+
+
+
+
+
+ Phone + +
+
+ + + +
+
+
+
+ Pincode + +
+
+ + + +
+
+
+
+ Landmark + +
+
+ + + +
+
+
+
+ + + + +
+ + + + Delivery Options + + + + + Standard 3-5 Days + Express + Overnight + + + + + + + + + + + Payment Method + + + + + Credit/Debit/ATM Card + + Cash on Delivery + + +
+
+ + Card Number + + + +
+
+ + Name + + + +
+
+ + Exp. Date + + + +
+
+ + CCV Code + + + + + + +
+
+
+
+ + + + + +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ +

Form with Tabs

+ + + + + + +
+ + + + +
+
+
+
+ First Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + France + Africa + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+
+
+ Last Name + +
+
+ + + +
+
+
+
+ Language + +
+
+ + + English + French + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+
+ + +
+
+
+ + +
+
+
+
+ Username + +
+
+ + + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+
+
+
+ Email + +
+
+ + + @exmaple.com + +
+
+
+
+ Confirm + +
+
+ + + + +
+
+
+
+
+ + +
+
+
+ + +
+
+
+
+ Twitter + +
+
+ + + +
+
+
+
+
+
+ Facebook + +
+
+ + + +
+
+
+
+
+
+ Google + +
+
+ + + +
+
+
+
+
+
+ Linkedin + +
+
+ + + +
+
+
+
+
+
+ Instagram + +
+
+ + + +
+
+
+
+
+
+ Quora + +
+
+ + + +
+
+
+
+
+ + +
+
+
+
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
diff --git a/theme/packages/main/src/app/pages/forms/form-horizontal/form-horizontal.component.ts b/theme/packages/main/src/app/pages/forms/form-horizontal/form-horizontal.component.ts new file mode 100644 index 0000000..450f6e1 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-horizontal/form-horizontal.component.ts @@ -0,0 +1,94 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { provideNativeDateAdapter } from '@angular/material/core'; +import { MatIconModule } from '@angular/material/icon'; + +// snippets +import { + BASIC_LAYOUT_TS_SNIPPET, + BASIC_WITH_ICONS_TS_SNIPPET, + FORM_SEPARATOR_TS_SNIPPET, + COLLAPSE_FORM_TS_SNIPPET, +} from './code/form-horizontal-ts-snippet'; +import { + BASIC_LAYOUT_HTML_SNIPPET, + BASIC_WITH_ICONS_HTML_SNIPPET, + FORM_SEPARATOR_HTML_SNIPPET, + FORM_LABEL_ALIGN_HTML_SNIPPET, + COLLAPSE_FORM_HTML_SNIPPET, + FORM_WITH_TABS_HTML_SNIPPET, +} from './code/form-horizontal-html-snippet'; +import { AppCodeViewComponent } from '../../../components/code-view/code-view.component'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-form-horizontal', + imports: [ + MaterialModule, + TablerIconsModule, + MatFormFieldModule, + MatInputModule, + MatDatepickerModule, + MatIconModule, + AppCodeViewComponent, + Highlight, + HighlightAuto, + HighlightLineNumbers, + ], + providers: [provideNativeDateAdapter()], + templateUrl: './form-horizontal.component.html', +}) +export class AppFormHorizontalComponent { + constructor() {} + hide = true; + hide2 = true; + conhide = true; + alignhide = true; + + // 3 accordian + step = 0; + + setStep(index: number) { + this.step = index; + } + + nextStep() { + this.step++; + } + + prevStep() { + this.step--; + } + + panelOpenState = false; + + // 1 [basic layout] + codeForBasicLayout = BASIC_LAYOUT_HTML_SNIPPET; + codeForBasicLayoutTs = BASIC_LAYOUT_TS_SNIPPET; + + // 2 [basic with icons] + codeForBasicwithIcons = BASIC_WITH_ICONS_HTML_SNIPPET; + codeForBasicwithIconsTs = BASIC_WITH_ICONS_TS_SNIPPET; + + // 3 [ form separator] + codeForFormSeparator = FORM_SEPARATOR_HTML_SNIPPET; + codeForFormSeparatorTs = FORM_SEPARATOR_TS_SNIPPET; + + // 4 [ form label align] + codeForFormLabelAlign = FORM_LABEL_ALIGN_HTML_SNIPPET; + codeForFormLabelAlignTs = FORM_SEPARATOR_TS_SNIPPET; + + // 5 [ form collpase] + codeForCollpaseForm = COLLAPSE_FORM_HTML_SNIPPET; + codeForCollpaseFormTs = COLLAPSE_FORM_TS_SNIPPET; + + // 6 [ form with tabs] + codeForFormwithTabs = FORM_WITH_TABS_HTML_SNIPPET; + codeForFormwithTabsTs = COLLAPSE_FORM_TS_SNIPPET; +} diff --git a/theme/packages/main/src/app/pages/forms/form-layouts/code/form-layout-html-snippet.ts b/theme/packages/main/src/app/pages/forms/form-layouts/code/form-layout-html-snippet.ts new file mode 100644 index 0000000..27a78c7 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-layouts/code/form-layout-html-snippet.ts @@ -0,0 +1,336 @@ +export const ORDINARY_FORM_HTML_SNIPPET = `
+ + Email + + + We'll never share your email with anyone else. + + + Password + + + + + Check Me Out! +
+ +
+
+`; + +export const INPUT_VARIANTS_HTML_SNIPPET = `
+ Error + + + + @if (email.invalid) { + {{ errorMessage() }} + } + +
+`; + +export const DEFAULT_FORM_HTML_SNIPPET = `
+ + Default Text + + + + + + Email + + + + + + Password + + + + + + Textarea + + + + +
+ +
+ Check this custom checkbox + Check this custom checkbox + Check this custom checkbox +
+ +
+ + Toggle this custom radio + Toggle this custom radio + Toggle this custom radio + +
+
+ Select + + + @for(option of foods; track option.value) { + {{ option.viewValue }} + } + + + +
+ +
+
+`; + +export const BASIC_HEADER_HTML_SNIPPET = `
+
+ Person Info +
+
+ +
+
+ + First Name + + + + + + Select Gender + + + Male + Female + Other + + + + + Membership + + Free + Paid + +
+
+ + Last Name + + + + + + Date of Birth + + + + + +
+
+ +
+
+ Address +
+
+ +
+
+ + Street + + + +
+ +
+ + City + + + +
+ +
+ + State + + + +
+ +
+ + Post Code + + + +
+ +
+ + Country + + + India + United Kingdom + Africa + + +
+
+ + + +`; + +export const DISABLED_FORM_HTML_SNIPPET = `
+ + Name + + + + + Email + + + + + Password + + + + +
+`; + +export const LEFT_ICON_HTML_SNIPPET = `
+ + Username + + + + + + + + + Email + + + + + + + + + Password + + + + + + + + + Confirm Password + + + + + + + + Remember Me! +
+ + +
+
+`; + +export const RIGHT_ICON_HTML_SNIPPET = `
+ + Username + + + + + + + + + Email + + + + + + + + + Password + + + + + + + + + Confirm Password + + + + + + + + Remember Me! + +
+ + +
+
+`; diff --git a/theme/packages/main/src/app/pages/forms/form-layouts/code/form-layout-ts-snippet.ts b/theme/packages/main/src/app/pages/forms/form-layouts/code/form-layout-ts-snippet.ts new file mode 100644 index 0000000..b947b9a --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-layouts/code/form-layout-ts-snippet.ts @@ -0,0 +1,209 @@ +export const ORDINARY_FORM_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; + + +@Component({ + selector: 'app-form-layouts', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + ], + templateUrl: './form-layouts.component.html', +}) +export class AppFormLayoutsComponent { + constructor() {} + +} + +`; + +export const INPUT_VARIANTS_TS_SNIPPET = ` import {ChangeDetectionStrategy, Component, signal} from '@angular/core'; +import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; +import {FormControl, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {MatInputModule} from '@angular/material/input'; +import {merge} from 'rxjs'; + +/** @title Form field with error messages */ +@Component({ + selector: 'form-layout', + templateUrl: 'form-layout.html', + styleUrl: 'form-layout.css', + imports: [MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppFormLayoutComponent { + readonly email = new FormControl('', [Validators.required, Validators.email]); + + errorMessage = signal(''); + + constructor() { + merge(this.email.statusChanges, this.email.valueChanges) + .pipe(takeUntilDestroyed()) + .subscribe(() => this.updateErrorMessage()); + } + + updateErrorMessage() { + if (this.email.hasError('required')) { + this.errorMessage.set('You must enter a value'); + } else if (this.email.hasError('email')) { + this.errorMessage.set('Not a valid email'); + } else { + this.errorMessage.set(''); + } + } +} + +`; + +export const DEFAULT_FORM_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatCheckboxModule } from '@angular/material/checkbox'; + + +@Component({ + selector: 'app-form-layouts', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + MatRadioModule + ], + templateUrl: './form-layouts.component.html', +}) +export class AppFormLayoutsComponent { + constructor() {} + + foods: Food[] = [ + { value: 'steak-0', viewValue: 'One' }, + { value: 'pizza-1', viewValue: 'Two' }, + { value: 'tacos-2', viewValue: 'Three' }, + { value: 'tacos-3', viewValue: 'Four' }, + ]; + + selectedFood = this.foods[2].value; + +} + +`; + +export const BASIC_HEADER_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { provideNativeDateAdapter } from '@angular/material/core'; + + +@Component({ + selector: 'app-form-layouts', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + MatRadioModule, MatDatepickerModule + ], + templateUrl: './form-layouts.component.html', + providers: [provideNativeDateAdapter()], +}) +export class AppFormLayoutsComponent { + constructor() {} + + foods: Food[] = [ + { value: 'steak-0', viewValue: 'One' }, + { value: 'pizza-1', viewValue: 'Two' }, + { value: 'tacos-2', viewValue: 'Three' }, + { value: 'tacos-3', viewValue: 'Four' }, + ]; + + selectedFood = this.foods[2].value; + +} + +`; + +export const DISABLED_FORM_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; + + +@Component({ + selector: 'app-form-layouts', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + ], + templateUrl: './form-layouts.component.html', +}) +export class AppFormLayoutsComponent { + constructor() {} + +} + +`; + +export const LEFT_ICON_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-form-layouts', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + TablerIconsModule + ], + templateUrl: './form-layouts.component.html', +}) +export class AppFormLayoutsComponent { + constructor() {} + +} + +`; + +export const RIGHT_ICON_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-form-layouts', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + TablerIconsModule + ], + templateUrl: './form-layouts.component.html', +}) +export class AppFormLayoutsComponent { + constructor() {} + +} + +`; diff --git a/theme/packages/main/src/app/pages/forms/form-layouts/form-layouts.component.html b/theme/packages/main/src/app/pages/forms/form-layouts/form-layouts.component.html new file mode 100644 index 0000000..6676cfe --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-layouts/form-layouts.component.html @@ -0,0 +1,500 @@ + + + + + +

Ordrinary Form

+
+
+ + Email + + + We'll never share your email with anyone else. + + + Password + + + + + Check Me Out! +
+ +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ + + + + + +

Input Variants

+
+ Error + + + + @if (email.invalid) { + {{ errorMessage() }} + } + +
+ + +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ + + + + + +

Default Form

+
+
+ + Default Text + + + + + + Email + + + + + + Password + + + + + + Textarea + + + + +
+ +
+ Check this custom checkbox + Check this custom checkbox + Check this custom checkbox +
+ +
+ + Toggle this custom radio + Toggle this custom radio + Toggle this custom radio + +
+
+ Select + + + @for(option of foods; track option.value) { + {{ option.viewValue }} + } + + + +
+ +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ + + + + + +

Basic Header Form

+
+
+
+ Person Info +
+
+ +
+
+ + First Name + + + + + + Select Gender + + + Male + Female + Other + + + + + Membership + + Free + Paid + +
+
+ + Last Name + + + + + + Date of Birth + + + + + +
+
+ +
+
+ Address +
+
+ +
+
+ + Street + + + +
+ +
+ + City + + + +
+ +
+ + State + + + +
+ +
+ + Post Code + + + +
+ +
+ + Country + + + India + United Kingdom + Africa + + +
+
+ + + +
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ + + + + + +

Disabled Form

+
+
+ + Name + + + + + Email + + + + + Password + + + + +
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ +
+
+ + + + + +

Form with Left Icon

+
+
+ + Username + + + + + + + + + Email + + + + + + + + + Password + + + + + + + + + Confirm Password + + + + + + + + Remember Me! +
+ + +
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
+ + + + + +

Form with Right Icon

+
+
+ + Username + + + + + + + + + Email + + + + + + + + + Password + + + + + + + + + Confirm Password + + + + + + + + Remember Me! + +
+ + +
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/forms/form-layouts/form-layouts.component.ts b/theme/packages/main/src/app/pages/forms/form-layouts/form-layouts.component.ts new file mode 100644 index 0000000..82e7783 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-layouts/form-layouts.component.ts @@ -0,0 +1,126 @@ +import { Component, signal } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { + FormControl, + FormsModule, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { provideNativeDateAdapter } from '@angular/material/core'; +import { AppCodeViewComponent } from '../../../components/code-view/code-view.component'; + +// snippets +import { + ORDINARY_FORM_TS_SNIPPET, + INPUT_VARIANTS_TS_SNIPPET, + DEFAULT_FORM_TS_SNIPPET, + BASIC_HEADER_TS_SNIPPET, + DISABLED_FORM_TS_SNIPPET, + LEFT_ICON_TS_SNIPPET, + RIGHT_ICON_TS_SNIPPET, +} from './code/form-layout-ts-snippet'; +import { + ORDINARY_FORM_HTML_SNIPPET, + INPUT_VARIANTS_HTML_SNIPPET, + DEFAULT_FORM_HTML_SNIPPET, + BASIC_HEADER_HTML_SNIPPET, + DISABLED_FORM_HTML_SNIPPET, + LEFT_ICON_HTML_SNIPPET, + RIGHT_ICON_HTML_SNIPPET, +} from './code/form-layout-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +import { merge } from 'rxjs'; + +interface Food { + value: string; + viewValue: string; +} + +@Component({ + selector: 'app-form-layouts', + imports: [ + MaterialModule, + TablerIconsModule, + MatFormFieldModule, + MatInputModule, + MatRadioModule, + MatCheckboxModule, + MatDatepickerModule, + AppCodeViewComponent, + Highlight, + HighlightAuto, + HighlightLineNumbers, + FormsModule, + ReactiveFormsModule, + ], + templateUrl: './form-layouts.component.html', + providers: [provideNativeDateAdapter()], +}) +export class AppFormLayoutsComponent { + readonly email = new FormControl('', [Validators.required, Validators.email]); + + errorMessage = signal(''); + + constructor() { + merge(this.email.statusChanges, this.email.valueChanges) + .pipe(takeUntilDestroyed()) + .subscribe(() => this.updateErrorMessage()); + } + + foods: Food[] = [ + { value: 'steak-0', viewValue: 'One' }, + { value: 'pizza-1', viewValue: 'Two' }, + { value: 'tacos-2', viewValue: 'Three' }, + { value: 'tacos-3', viewValue: 'Four' }, + ]; + + selectedFood = this.foods[2].value; + + updateErrorMessage() { + if (this.email.hasError('required')) { + this.errorMessage.set('You must enter a value'); + } else if (this.email.hasError('email')) { + this.errorMessage.set('Not a valid email'); + } else { + this.errorMessage.set(''); + } + } + + // 1 [ordinary form] + codeForOrdinary = ORDINARY_FORM_HTML_SNIPPET; + codeForOrdinaryTs = ORDINARY_FORM_TS_SNIPPET; + + // 2 [input variant] + codeForInputVariant = INPUT_VARIANTS_HTML_SNIPPET; + codeForInputVariantTs = INPUT_VARIANTS_TS_SNIPPET; + + // 3 [ default form] + codeForDefaultForm = DEFAULT_FORM_HTML_SNIPPET; + codeForDefaultFormTs = DEFAULT_FORM_TS_SNIPPET; + + // 4 [Basic header form] + codeForBasicHeader = BASIC_HEADER_HTML_SNIPPET; + codeForBasicHeaderTs = BASIC_HEADER_TS_SNIPPET; + + // 5 [ disabled form] + codeForDisabledForm = DISABLED_FORM_HTML_SNIPPET; + codeForDisabledFormTs = DISABLED_FORM_TS_SNIPPET; + + // 6 [ form left icon] + codeForLeftIcon = LEFT_ICON_HTML_SNIPPET; + codeForLeftIconTs = LEFT_ICON_TS_SNIPPET; + + // 6 [ form right icon] + codeForRightIcon = RIGHT_ICON_HTML_SNIPPET; + codeForRightIconTs = RIGHT_ICON_TS_SNIPPET; +} diff --git a/theme/packages/main/src/app/pages/forms/form-toastr/form-toastr.component.html b/theme/packages/main/src/app/pages/forms/form-toastr/form-toastr.component.html new file mode 100644 index 0000000..ceace6c --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-toastr/form-toastr.component.html @@ -0,0 +1,38 @@ +
+
+ + + Toastr Success + This is the simple toastr with success message + + + +
+
+ + + Toastr Danger + This is the simple toastr with Danger message + + + +
+
+ + + Toastr Warning + This is the simple toastr with Warning message + + + +
+
+ + + Toastr Accent + This is the simple toastr with Accent message + + + +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/forms/form-toastr/form-toastr.component.ts b/theme/packages/main/src/app/pages/forms/form-toastr/form-toastr.component.ts new file mode 100644 index 0000000..21df4b3 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-toastr/form-toastr.component.ts @@ -0,0 +1,31 @@ +import { CommonModule } from '@angular/common'; +import { Component, Inject } from '@angular/core'; +import { ToastrService, ToastrModule } from 'ngx-toastr'; +import { MaterialModule } from '../../../material.module'; + + +@Component({ + selector: 'app-form-toastr', + templateUrl: './form-toastr.component.html', + imports: [MaterialModule, CommonModule, ToastrModule], + providers: [ToastrService] +}) +export class AppFormToastrComponent { + constructor(private toastr: ToastrService) {} + + showSuccess() { + this.toastr.success('You are awesome!', 'Success!'); + } + + showError() { + this.toastr.error('This is not good!', 'Oops!'); + } + + showWarning() { + this.toastr.warning('You are being warned.', 'Alert!'); + } + + showInfo() { + this.toastr.info('Just some information for you.'); + } +} diff --git a/theme/packages/main/src/app/pages/forms/form-vertical/code/form-vertical-html-snippet.ts b/theme/packages/main/src/app/pages/forms/form-vertical/code/form-vertical-html-snippet.ts new file mode 100644 index 0000000..1678f4e --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-vertical/code/form-vertical-html-snippet.ts @@ -0,0 +1,937 @@ +export const BASIC_LAYOUT_HTML_SNIPPET = `
+
+
+ Name +
+
+ + + +
+
+
+
+ Company +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Phone No +
+
+ + + +
+
+
+
+ Message + +
+
+ + + +
+
+
+
+ +
+
+
+`; + +export const BASIC_WITH_ICONS_HTML_SNIPPET = `
+
+
+ Name +
+
+ + + + + + +
+
+
+
+ Company +
+
+ + + + + + +
+
+
+
+ Email +
+
+ + + + + + +
+
+
+
+ Phone No +
+
+ + + + + + +
+
+
+
+ Message + +
+
+ + + + + + +
+
+
+
+ +
+
+
+`; + +export const FORM_SEPARATOR_HTML_SNIPPET = ` + +

Account Details

+ +
+
+ Username + +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+ +

Personal Info

+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + Africa + United Kingdom + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+ + +
+
+
+
+`; + +export const FORM_LABEL_ALIGN_HTML_SNIPPET = ` + +

Account Details

+ +
+
+ Username + +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+ +

Personal Info

+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + Africa + United Kingdom + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+ + +
+
+
+
+`; + +export const COLLAPSE_FORM_HTML_SNIPPET = ` + + + Delivery Address + + + +
+
+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Address + +
+
+ + + +
+
+
+
+ City + +
+
+ + + +
+
+
+
+ Address Type + +
+
+ + Home (All day delivery) + Office (Delivery between 10 AM - 5 PM) + +
+
+
+
+
+
+ Phone + +
+
+ + + +
+
+
+
+ Pincode + +
+
+ + + +
+
+
+
+ Landmark + +
+
+ + + +
+
+
+
+ + + + +
+ + + + Delivery Options + + + + + Standard 3-5 Days + Express + Overnight + + + + + + + + + + + Payment Method + + + + + Credit/Debit/ATM Card + + Cash on Delivery + + +
+
+ + Card Number + + + +
+
+ + Name + + + +
+
+ + Exp. Date + + + +
+
+ + CCV Code + + + + + + +
+
+
+
+ + + + + +
+
+`; + +export const FORM_WITH_TABS_HTML_SNIPPET = ` + + +
+
+
+
+ First Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + France + Africa + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+
+
+ Last Name + +
+
+ + + +
+
+
+
+ Language + +
+
+ + + English + French + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+
+ + +
+
+
+ + +
+
+
+
+ Username + +
+
+ + + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+
+
+
+ Email + +
+
+ + + @exmaple.com + +
+
+
+
+ Confirm + +
+
+ + + + +
+
+
+
+
+ + +
+
+
+ + +
+
+
+
+ Twitter + +
+
+ + + +
+
+
+
+
+
+ Facebook + +
+
+ + + +
+
+
+
+
+
+ Google + +
+
+ + + +
+
+
+
+
+
+ Linkedin + +
+
+ + + +
+
+
+
+
+
+ Instagram + +
+
+ + + +
+
+
+
+
+
+ Quora + +
+
+ + + +
+
+
+
+
+ + +
+
+
+
+`; diff --git a/theme/packages/main/src/app/pages/forms/form-vertical/code/form-vertical-ts-snippet.ts b/theme/packages/main/src/app/pages/forms/form-vertical/code/form-vertical-ts-snippet.ts new file mode 100644 index 0000000..bb9d9d8 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-vertical/code/form-vertical-ts-snippet.ts @@ -0,0 +1,143 @@ +export const BASIC_LAYOUT_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; + + +@Component({ + selector: 'app-form-vertical', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + ], + templateUrl: './form-vertical.component.html', +}) +export class AppFormVerticalComponent { + constructor() {} + +} + +`; + +export const BASIC_WITH_ICONS_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-form-vertical', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + TablerIconsModule + ], + templateUrl: './form-vertical.component.html', +}) +export class AppFormVerticalComponent { + constructor() {} + +} + +`; + +export const FORM_SEPARATOR_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { provideNativeDateAdapter } from '@angular/material/core'; + +@Component({ + selector: 'app-form-vertical', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + TablerIconsModule, + MatDatepickerModule + ], + templateUrl: './form-vertical.component.html', + providers: [provideNativeDateAdapter()], +}) +export class AppFormVerticalComponent { + constructor() {} + +} + +`; + +export const FORM_LABEL_ALIGN_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { provideNativeDateAdapter } from '@angular/material/core'; + +@Component({ + selector: 'app-form-vertical', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + TablerIconsModule, + MatDatepickerModule + ], + templateUrl: './form-vertical.component.html', + providers: [provideNativeDateAdapter()], +}) +export class AppFormVerticalComponent { + constructor() {} + +} + +`; + +export const COLLAPSE_FORM_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { provideNativeDateAdapter } from '@angular/material/core'; + +@Component({ + selector: 'app-form-horizontal', + imports: [ + MaterialModule, + MatFormFieldModule, + MatInputModule, + MatCheckboxModule, + TablerIconsModule, + MatDatepickerModule + ], + templateUrl: './form-horizontal.component.html', + providers: [provideNativeDateAdapter()], +}) +export class AppFormHorizontalComponent { + constructor() {} + + step = 0; + + setStep(index: number) { + this.step = index; + } + + nextStep() { + this.step++; + } + + prevStep() { + this.step--; + } + + panelOpenState = false; + +} + +`; diff --git a/theme/packages/main/src/app/pages/forms/form-vertical/form-vertical.component.html b/theme/packages/main/src/app/pages/forms/form-vertical/form-vertical.component.html new file mode 100644 index 0000000..fe4b463 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-vertical/form-vertical.component.html @@ -0,0 +1,1101 @@ +
+
+ + + + + +

Basic Layout

+
+
+
+
+ Name +
+
+ + + +
+
+
+
+ Company +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Phone No +
+
+ + + +
+
+
+
+ Message + +
+
+ + + +
+
+
+
+ +
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
+ + + + + +

Basic with Icons

+
+
+
+
+ Name +
+
+ + + + + + +
+
+
+
+ Company +
+
+ + + + + + +
+
+
+
+ Email +
+
+ + + + + + +
+
+
+
+ Phone No +
+
+ + + + + + +
+
+
+
+ Message + +
+
+ + + + + + +
+
+
+
+ +
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+ +
+ + + + + +

Form Separator

+
+ + +

Account Details

+ +
+
+ Username + +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+ +

Personal Info

+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + Africa + United Kingdom + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+ + +
+
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
+ + + + + +

Form Label Alignment

+
+ + +

Account Details

+ +
+
+ Username + +
+
+ + + +
+
+
+
+ Email +
+
+ + + @exmaple.com + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+ +

Personal Info

+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + Africa + United Kingdom + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+ + +
+
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
+ +

Collapsible Section

+ + + + + +
+ + + + Delivery Address + + + +
+
+
+
+ Full Name + +
+
+ + + +
+
+
+
+ Address + +
+
+ + + +
+
+
+
+ City + +
+
+ + + +
+
+
+
+ Address Type + +
+
+ + Home (All day delivery) + Office (Delivery between 10 AM - 5 PM) + +
+
+
+
+
+
+ Phone + +
+
+ + + +
+
+
+
+ Pincode + +
+
+ + + +
+
+
+
+ Landmark + +
+
+ + + +
+
+
+
+ + + + +
+ + + + Delivery Options + + + + + Standard 3-5 Days + Express + Overnight + + + + + + + + + + + Payment Method + + + + + Credit/Debit/ATM Card + + Cash on Delivery + + +
+
+ + Card Number + + + +
+
+ + Name + + + +
+
+ + Exp. Date + + + +
+
+ + CCV Code + + + + + + +
+
+
+
+ + + + + +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ +

Form with Tabs

+ + + + + +
+ + + +
+
+
+
+ First Name + +
+
+ + + +
+
+
+
+ Country + +
+
+ + + + India + France + Africa + + +
+
+
+
+ Birth Date + +
+
+ + + + + +
+
+
+
+
+
+ Last Name + +
+
+ + + +
+
+
+
+ Language + +
+
+ + + English + French + + +
+
+
+
+ Phone no + +
+
+ + + +
+
+
+
+
+ + +
+
+
+ + +
+
+
+
+ Username + +
+
+ + + +
+
+
+
+ Password + +
+
+ + + + +
+
+
+
+
+
+ Email + +
+
+ + + @exmaple.com + +
+
+
+
+ Confirm + +
+
+ + + + +
+
+
+
+
+ + +
+
+
+ + +
+
+
+
+ Twitter + +
+
+ + + +
+
+
+
+
+
+ Facebook + +
+
+ + + +
+
+
+
+
+
+ Google + +
+
+ + + +
+
+
+
+
+
+ Linkedin + +
+
+ + + +
+
+
+
+
+
+ Instagram + +
+
+ + + +
+
+
+
+
+
+ Quora + +
+
+ + + +
+
+
+
+
+ + +
+
+
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
diff --git a/theme/packages/main/src/app/pages/forms/form-vertical/form-vertical.component.ts b/theme/packages/main/src/app/pages/forms/form-vertical/form-vertical.component.ts new file mode 100644 index 0000000..0975342 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-vertical/form-vertical.component.ts @@ -0,0 +1,96 @@ +import { Component } from '@angular/core'; +import { MaterialModule } from '../../../material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatIconModule } from '@angular/material/icon'; +import { provideNativeDateAdapter } from '@angular/material/core'; + +import { AppCodeViewComponent } from '../../../components/code-view/code-view.component'; + +// snippets +import { + BASIC_LAYOUT_TS_SNIPPET, + BASIC_WITH_ICONS_TS_SNIPPET, + FORM_SEPARATOR_TS_SNIPPET, + FORM_LABEL_ALIGN_TS_SNIPPET, + COLLAPSE_FORM_TS_SNIPPET, +} from './code/form-vertical-ts-snippet'; +import { + BASIC_LAYOUT_HTML_SNIPPET, + BASIC_WITH_ICONS_HTML_SNIPPET, + FORM_SEPARATOR_HTML_SNIPPET, + FORM_LABEL_ALIGN_HTML_SNIPPET, + COLLAPSE_FORM_HTML_SNIPPET, + FORM_WITH_TABS_HTML_SNIPPET, +} from './code/form-vertical-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-form-vertical', + imports: [ + MaterialModule, + TablerIconsModule, + MatFormFieldModule, + MatInputModule, + MatDatepickerModule, + MatIconModule, + AppCodeViewComponent, + HighlightLineNumbers, + Highlight, + HighlightAuto, + ], + providers: [provideNativeDateAdapter()], + templateUrl: './form-vertical.component.html', +}) +export class AppFormVerticalComponent { + constructor() {} + hide = true; + hide2 = true; + conhide = true; + alignhide = true; + + // 3 accordian + step = 0; + + setStep(index: number) { + this.step = index; + } + + nextStep() { + this.step++; + } + + prevStep() { + this.step--; + } + + panelOpenState = false; + + // 1 [basic layout] + codeForBasicLayout = BASIC_LAYOUT_HTML_SNIPPET; + codeForBasicLayoutTs = BASIC_LAYOUT_TS_SNIPPET; + + // 2 [basic with icons] + codeForBasicwithIcons = BASIC_WITH_ICONS_HTML_SNIPPET; + codeForBasicwithIconsTs = BASIC_WITH_ICONS_TS_SNIPPET; + + // 3 [ Form Separator ] + codeForFormSeparator = FORM_SEPARATOR_HTML_SNIPPET; + codeForFormSeparatorTs = FORM_SEPARATOR_TS_SNIPPET; + + // 4 [ Form label align ] + codeForFormLabelAlign = FORM_LABEL_ALIGN_HTML_SNIPPET; + codeForFormLabelAlignTs = FORM_LABEL_ALIGN_TS_SNIPPET; + + // 5 [ collpase form ] + codeForCollpaseForm = COLLAPSE_FORM_HTML_SNIPPET; + codeForCollpaseFormTs = COLLAPSE_FORM_TS_SNIPPET; + + // 6 [ form with tabs] + codeForFormwithTabs = FORM_WITH_TABS_HTML_SNIPPET; + codeForFormwithTabsTs = COLLAPSE_FORM_TS_SNIPPET; +} diff --git a/theme/packages/main/src/app/pages/forms/form-wizard/code/form-wizard-html-snippet.ts b/theme/packages/main/src/app/pages/forms/form-wizard/code/form-wizard-html-snippet.ts new file mode 100644 index 0000000..324b58f --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-wizard/code/form-wizard-html-snippet.ts @@ -0,0 +1,209 @@ +export const BASIC_FORM_WIZARD_HTML_SNIPPET = ` + +
+ Account +
+ + Name + + + + + Email + + + + + Password + + + + +
+
+ +
+
+
+ +
+ Profile +
+ + First Name + + + + + + Last Name + + + + + + Address + + + + +
+
+ + +
+
+
+ + Finish +

Terms and condition

+

+ Sard about this site or you have been to it, but you cannot figure out + what it is or what it can do. MTA web directory isSard about this site + or you have been to it, but you cannot figure out what it is or what + it can do. MTA web directory is +

+ Agree with terms? +
+ + +
+
+
+`; + +export const VERTICAL_FORM_WIZARD_HTML_SNIPPET = ` + +
+ Account +
+ + Name + + + + + Email + + + + + Password + + + + +
+
+ +
+
+
+ +
+ Profile +
+ + First Name + + + + + + Last Name + + + + + + Address + + + + +
+
+ + +
+
+
+ + Finish +

Terms and condition

+

+ Sard about this site or you have been to it, but you cannot figure out + what it is or what it can do. MTA web directory isSard about this site + or you have been to it, but you cannot figure out what it is or what + it can do. MTA web directory is +

+ Agree with terms? +
+ + +
+
+
+`; diff --git a/theme/packages/main/src/app/pages/forms/form-wizard/code/form-wizard-ts-snippet.ts b/theme/packages/main/src/app/pages/forms/form-wizard/code/form-wizard-ts-snippet.ts new file mode 100644 index 0000000..bb6c351 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-wizard/code/form-wizard-ts-snippet.ts @@ -0,0 +1,32 @@ +export const BASIC_FORM_WIZARD_TS_SNIPPET = ` import { Component } from '@angular/core'; +import { + FormBuilder, + FormsModule, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; +import { MaterialModule } from '../../../material.module'; + + +@Component({ + selector: 'app-form-wizard', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + ], + templateUrl: './form-wizard.component.html', +}) +export class AppFormWizardComponent { + firstFormGroup = this._formBuilder.group({ + firstCtrl: ['', Validators.required], + }); + secondFormGroup = this._formBuilder.group({ + secondCtrl: ['', Validators.required], + }); + + constructor(private _formBuilder: FormBuilder) {} + +} + +`; diff --git a/theme/packages/main/src/app/pages/forms/form-wizard/form-wizard.component.html b/theme/packages/main/src/app/pages/forms/form-wizard/form-wizard.component.html new file mode 100644 index 0000000..8b89e16 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-wizard/form-wizard.component.html @@ -0,0 +1,257 @@ + + + + + + +

Form Wizard

+
+ + +
+ Account +
+ + Name + + + + + Email + + + + + Password + + + + +
+
+ +
+
+
+ +
+ Profile +
+ + First Name + + + + + + Last Name + + + + + + Address + + + + +
+
+ + +
+
+
+ + Finish +

Terms and condition

+

+ Sard about this site or you have been to it, but you cannot figure out + what it is or what it can do. MTA web directory isSard about this site + or you have been to it, but you cannot figure out what it is or what + it can do. MTA web directory is +

+ Agree with terms? +
+ + +
+
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ + + + + + + +

Vertical

+
+ + +
+ Account +
+ + Name + + + + + Email + + + + + Password + + + + +
+
+ +
+
+
+ +
+ Profile +
+ + First Name + + + + + + Last Name + + + + + + Address + + + + +
+
+ + +
+
+
+ + Finish +

Terms and condition

+

+ Sard about this site or you have been to it, but you cannot figure out + what it is or what it can do. MTA web directory isSard about this site + or you have been to it, but you cannot figure out what it is or what + it can do. MTA web directory is +

+ Agree with terms? +
+ + +
+
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
diff --git a/theme/packages/main/src/app/pages/forms/form-wizard/form-wizard.component.ts b/theme/packages/main/src/app/pages/forms/form-wizard/form-wizard.component.ts new file mode 100644 index 0000000..2d1e383 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/form-wizard/form-wizard.component.ts @@ -0,0 +1,50 @@ +import { Component } from '@angular/core'; +import { + FormBuilder, + FormsModule, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; +import { MaterialModule } from '../../../material.module'; +import { AppCodeViewComponent } from '../../../components/code-view/code-view.component'; +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +// snippets +import { BASIC_FORM_WIZARD_TS_SNIPPET } from './code/form-wizard-ts-snippet'; +import { + BASIC_FORM_WIZARD_HTML_SNIPPET, + VERTICAL_FORM_WIZARD_HTML_SNIPPET, +} from './code/form-wizard-html-snippet'; + +@Component({ + selector: 'app-form-wizard', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + AppCodeViewComponent, + HighlightLineNumbers, + Highlight, + HighlightAuto, + ], + templateUrl: './form-wizard.component.html', +}) +export class AppFormWizardComponent { + firstFormGroup = this._formBuilder.group({ + firstCtrl: ['', Validators.required], + }); + secondFormGroup = this._formBuilder.group({ + secondCtrl: ['', Validators.required], + }); + + constructor(private _formBuilder: FormBuilder) {} + + // 1 [basic form wizard] + codeForFormWizard = BASIC_FORM_WIZARD_HTML_SNIPPET; + codeForFormWizardTs = BASIC_FORM_WIZARD_TS_SNIPPET; + + // 2 [ vertical form wizard] + codeForVerticalFormWizard = VERTICAL_FORM_WIZARD_HTML_SNIPPET; + codeForVerticalFormWizardTs = BASIC_FORM_WIZARD_TS_SNIPPET; +} diff --git a/theme/packages/main/src/app/pages/forms/forms.routes.ts b/theme/packages/main/src/app/pages/forms/forms.routes.ts new file mode 100644 index 0000000..e86dbd6 --- /dev/null +++ b/theme/packages/main/src/app/pages/forms/forms.routes.ts @@ -0,0 +1,152 @@ +import { Routes } from '@angular/router'; + +// Forms +import { + AppAutocompleteComponent, + AppButtonComponent, + AppCheckboxComponent, + AppDatepickerComponent, + AppRadioComponent, +} from './form-elements'; +import { AppFormHorizontalComponent } from './form-horizontal/form-horizontal.component'; +import { AppFormLayoutsComponent } from './form-layouts/form-layouts.component'; +import { AppFormVerticalComponent } from './form-vertical/form-vertical.component'; +import { AppFormWizardComponent } from './form-wizard/form-wizard.component'; +import { AppFormToastrComponent } from './form-toastr/form-toastr.component'; +import { AppFormEditorComponent } from './form-editor/form-editor.component'; + +export const FormsRoutes: Routes = [ + { + path: 'forms-elements', + children: [ + { + path: 'autocomplete', + component: AppAutocompleteComponent, + data: { + title: 'Autocomplete', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Autocomplete' }, + ], + }, + }, + { + path: 'button', + component: AppButtonComponent, + data: { + title: 'Button', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Button' }, + ], + }, + }, + { + path: 'checkbox', + component: AppCheckboxComponent, + data: { + title: 'Checkbox', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Checkbox' }, + ], + }, + }, + + { + path: 'radio', + component: AppRadioComponent, + data: { + title: 'Radio Button', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Radio Button' }, + ], + }, + }, + { + path: 'datepicker', + component: AppDatepickerComponent, + data: { + title: 'Datepicker', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Datepicker' }, + ], + }, + }, + ], + }, + { + path: '', + children: [ + { + path: 'form-layouts', + component: AppFormLayoutsComponent, + data: { + title: 'Form Layouts', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Form Layouts' }, + ], + }, + }, + { + path: 'form-horizontal', + component: AppFormHorizontalComponent, + data: { + title: 'Form Horizontal', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Form Horizontal' }, + ], + }, + }, + { + path: 'form-vertical', + component: AppFormVerticalComponent, + data: { + title: 'Form Vertical', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Form Vertical' }, + ], + }, + }, + { + path: 'form-wizard', + component: AppFormWizardComponent, + data: { + title: 'Form Wizard', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Form Wizard' }, + ], + }, + }, + { + path: 'form-toastr', + component: AppFormToastrComponent, + data: { + title: 'Form Toastr', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Form Toastr' }, + ], + }, + }, + { + path: 'form-editor', + component: AppFormEditorComponent, + data: { + title: 'Form Editor', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Form Editor' }, + ], + }, + }, + ], + }, +]; + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.html b/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.html new file mode 100644 index 0000000..0fef605 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.html @@ -0,0 +1,169 @@ +
+ + +
+
+

+ The hassle-free setup process +

+
+ @for(topcard of setupCards; track topcard.title) { +
+ + +
+ @if(topcard.id!==2){ + users + } + +
+ {{ topcard.title }} +
+

+ {{ topcard.subtitle }} +

+ @if(topcard.id===2){ + image + } +
+
+
+
+ } +
+
+
+ + + +
+
+
+
+
+

Key metric at a glance

+

+ From the year we were founded to the impressive customer base + we've built, and the growth percentages that reflect our + continuous improvement, these numbers tell our story at a glance. + Explore the data that drives our mission and underscores our + commitment to excellence. +

+
+
+
+
+ @for (stat of stats; track stat) { +
+
+

+ {{ stat.label }} +

+

+ {{ stat.value }} +

+

{{ stat.description }}

+
+
+ } +
+
+
+
+
+ +
+ +
+ +
+
+
+ +
+
+

+ What our clients
think logo + about us? +

+

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+
+
+
+ + + Features availability + +
+
+ +
+
{{ currentUser().name }}
+
+ +

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+ + + +
+ + + {{ displayCount() }} + + +
+
+
+
+
+
+
+ + + +
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.scss b/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.scss new file mode 100644 index 0000000..e5e27d5 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.scss @@ -0,0 +1,23 @@ +.contact-page { + + .setup-process { + + mat-card-content { + padding: 0px !important; + padding: 30px 16px !important; + } + } + + .key-metric { + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + } + + .features { + + .cardWithShadow { + mat-card-content { + padding: 0px !important; + } + } + } +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.spec.ts new file mode 100644 index 0000000..0d075ce --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AboutUsComponent } from './about-us.component'; + +describe('AboutUsComponent', () => { + let component: AboutUsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AboutUsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AboutUsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.ts b/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.ts new file mode 100644 index 0000000..497b22d --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/about-us/about-us.component.ts @@ -0,0 +1,48 @@ +import { Component, computed, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { ImageSliderComponent } from '../image-slider/image-slider.component'; +import { FooterComponent } from '../footer/footer.component'; +//import { PagePricingComponent } from '../page-pricing/page-pricing.component'; +import { + setupCards, + stats, + users, +} from '../front-pagesData'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-about-us', + imports: [IconModule,MaterialModule ,CommonModule,ImageSliderComponent,FooterComponent, + //PagePricingComponent + ], + templateUrl: './about-us.component.html', + styleUrl: './about-us.component.scss' +}) +export class AboutUsComponent { + setupCards=setupCards; + stats = stats; + currentIndex = signal(0); // Starting from 0 + users = users; + // Computed values to auto-update template + currentUser = computed(() => this.users[this.currentIndex()]); + displayCount = computed( + () => `${this.currentIndex() + 1}/${this.users.length}` + ); + goPrev() { + if (this.currentIndex() > 0) { + this.currentIndex.update((i) => i - 1); + } + } + + goNext() { + if (this.currentIndex() < this.users.length - 1) { + this.currentIndex.update((i) => i + 1); + } + + + } + + + +} diff --git a/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.html b/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.html new file mode 100644 index 0000000..020f82c --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.html @@ -0,0 +1,116 @@ + + +
+
+ + + + @if(blogDetail()) { + + Photo of a Shiba Inu +
+ 2 mins Read +
+ +
+
+ +
+ {{ + blogDetail()?.category }} +
+ + {{ + blogDetail()?.title }} + +
+
+ {{ + blogDetail()?.views }} + 4 +
+ + + {{ blogDetail()?.date }} + +
+
+ +

Main Heading & Points

+

+ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the + industry's standard dummy text ever since + the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It + has survived not only five centuries, + but also the leap into electronic typesetting, + remaining essentially unchanged. It was popularised in the +

+
    +
  • Vivamus eu lacus scelerisque, placerat commodo lectus.
  • +
  • Etiam et ante at ex porta fringilla.
  • +
  • Nullam dignissim sem eu magna aliquet, sit amet volutpat tellus
  • +
+

+ Unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not + only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was + popularised in the +

+ +

+ We are a dedicated team of passionate product managers, developers, UX/UI designers, QA engineers experts + helping businesses from new startups +

+ +

+ There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in + some form, by injected humour, or randomised words which don't look even slightly believable making this the + first true generator on the Internet. It uses a dictionary +

+ +

Tags

+
    +
  • Trends
  • +
  • Design
  • +
  • Research
  • +
+ + +

Share

+ + + +

Join our newsletter

+

Email address : Subscribe

+
+
+ } + + + + + + @if (!blogDetail() || blogDetail().length === 0) { + + +

No blog post available.

+
+
+ } +
+
+ + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.scss b/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts new file mode 100644 index 0000000..241ed7b --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlogDetailsComponent } from './blog-details.component'; + +describe('BlogDetailsComponent', () => { + let component: BlogDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BlogDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BlogDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.ts b/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.ts new file mode 100644 index 0000000..9633085 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/blog-details/blog-details.component.ts @@ -0,0 +1,40 @@ +import { CommonModule } from '@angular/common'; +import { Component, inject, OnInit, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; +import { FrontEndService } from 'src/app/services/apps/front-pages/front-end.service'; + +@Component({ + selector: 'app-blog-details', + imports: [IconModule, MaterialModule, CommonModule, + FooterComponent + ], + templateUrl: './blog-details.component.html', + styleUrl: './blog-details.component.scss' +}) +export class BlogDetailsComponent implements OnInit { + blogDetail = signal(null); + private frontendService = inject(FrontEndService); + ngOnInit(): void { + const selected = this.frontendService.getBlog()(); + + if (selected) { + this.blogDetail.set(selected); + } else { + // Fallback if accessed directly (e.g., from sidebar or refresh) + const defaultBlog = { + id: 1, + time: "2 mins Read", + imgSrc: "/assets/images/blog/blog-img1.jpg", + user: "/assets/images/profile/user-1.jpg", + title: "As yen tumbles, gadget-loving Japan goes for secondhand iPhones", + views: "9,125", + category: "Social", + comments: 3, + date: "Mon, Dec 23" + }; + this.blogDetail.set(defaultBlog); + } + } +} diff --git a/theme/packages/main/src/app/pages/front-pages/blog/blog.component.html b/theme/packages/main/src/app/pages/front-pages/blog/blog.component.html new file mode 100644 index 0000000..e30ba7c --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/blog/blog.component.html @@ -0,0 +1,55 @@ + + +
+
+
+ @for(cardimg of cardimgs; track cardimg.imgSrc) { +
+ + Photo of a Shiba Inu +
+ {{ + cardimg.time + }} +
+ + +
+
+ +
+ {{ + cardimg.category + }} +
+ {{ cardimg.title }} +
+
+ {{ cardimg.views }} + {{ cardimg.comments }} +
+ + + {{ cardimg.date }} + +
+
+
+
+ } +
+
+
+ + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/blog/blog.component.scss b/theme/packages/main/src/app/pages/front-pages/blog/blog.component.scss new file mode 100644 index 0000000..e5dce08 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/blog/blog.component.scss @@ -0,0 +1,24 @@ + + +.social-btns { + margin-top: 20px; + + .btn-icon { + width: 25px !important; + height: 25px !important; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + + tabler-icon { + width: 16px !important; + height: 16px !important; + } + } + + .btn-add-story { + font-size: 0.75rem; + padding: 0.35rem 0.75rem; + } +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/blog/blog.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/blog/blog.component.spec.ts new file mode 100644 index 0000000..7998b08 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/blog/blog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlogComponent } from './blog.component'; + +describe('BlogComponent', () => { + let component: BlogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BlogComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BlogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/blog/blog.component.ts b/theme/packages/main/src/app/pages/front-pages/blog/blog.component.ts new file mode 100644 index 0000000..d25328e --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/blog/blog.component.ts @@ -0,0 +1,32 @@ +import { Component, inject, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { cardimgs } from '../front-pagesData'; +import { FooterComponent } from '../footer/footer.component'; +import { Router } from '@angular/router'; +import { FrontEndService } from 'src/app/services/apps/front-pages/front-end.service'; + +@Component({ + selector: 'app-blog', + imports: [IconModule, MaterialModule, FooterComponent,], + templateUrl: './blog.component.html', + styleUrl: './blog.component.scss' +}) +export class BlogComponent implements OnInit { + + private router = inject(Router); + private frontendService = inject(FrontEndService); + cardimgs = cardimgs; + + ngOnInit() { + console.log(cardimgs, 'cardimgs'); + } + + getNavigate(cardimg: any) { + console.log('cardimg--->', cardimg); + this.frontendService.setBlog(cardimg); + this.router.navigate(['front-pages/blog-details']) + + } + +} diff --git a/theme/packages/main/src/app/pages/front-pages/contact/contact.component.html b/theme/packages/main/src/app/pages/front-pages/contact/contact.component.html new file mode 100644 index 0000000..f2cfc62 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/contact/contact.component.html @@ -0,0 +1,103 @@ +
+ + + +
+
+
+ +
+ +
+
+
+
+
+
+ + First Name* + + + + + Phone Number* + + + +
+
+ + Last Name* + + + + + Email* + + + +
+
+ +
+
+ Enquire related to* + + + + General Enquiry + General Enquiry 2 + + +
+
+
+
+ Message + + + +
+
+ +
+
+ + +
+
Reach Out Today
+

+ Have questions or need assistance? We're just a message + away. +

+
+ +
+
Our Location
+

+ Visit us in person or find our contact details to connect + with us directly. +

+
+
+
+
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/contact/contact.component.scss b/theme/packages/main/src/app/pages/front-pages/contact/contact.component.scss new file mode 100644 index 0000000..572fa27 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/contact/contact.component.scss @@ -0,0 +1,3 @@ +.map-container{ + margin-top: -200px; +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/contact/contact.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/contact/contact.component.spec.ts new file mode 100644 index 0000000..dae8ee6 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/contact/contact.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ContactComponent } from './contact.component'; + +describe('ContactComponent', () => { + let component: ContactComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ContactComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ContactComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/contact/contact.component.ts b/theme/packages/main/src/app/pages/front-pages/contact/contact.component.ts new file mode 100644 index 0000000..556ed9a --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/contact/contact.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; + +@Component({ + selector: 'app-contact', + imports: [MaterialModule,IconModule,FooterComponent], + templateUrl: './contact.component.html', + styleUrl: './contact.component.scss' +}) +export class ContactComponent { + +} diff --git a/theme/packages/main/src/app/pages/front-pages/footer/footer.component.html b/theme/packages/main/src/app/pages/front-pages/footer/footer.component.html new file mode 100644 index 0000000..0177911 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/footer/footer.component.html @@ -0,0 +1,94 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/footer/footer.component.scss b/theme/packages/main/src/app/pages/front-pages/footer/footer.component.scss new file mode 100644 index 0000000..6a425bb --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/footer/footer.component.scss @@ -0,0 +1,13 @@ + +.footer-content{ + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } +} + +.imgStyleDash { + position: absolute; +} diff --git a/theme/packages/main/src/app/pages/front-pages/footer/footer.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/footer/footer.component.spec.ts new file mode 100644 index 0000000..3f93915 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/footer/footer.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FooterComponent } from './footer.component'; + +describe('FooterComponent', () => { + let component: FooterComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FooterComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FooterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/footer/footer.component.ts b/theme/packages/main/src/app/pages/front-pages/footer/footer.component.ts new file mode 100644 index 0000000..7864854 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/footer/footer.component.ts @@ -0,0 +1,95 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { RouterLink } from '@angular/router'; + +@Component({ + selector: 'app-footer', + imports: [MaterialModule, IconModule, RouterLink], + templateUrl: './footer.component.html', + styleUrl: './footer.component.scss' +}) +export class FooterComponent { + applicationsItems = [ + { + title: 'Kanban', + href: "/apps/kanban" + }, + { + title: 'Invoice List', + href: "/apps/invoice/list" + }, + { + title: 'eCommerce', + href: "/apps/product/shop" + }, + { + title: 'Chats', + href: "/apps/chat" + }, + { + title: 'Tickets', + href: "/apps/tickets" + }, + { + title: 'Blog', + href: "/apps/blog/post" + }, + ]; + + formsItems = [ + { + title: 'Form Layout', + href: "/forms/form-layouts" + }, + { + title: 'Form Horizontal', + href: "/forms/form-horizontal" + }, + { + title: 'Form Wizard', + href: "/forms/form-wizard" + }, + { + title: 'Form Vertical', + href: "/forms/form-vertical" + }, + { + title: 'Form Toastr', + href: "/forms/form-toastr" + }, + ]; + + tablesItems = [ + { + title: 'Basic Table', + href: "/tables/basic-table" + }, + { + title: 'Multi Header Footer Table', + href: "/tables/multi-header-footer-table" + }, + { + title: 'Pagination Table', + href: "/tables/pagination-table" + }, + { + title: 'Dynamic Table', + href: "/tables/dynamic-table" + }, + { + title: 'HTTP Table', + href: "/tables/http-table" + }, + { + title: 'Sortable Table', + href: "/tables/sortable-table" + }, + ]; + + socialIcons = [ + { src: 'assets/images/front-pages/icon-facebook.svg', tooltip: 'Facebook' }, + { src: 'assets/images/front-pages/icon-twitter.svg', tooltip: 'Twitter' }, + { src: 'assets/images/front-pages/icon-instagram.svg', tooltip: 'Instagram' }, + ]; +} diff --git a/theme/packages/main/src/app/pages/front-pages/front-pages.routes.ts b/theme/packages/main/src/app/pages/front-pages/front-pages.routes.ts new file mode 100644 index 0000000..bf9375c --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/front-pages.routes.ts @@ -0,0 +1,28 @@ +import { Routes } from '@angular/router'; +import { HomepageComponent } from './homepage/homepage.component'; +import { AboutUsComponent } from './about-us/about-us.component'; +import { HomepageDetailsComponent } from './homepage-details/homepage-details.component'; +import { BlogComponent } from './blog/blog.component'; +import { PortfolioComponent } from './portfolio/portfolio.component'; +import { PricingComponent } from './pricing/pricing.component'; +import { ContactComponent } from './contact/contact.component'; +import { BlogDetailsComponent } from './blog-details/blog-details.component'; + + +export const FrontPagesRoutes: Routes = [ + + { + path: '', + component: HomepageComponent, // acts as layout shell + children: [ + { path: '', redirectTo: 'homepage', pathMatch: 'full' }, + { path: 'homepage', component: HomepageDetailsComponent }, // real homepage content + { path: 'about', component: AboutUsComponent }, + {path:'blog',component:BlogComponent }, + { path: 'portfolio', component: PortfolioComponent }, + { path: 'pricing', component: PricingComponent }, + { path: 'contact', component: ContactComponent }, + { path: 'blog-details', component: BlogDetailsComponent }, + ], + }, +]; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/front-pagesData.ts b/theme/packages/main/src/app/pages/front-pages/front-pagesData.ts new file mode 100644 index 0000000..0e870f4 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/front-pagesData.ts @@ -0,0 +1,768 @@ +interface cardimgs { + id: number; + time: string; + imgSrc: string; + user: string; + title: string; + views: string; + category: string; + comments: number; + date: string; +} + +interface productcards { + id: number; + imgSrc: string; + title: string; + price: string; + rprice: string; + date: string; +} + +interface Framework { + src: string; + alt: string; + tooltip: string; +} + +interface followercards { + id: number; + imgSrc: string; + title: string; +} + +interface setupCards { + id: number; + img: string; + color: string; + title: string; + subtitle: string; + imgMain?:string; +} + +export const cardimgs: cardimgs[] = [ + { + id: 1, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img1.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 2, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img2.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 3, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img3.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + { + id: 4, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img4.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 5, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img5.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 6, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img6.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + { + id: 7, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img10.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 8, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img8.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 9, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img9.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, +]; + +export const productcards: productcards[] = [ + { + id: 1, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Headphone', + price: '285', + rprice: '375', + date: 'Tue, Apr 03, 2025', + }, + { + id: 2, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Air Pro', + price: '285', + rprice: '375', + date: 'Tue, Apr 10, 2025', + }, + { + id: 3, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Red Velvet Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 15, 2025', + }, + { + id: 4, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Soft Plush Teddy', + price: '285', + rprice: '375', + date: 'Tue, Apr 12, 2025', + }, + { + id: 5, + imgSrc: 'assets/images/products/s2.jpg', + title: 'Boat Bass Booster', + price: '285', + rprice: '375', + date: 'Tue, Apr 14, 2025', + }, + { + id: 6, + imgSrc: 'assets/images/products/s6.jpg', + title: 'MacBook Ultra Slim', + price: '285', + rprice: '375', + date: 'Tue, Apr 18, 2025', + }, + { + id: 7, + imgSrc: 'assets/images/products/s8.jpg', + title: 'Crimson Party Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 20, 2025', + }, + { + id: 8, + imgSrc: 'assets/images/products/s12.jpg', + title: 'Cuddly Teddy Gift', + price: '285', + rprice: '375', + date: 'Tue, Apr 22, 2025', + }, + { + id: 9, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Sonic Headset', + price: '285', + rprice: '375', + date: 'Tue, Apr 25, 2025', + }, + { + id: 10, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Pro 2025', + price: '285', + rprice: '375', + date: 'Tue, Apr 27, 2025', + }, + { + id: 11, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Evening Gown - Red', + price: '285', + rprice: '375', + date: 'Tue, Apr 29, 2025', + }, + { + id: 12, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Fluffy Bear Surprise', + price: '285', + rprice: '375', + date: 'Tue, Apr 30, 2025', + }, +]; + +export const frameworks: Framework[] = [ + { + src: 'assets/images/landingpage/frameworks/angular.svg', + alt: 'Angular', + tooltip: 'Angular', + }, + { + src: 'assets/images/landingpage/frameworks/material.svg', + alt: 'Angular Material', + tooltip: 'Angular Material', + }, + { + src: 'assets/images/landingpage/frameworks/logo-ts.svg', + alt: 'Typescript', + tooltip: 'Typescript', + }, + { + src: 'assets/images/landingpage/frameworks/icon-tabler.svg', + alt: 'Tabler Icon', + tooltip: 'Tabler Icon', + }, +]; + +export const tiles = [ + { + id: 1, + text: 'Light & Dark Color Schemes', + cols: 1, + rows: 1, + color: '#FFF6E5', + icon: 'svgs/icon-briefcase.svg', + subtitle: 'Choose your preferred visual style effortlessly.', + }, + { + id: 2, + text: 'New Demos', + cols: 2, + rows: 2, + color: '#E9F1FF', + icon: 'logos/logoIcon.svg', + img: 'landingpage/background/screen1.png', + subtitle: + 'Brand new demos to help you build the perfect dashboard:
Dark and Right-to-Left.', + }, + { + id: 3, + text: 'Code Improvements', + cols: 1, + rows: 1, + color: '#E7FFF2', + icon: 'logos/icon-speech-bubble.svg', + subtitle: 'Benefit from continuous improvements and optimizations.', + }, + { + id: 4, + text: '12+ Ready to Use Application Designs', + cols: 1, + rows: 1, + color: '#E4F4FF', + icon: 'icon-layer.svg', + img: 'landingpage/background/feature-apps.png', + subtitle: 'Instantly deployable designs for your applications.', + }, + { + id: 5, + text: '50+ UI Components', + cols: 1, + rows: 1, + color: '#FFECEC', + icon: 'logos/icon-favorites.svg', + subtitle: 'A rich collection for seamless user experiences.', + }, +]; + +export const users = [ + { name: 'Jenny Wilson', img: '/assets/images/profile/user-1.jpg' }, + { name: 'Robert Fox', img: '/assets/images/profile/user-2.jpg' }, + { name: 'Kristin Watson', img: '/assets/images/profile/user-3.jpg' }, + { name: 'Darlene Robertson', img: '/assets/images/profile/user-4.jpg' }, + { name: 'Jacob Jones', img: '/assets/images/profile/user-5.jpg' }, +]; + +export const plans = [ + { + title: 'Single Use', + description: + 'Use for single end product which end users can’t be charged for.', + price: 49, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: false }, + { text: 'One Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Multiple Use', + description: + 'Use for unlimited end products end users can’t be charged for.', + price: 89, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: false }, + { text: 'Unlimited Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Extended Use', + description: + 'Use for single end product which end users can be charged for.', + price: 299, + period: 'one time pay', + popular: true, + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: true }, + { text: 'One Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Unlimited Use', + description: + 'Use in unlimited end products end users can be charged for.', + price: 499, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: true }, + { text: 'Unlimited Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, +]; + +export const paymentLogos = [ + { src: 'assets/images/front-pages/icon-visa.svg', alt: 'visa', tooltip: 'Visa' }, + { + src: 'assets/images/front-pages/icon-mastercard.svg', + alt: 'mastercard', + tooltip: 'Master Card', + }, + { + src: 'assets/images/front-pages/icon-american-express.svg', + alt: 'american express', + tooltip: 'American Express', + }, + { + src: 'assets/images/front-pages/icon-discover.svg', + alt: 'discover', + tooltip: 'Discover', + }, + { + src: 'assets/images/front-pages/icon-paypal.svg', + alt: 'paypal', + tooltip: 'Paypal', + }, + { + src: 'assets/images/front-pages/icon-masetro.svg', + alt: 'maestro', + tooltip: 'Maestro', + }, + { src: 'assets/images/front-pages/icon-jcb.svg', alt: 'jcb', tooltip: 'JCB' }, + { + src: 'assets/images/front-pages/icon-diners.svg', + alt: 'diners', + tooltip: 'Diners', + }, +]; + +export const faqList = [ + { + question: 'What is included with my purchase?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Are there any recurring fees?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Can i use template on multiple projects? ', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: + 'Can i use customize the admin dashboard template to match my brand?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Are any restrictions on using the template?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'How can i get support after purchase? ', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, +]; + +export const followercardsFirst: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, +]; + +export const followercardSecond: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, +]; +export const followercardThird: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-customize.svg', + title: 'Easy to Customize', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-chart.svg', + title: 'Lots of Chart Options', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-table.svg', + title: 'Lots of Table Examples', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-update.svg', + title: 'Regular Updates', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-support.svg', + title: 'Dedicated Support', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Easy to Customize', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: 'Lots of Chart Options', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Lots of Table Examples', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Regular Updates', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Dedicated Support', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Easy to Customize', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: 'Lots of Chart Options', + }, + +]; + +export const topcardsGrid = [ + { title: 'Light & Dark Color Schemes', subtitle: 'Choose your preferred visual style effortlessly.', + img: '/assets/images/svgs/icon-briefcase.svg', color: 'warning' }, + { title: '12+ Ready to Use Application Designs', subtitle: 'Instantly deployable designs for your applications.', + img: 'assets/icons/icon2.png', color: 'secondary',imgMain: '/assets/images/landingpage/background/feature-apps.png', }, + { title: 'New Demos', subtitle: 'Brand new demos to help you build the perfect dashboard: Dark and Right-to-Left.', + img: '/assets/images/front-pages/logoIcon.svg', color: 'primary',imgMain: '/assets/images/landingpage/background/screen1.png' }, + { title: 'Code Improvements', subtitle: 'Benefit from continuous improvements and optimizations.', + img: '/assets/images/front-pages/icon-speech-bubble.svg', color: 'success' }, + { title: '50+ UI Components', subtitle: 'A rich collection for seamless user experiences.', + img: '/assets/images/front-pages/icon-favorites.svg', color: 'error' }, +]; + +export const setupCards:setupCards[] = [ + { + id: 1, + color: 'warning', + img: '/assets/images/svgs/icon-briefcase.svg', + title: 'Light & Dark Color Schemes', + subtitle: 'Choose your preferred visual style effortlessly.', + }, + { + id: 2, + color: 'secondary', + img: '/assets/images/svgs/icon-connect.svg', + title: '12+ Ready to Use Application Designs', + subtitle: 'Instantly deployable designs for your applications.', + imgMain: '/assets/images/landingpage/background/feature-apps.png' + }, + + { + id: 3, + color: 'success', + img: '/assets/images/svgs/icon-speech-bubble.svg', + title: 'Code Improvements', + subtitle: 'Benefit from continuous improvements and optimizations.', + }, + { + id: 4, + color: 'error', + img: '/assets/images/svgs/icon-favorites.svg', + title: '50+ UI Components', + subtitle: 'A rich collection for seamless user experiences.', + }, + +]; + +export const stats = [ + { + label: 'Founded', + value: '2019', + description: 'When we founded Modernize', + }, + { + label: 'Growth', + value: '1,400%', + description: 'Revenue growth in 2024', + }, + { + label: 'Customers', + value: '300k+', + description: 'Customers on Modernize', + }, + { + label: 'Dashboards', + value: '25k+', + description: 'Dashboards built using Modernize', + }, +]; + +export const team = [ + {id: 1, + name: 'Alex Martinez', + position: 'CEO & Co-Founder', + image: 'assets/images/front-pages/user1.jpg' + }, + { + id: 2, + name: 'Jordan Nguyen', + position: 'CTO & Co-Founder', + image: 'assets/images/front-pages/user2.jpg' + }, + { + id: 3, + name: 'Taylor Roberts', + position: 'Product Manager', + image: 'assets/images/front-pages/user3.jpg' + }, + {id: 4, + name: 'Morgan Patel', + position: 'Lead Developer', + image: 'assets/images/front-pages/user4.jpg' + }, + { + id: 5, + name: 'Andrew Grant', + position: 'Product Manager', + image: 'assets/images/front-pages/user5.jpg' + }, + { + id: 6, + name: 'Leo Pratt', + position: 'Lead Developer', + image: 'assets/images/front-pages/user3.jpg' + }, + { + id: 7, + name: 'C. A. Nunez', + position: 'CEO & Co-Founder', + image: 'assets/images/front-pages/user2.jpg' + }, + { + id: 8, + name: 'Leo Maxwell', + position: 'Lead Developer', + image: 'assets/images/front-pages/user1.jpg' + } +]; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.html b/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.html new file mode 100644 index 0000000..b50b52c --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.html @@ -0,0 +1,603 @@ +
+
+
+
+
+

+ Most powerful & + developer friendly + dashboard +

+
+
+
+ @if(!isMobileView){ + +
+ banner-top-left +
+ } + +
+
+
+ +
+ 52,589+ developers & agencies using our templates +
+
+
+
+ Login +
+ + See how it works +
+
+
+ @for (framework of frameworks; track framework.tooltip) { + + + + } +
+
+ @if(!isMobileView){ +
+ banner-top-right +
+ + } +
+ @if (!isMobileView) { +
+
+ bottom-part +
+
+ } +
+
+ +
+
+
+
+

+ Introducing Modernize's Light & Dark Skins, Exceptional Dashboards, + and Dynamic Pages - Stay Updated on What's New! +

+
+
+ + + + + @if (!isMobileView) { +
+ +
+
+ @for (topcard of topcards; track topcard.title) { + @if (topcard.title === 'Light & Dark Color Schemes' || topcard.title.includes('12+')) { + + + @if (topcard.title === 'Light & Dark Color Schemes') { + icon + } +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+ @if (topcard.title.includes('12+')) { + image + } +
+
+ } + } +
+
+
+
+ @for (topcard of topcards; track topcard.title) + { + @if + (topcard.title.includes('New Demos')) { + + + icon +

{{ topcard.title }}

+

+ demo +
+
+ } } +
+
+ + +
+
+ @for (topcard of topcards; track topcard.title) { + @if (topcard.title.includes('Code Improvements') || topcard.title.includes('UI Components')) { + + + icon +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+
+
+ } + } +
+
+ +
+ } + + + @else { +
+ @for (topcard of topcards; track topcard.title) { + @if (!topcard.title.includes('New Demos')) { + + + @if (!topcard.title.includes('12+')) { + icon + } +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+ + @if (topcard.title.includes('12+')) { + image + } +
+
+ } + } +
+ + +
+ @for (topcard of topcards; track topcard.title) + { + @if + (topcard.title.includes('New Demos')) { + + + icon +
{{ topcard.title }}
+

+ demo +
+
+ } } +
+ } + + +
+
+ +
+ +
+ + + + + Team Scheduling + + + + + + Payments + + + + + + Embedding + + + + + + Workflows + + + + + + +
+
+
+ slider-group +
+
+ +
+
+

Defend your focus

+
+ + + + +
+ Factor in outside colleagues + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+ + + + +
+ Combine teammate schedules + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+ + + + +
+ Round robin pooling + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+
+
+ + Learn More +
+ + +
+
+
+
+ +
+ +
+ +
+
+
+ + + Save valuable time and effort spent searching for a solution. + Contact us now + +
+
+
+ +
+
+
+
+

+ Discover Powerful Dozens of
Purpose-Fit Templates +

+
+
+
+
+ + slide + +
+
+
+
+ + slide + +
+
+
+
+ + slide + +
+
+
+
+ slide +
+
+
+
+ + slide + +
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+
+
+

High Customizability

+

+ Tailor the dashboard to your exact needs. Customize layouts, color + schemes, and widgets effortlessly for a personalized user + experience. +

+
+
+

Powerful Data Analytics

+

+ Unlock the true potential of your data with our advanced analytics + tools. Gain valuable insights and make data-driven decisions with + ease. +

+
+ +
+

Interactive Charts

+

+ Visualize complex data sets beautifully with our interactive + graphs and charts. Quickly grasp trends and patterns for smarter + analysis. +

+
+
+
+
+
+
+ +
+
+
+ +
+
+

+ What our clients
think logo + about us? +

+

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+
+
+
+ + + Features availability + +
+
+ +
+
{{ currentUser().name }}
+
+ +

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+ + + +
+ + + {{ displayCount() }} + + +
+
+
+
+
+
+
+ +
+
+
+
+
+

+ Enjoy unparalleled features & exceptional flexibility. +

+
+
+ +
+
+
+ @for (followercard of followercardsfirst; track followercard.title) + { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+ @for (followercard of followercardsecond; track followercard.title) + { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+ @for (followercard of followercardthird; track followercard.title) { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+
+
+ +
+
+

Frequently Asked Questions

+
+
+ + @for (item of faqList; track item) { + + + {{ + item.question + }} + + + + + +

{{ item.answer }}

+
+ } +
+
+
+
+
+ Still have a question? + Ask on discord + or + Submit a ticket +
+
+
+
+ + + +
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.scss b/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.scss new file mode 100644 index 0000000..e6e0f4b --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.scss @@ -0,0 +1,189 @@ +.home-page { + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } + + .home-page-header { + + .header-container-content { + + .cardPosition { + .float-image { + animation: floatUpDown 6s ease-in-out infinite; + } + } + + .cardPositionTwo { + + .float-image { + animation: floatUpDown 6s ease-in-out infinite; + } + } + + .loginBtn { + .play-button { + background-color: transparent; + border: 2px solid var(--mat-sys-primary); // or use your theme color + color: var(--mat-sys-primary); + box-shadow: none; + } + + .textSee { + cursor: pointer; + + &:hover { + color: var(--mat-sys-primary); + } + } + } + } + } + + .dashboardCards { + + .card-container { + + mat-card-content { + padding: 0px !important; + } + } + } + + .tab-header { + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + + .profileTabs { + background-color: var(--mdc-elevated-card-container-color) !important; + + .mat-mdc-tab.mdc-tab-indicator--active { + .mdc-tab__text-label { + color: var(--mat-sys-primary); + } + } + } + + } + + .template-slider { + .template-slider-content { + .demo-slider { + .demo-slide { + animation: slide3d 15s linear infinite; + } + } + } + } + + .features { + + .cardWithShadow { + mat-card-content { + padding: 0px !important; + } + } + } + + .exceptional { + .exceptional-content { + .demo-slider { + .demo-slide { + animation: slide3d 20s linear infinite; + } + + .demo-slide-two { + animation: slide3dTwo 20s linear infinite; + } + } + } + } + + .expansion-panel { + box-shadow: none; + background: transparent; + border-radius: 0 !important; + border-bottom: 1px solid var(--mat-sys-outline); + + .mat-expansion-panel-header { + padding: 18px 0 !important; + height: auto; + } + } + + .sliderImg { + max-width: 380px; + height: 300px; + } + + .img-border { + border: 2px solid var(--mat-sys-secondary); + /* Blue border, change color as needed */ + cursor: pointer; + } + + .img-border:hover { + border-color: var(--mat-sys-secondary); + } + + .border-dash { + border: 1px dashed var(--mat-sys-outline); // Initial border color (Bootstrap primary) + transition: border-color 0.3s ease; + flex-wrap: wrap; + + &:hover { + border-color: var(--mat-sys-primary); // Use your Angular Material primary variable or a custom color + } + } + + .faq-accordion { + .mat-expansion-panel { + border-radius: 8px !important; + + .mat-expansion-panel-header { + padding: 20px 21px !important; + } + } + } +} + +@keyframes floatUpDown { + + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(-6px); // smaller bounce + } +} + +@keyframes slide3d { + from { + transform: translate3d(0, 0, 0); + } + + to { + transform: translate3d(-2028px, 0, 0); // adjust based on actual slide width + } +} + +@keyframes slide3dTwo { + from { + transform: translate3d(-2028px, 0, 0); // Rightward (starts left) + } + + to { + transform: translate3d(0, 0, 0); + } +} + + + +@media (max-width: 1199px) { + .home-page-header { + padding-bottom: 48px; + } +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts new file mode 100644 index 0000000..52b6227 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HomepageDetailsComponent } from './homepage-details.component'; + +describe('HomepageDetailsComponent', () => { + let component: HomepageDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HomepageDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HomepageDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.ts b/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.ts new file mode 100644 index 0000000..46f68e1 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/homepage-details/homepage-details.component.ts @@ -0,0 +1,131 @@ +import { Component, computed, DestroyRef, inject, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { + faqList, + followercardsFirst, + followercardSecond, + followercardThird, + frameworks, + tiles, + users, + topcardsGrid, +} from '../front-pagesData'; +import { CommonModule } from '@angular/common'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { ImageSliderComponent } from '../image-slider/image-slider.component'; +import { FooterComponent } from '../footer/footer.component'; +import { MatDialog } from '@angular/material/dialog'; +import { TemplateVideoComponent } from '../template-video/template-video.component'; +import { Router, RouterModule } from '@angular/router'; + + +@Component({ + selector: 'app-homepage-details', + imports: [ + MaterialModule, + IconModule, + CommonModule, + ImageSliderComponent, + FooterComponent, + RouterModule + ], + templateUrl: './homepage-details.component.html', + styleUrl: './homepage-details.component.scss', +}) +export class HomepageDetailsComponent { + + topcards=topcardsGrid; + + + centered = false; + disabled = false; + unbounded = false; + radius: number; + color: string; + showBackground: boolean = false; + frameworks = frameworks; + selectedIndex = 1; + + readonly dialog = inject(MatDialog); + private router = inject(Router); + private destroyRef = inject(DestroyRef); // ✅ For automatic cleanup + private mediaMatcher = inject(MediaMatcher); // ✅ Proper MediaMatcher injection + + mobileQuery: MediaQueryList; + isMobileView = false; + + readonly panelOpenState = signal(false); + tiles = tiles; + hideCloserBtn: boolean = true; + users = users; + expandedIndex: number | null = null; + currentIndex = signal(0); // Starting from 0 + faqList = faqList; + selectedPath: string | null = null; + clicked = false; + + followercardsfirst = followercardsFirst; + followercardsecond = followercardSecond; + followercardthird = followercardThird; + + currentUser = computed(() => this.users[this.currentIndex()]); + displayCount = computed(() => `${this.currentIndex() + 1}/${this.users.length}`); + + constructor() { + const isSmallScreen = this.mediaMatcher.matchMedia('(max-width: 599px)'); + // ✅ Setup media query for max-width: 1199px + this.mobileQuery = this.mediaMatcher.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + const listener = (e: MediaQueryListEvent) => { + this.isMobileView = e.matches; + }; + + // ✅ Listen to viewport changes + this.mobileQuery.addEventListener('change', listener); + + // ✅ Clean up listener on component destroy + this.destroyRef.onDestroy(() => { + this.mobileQuery.removeEventListener('change', listener); + }); + } + isOver(): boolean { + return this.mediaMatcher.matchMedia('(max-width: 1199px)').matches; + } + + goPrev() { + if (this.currentIndex() > 0) { + this.currentIndex.update((i) => i - 1); + } + } + + goNext() { + if (this.currentIndex() < this.users.length - 1) { + this.currentIndex.update((i) => i + 1); + } + } + openDialog(showBackground:boolean){ + this.showBackground = showBackground; + + const dialogRef = this.dialog.open(TemplateVideoComponent, { + data: {}, + width: '1000px', + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result === false) { + this.showBackground = false; // Reset or take any action + } + }); + } + + + onImageClick(path: string) { + this.selectedPath = path; + + setTimeout(() => { + this.router.navigate([path]); + }, 100); // brief delay to show border + } +} diff --git a/theme/packages/main/src/app/pages/front-pages/homepage/homepage.component.html b/theme/packages/main/src/app/pages/front-pages/homepage/homepage.component.html new file mode 100644 index 0000000..532acf0 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/homepage/homepage.component.html @@ -0,0 +1,137 @@ +
+ + + @if(hideCloserBtn){ + + + + +
+ New + Frontend Pages Included! +
+ + + + +
+ + } + +
+
+
+ +
+ + @if(!isMobileView){ +
+ + + + + + + + +
+ Login + } @if(isMobileView){ + + } +
+
+
+ +
+ +
+
+ + + +
+
+ +
+
+ + + + + + + + + + + + + + + + + Get + Started + +
+
+
+
+ @if(showBackToTop){ +
+ +
+ } +
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/homepage/homepage.component.scss b/theme/packages/main/src/app/pages/front-pages/homepage/homepage.component.scss new file mode 100644 index 0000000..3cee318 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/homepage/homepage.component.scss @@ -0,0 +1,32 @@ +.landing-page { + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } + + .heightToolbar { + height: 46px; + background-size: cover; + background-repeat: no-repeat; + background-image: url(../../../../assets/images/front-pages/topbar-bg.png); + } + + .toolBarContent { + .nav-item { + &.selected { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); // optional for visibility + transition: background-color 0.3s ease; + } + + &:hover { + color: var(--mat-sys-primary); + transition: color 0.3s ease; + } + } + + } + +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/homepage/homepage.component.ts b/theme/packages/main/src/app/pages/front-pages/homepage/homepage.component.ts new file mode 100644 index 0000000..ca1a34a --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/homepage/homepage.component.ts @@ -0,0 +1,65 @@ +import { MediaMatcher } from '@angular/cdk/layout'; +import { CommonModule } from '@angular/common'; +import { Component, HostListener, inject, ViewChild } from '@angular/core'; +import { MatSidenav } from '@angular/material/sidenav'; +import { ActivatedRoute, Router, RouterLink, RouterOutlet } from '@angular/router'; +import { IconModule } from 'src/app/icon/icon.module'; +import { BrandingComponent } from 'src/app/layouts/full/vertical/sidebar/branding.component'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-homepage', + imports: [MaterialModule, BrandingComponent, RouterLink, + IconModule, RouterOutlet, CommonModule], + templateUrl: './homepage.component.html', + styleUrl: './homepage.component.scss' +}) +export class HomepageComponent { + @ViewChild('customizerRight') customizerRight!: MatSidenav; + selected: string = ''; // default selected + mobileQuery: MediaQueryList; + isMobileView = false; + hideCloserBtn: boolean = true; + private router = inject(Router) + private mediaMatcher: MediaQueryList = matchMedia(`(max-width: 1199px)`); + showBackToTop: boolean; + isTopbarFixed: boolean; + constructor(private route: ActivatedRoute) { + const media = inject(MediaMatcher); + this.mobileQuery = media.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + this.mobileQuery.addEventListener('change', (e) => { + + this.isMobileView = e.matches; + this.closeSidenavIfNeeded(); + }); + } + closeSidenavIfNeeded() { + if (!this.isMobileView && this.customizerRight?.opened) { + this.customizerRight.close(); + } + } + isOver(): boolean { + return this.mediaMatcher.matches; + } + + isActiveRoute(route: string): boolean { + return this.router.url.includes(`/front-pages/${route}`); + } + hideCloser() { + this.hideCloserBtn = false; + } + getNavigate() { + this.router.navigate(['/dashboards/dashboard1']) + } + + scrollToTop(): void { + window.scrollTo({ top: 0, behavior: 'smooth' }); + } + @HostListener('window:scroll', []) + onWindowScroll() { + this.showBackToTop = window.scrollY > 300; + this.isTopbarFixed = scrollY > 45; + } +} diff --git a/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.html b/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.html new file mode 100644 index 0000000..f4c4b31 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.html @@ -0,0 +1,44 @@ +
+
+
+
+
+

Our leadership

+
+

+ Our robust analytics offer rich insights into the information + buyers want, informing where teams +

+
+
+ +
+
+ + +
+
+
+ +
+ @for (member of visibleTeamMembers(); track member.id){ +
+ + + imgSrc + + +

{{ member.name }}

+

{{ member.position }}

+
+
+
+ } +
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.scss b/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.scss new file mode 100644 index 0000000..0832285 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.scss @@ -0,0 +1,22 @@ +.img-slider-content { + .img-slider { + + .mat-mdc-card { + margin-bottom: 0px !important; + } + + .productcard { + position: relative; + + .info-card { + bottom: 42px; // controls overlap depth + left: 50%; + transform: translateX(-50%); + width: 90%; + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + z-index: 2; + } + } + + } +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts new file mode 100644 index 0000000..c933f20 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ImageSliderComponent } from './image-slider.component'; + +describe('ImageSliderComponent', () => { + let component: ImageSliderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ImageSliderComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ImageSliderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.ts b/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.ts new file mode 100644 index 0000000..d5db5ee --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/image-slider/image-slider.component.ts @@ -0,0 +1,39 @@ +import { Component, computed, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { team } from '../front-pagesData'; + +@Component({ + selector: 'app-image-slider', + imports: [MaterialModule,IconModule], + templateUrl: './image-slider.component.html', + styleUrl: './image-slider.component.scss' +}) +export class ImageSliderComponent { + team = team; + // Signals + currentPage = signal(0); + pageSize = 4; + + visibleTeamMembers = computed(() => { + const start = this.currentPage() * this.pageSize; + const end = start + this.pageSize; + return this.team.slice(start, end); + }); + + next() { + console.log('next--->',this.visibleTeamMembers().map(m => m.id)); + const totalPages = Math.ceil(this.team.length / this.pageSize); + if (this.currentPage() < totalPages - 1) { + this.currentPage.update((p) => p + 1); + } + } + + prev() { + console.log(this.visibleTeamMembers().map(m => m.id)); + if (this.currentPage() > 0) { + this.currentPage.update((p) => p - 1); + } + } + +} diff --git a/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.html b/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.html new file mode 100644 index 0000000..32bdd60 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.html @@ -0,0 +1,68 @@ +
+
+

+ 111,476+ Trusted developers & many tech giants as well +

+
+
+
+ @for(plan of plans;track plan){ +
+ + + +
+
+ {{ plan.title }} + @if (plan.popular) { + + Popular + + } +
+
+

{{ plan.description }}

+ + +
+ ${{ plan.price }} + /{{ plan.period }} +
+
+ @for(feature of plan.features; track feature) { +
+ icon-facebook-dark + + + {{ feature.text }} + +
+ } +
+ + +
+
+ +
+ } + + +
+
+

Secured payment with PayPal & Razorpay

+
+ @for( logo of paymentLogos;track logo){ + + } +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.scss b/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts new file mode 100644 index 0000000..fb0a9c8 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PagePricingComponent } from './page-pricing.component'; + +describe('PagePricingComponent', () => { + let component: PagePricingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PagePricingComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PagePricingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.ts b/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.ts new file mode 100644 index 0000000..7a435ae --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/page-pricing/page-pricing.component.ts @@ -0,0 +1,17 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { paymentLogos, plans } from '../front-pagesData'; + +@Component({ + selector: 'app-page-pricing', + imports: [MaterialModule, IconModule, CommonModule], + templateUrl: './page-pricing.component.html', + styleUrl: './page-pricing.component.scss', +}) +export class PagePricingComponent { + plans = plans; + + paymentLogos = paymentLogos; +} diff --git a/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.html b/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.html new file mode 100644 index 0000000..f64670b --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.html @@ -0,0 +1,57 @@ + + +
+
+
+
+
Portfolio
+
+
{{ filteredCount }}
+
+
+ + + + search + + +
+
+ @for(productcard of filteredCardImgs; track productcard.id) { +
+ + + imgSrc + + + +
+ +
+
{{ productcard.title }}
+

{{ productcard.date }}

+
+ + + +
+
+
+
+
+ } +
+
+
+ \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.scss b/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts new file mode 100644 index 0000000..073ce35 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PortfolioComponent } from './portfolio.component'; + +describe('PortfolioComponent', () => { + let component: PortfolioComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PortfolioComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PortfolioComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.ts b/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.ts new file mode 100644 index 0000000..702ebee --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/portfolio/portfolio.component.ts @@ -0,0 +1,37 @@ + + +import { Component, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { productcards } from '../front-pagesData'; +import { FooterComponent } from '../footer/footer.component'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-portfolio', + imports: [MaterialModule, IconModule, FooterComponent, CommonModule, FormsModule], + templateUrl: './portfolio.component.html', + styleUrl: './portfolio.component.scss' +}) +export class PortfolioComponent implements OnInit { + + filteredCards = productcards; + + searchText: string = ''; + + filteredCardImgs = [...this.filteredCards]; // Initialize with full data + filteredCount: number = this.filteredCardImgs.length; + ngOnInit(): void { + console.log('filteredCards', this.filteredCards) + } + onSearchChange() { + const query = this.searchText.toLowerCase().trim(); + this.filteredCardImgs = this.filteredCards.filter(item => + item.title.toLowerCase().includes(query) || + item.date.toLowerCase().includes(query) + ); + this.filteredCount = this.filteredCardImgs.length; // ✅ update the count here + } +} + diff --git a/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.html b/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.html new file mode 100644 index 0000000..6c42e4a --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.html @@ -0,0 +1,18 @@ + + +
+
+ +
+
+ + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.scss b/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.spec.ts new file mode 100644 index 0000000..147f94e --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PricingComponent } from './pricing.component'; + +describe('PricingComponent', () => { + let component: PricingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PricingComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PricingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.ts b/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.ts new file mode 100644 index 0000000..0684d59 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/pricing/pricing.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; +import { PagePricingComponent } from '../page-pricing/page-pricing.component'; + +@Component({ + selector: 'app-pricing', + imports: [MaterialModule,IconModule,FooterComponent,PagePricingComponent], + templateUrl: './pricing.component.html', + styleUrl: './pricing.component.scss' +}) +export class PricingComponent { + +} diff --git a/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.html b/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.html new file mode 100644 index 0000000..9b7d777 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.html @@ -0,0 +1,11 @@ + + + +
+ + +
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.scss b/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.spec.ts b/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.spec.ts new file mode 100644 index 0000000..46d7589 --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TemplateVideoComponent } from './template-video.component'; + +describe('TemplateVideoComponent', () => { + let component: TemplateVideoComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TemplateVideoComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TemplateVideoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.ts b/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.ts new file mode 100644 index 0000000..b239adb --- /dev/null +++ b/theme/packages/main/src/app/pages/front-pages/template-video/template-video.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { MatDialogRef } from '@angular/material/dialog'; +@Component({ + selector: 'app-template-video', + imports: [MaterialModule, + IconModule,], + templateUrl: './template-video.component.html', + styleUrl: './template-video.component.scss' +}) +export class TemplateVideoComponent { +constructor(private dialogRef: MatDialogRef){ + +} +closeDialog(): void { + this.dialogRef.close(false); // Pass false back to parent +} +} diff --git a/theme/packages/main/src/app/pages/pages.routes.ts b/theme/packages/main/src/app/pages/pages.routes.ts new file mode 100644 index 0000000..492ec5b --- /dev/null +++ b/theme/packages/main/src/app/pages/pages.routes.ts @@ -0,0 +1,12 @@ +import { Routes } from '@angular/router'; +import { StarterComponent } from './starter/starter.component'; + +export const PagesRoutes: Routes = [ + { + path: '', + component: StarterComponent, + data: { + title: 'Starter Page', + }, + }, +]; diff --git a/theme/packages/main/src/app/pages/starter/starter.component.html b/theme/packages/main/src/app/pages/starter/starter.component.html new file mode 100644 index 0000000..51aa4d2 --- /dev/null +++ b/theme/packages/main/src/app/pages/starter/starter.component.html @@ -0,0 +1,33 @@ + + + + + +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ Link +
+
+

test

+

test

+
+
+
diff --git a/theme/packages/main/src/app/pages/starter/starter.component.ts b/theme/packages/main/src/app/pages/starter/starter.component.ts new file mode 100644 index 0000000..92c6295 --- /dev/null +++ b/theme/packages/main/src/app/pages/starter/starter.component.ts @@ -0,0 +1,10 @@ +import { Component, ViewEncapsulation } from '@angular/core'; +import { MaterialModule } from '../../material.module'; + +@Component({ + selector: 'app-starter', + imports: [MaterialModule], + templateUrl: './starter.component.html', + encapsulation: ViewEncapsulation.None +}) +export class StarterComponent {} diff --git a/theme/packages/main/src/app/pages/tables/basic-table/basic-table.component.html b/theme/packages/main/src/app/pages/tables/basic-table/basic-table.component.html new file mode 100644 index 0000000..ce47718 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/basic-table/basic-table.component.html @@ -0,0 +1,344 @@ + + +

+ Top Projects + top new products +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+ Name + + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + Budget + + ${{ element.budget }}k +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ + + +

+ Best Products + Sell new products +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Product + +
+ users +
+
+ {{ element.pname }} +
+ + {{ element.category }} + +
+
+
+ Progress + + {{ element.progress }}% + + Status + + @if(element.status == 'low') { + + {{ element.status | titlecase }} + + } @if(element.status == 'medium') { + + {{ element.status | titlecase }} + + } @if(element.status == 'high') { + + {{ element.status | titlecase }} + + } @if(element.status == 'critical') { + + {{ element.status | titlecase }} + + } + + Sales + + ${{ element.sales }}k +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ + + +

+ Payment Gateways + Platform For Income +

+
+
+ + + + + + + + + + + + + + + +
+ Product + +
+ + icon + + +
+
+ {{ element.pname }} +
+ + {{ element.category }} + +
+
+
+ Price + + +${{ element.price }} +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ + + +

+ Employee of the Year + great work +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Users + +
+ user +
+
+ {{ element.name }} +
+ {{ element.post }} +
+
+
+ Project Name + + {{ element.pname }} + + Status + + + {{ element.status }} + + Budget + + ${{ element.budget }}k +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/basic-table/basic-table.component.ts b/theme/packages/main/src/app/pages/tables/basic-table/basic-table.component.ts new file mode 100644 index 0000000..5218a6d --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/basic-table/basic-table.component.ts @@ -0,0 +1,271 @@ +import { Component, OnInit } from '@angular/core'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { BreakpointObserver } from '@angular/cdk/layout'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BEST_PRODUCT_TABLE_HTML_SNIPPET, EMPLOYEE_THE_YEAR_TABLE_HTML_SNIPPET, PAYMENT_GATEWAYS_TABLE_HTML_SNIPPET, TOP_PROJECT_TABLE_HTML_SNIPPET } from './code/basic-table-html-snippet'; +import { BEST_PRODUCT_TABLE_TS_SNIPPET, EMPLOYEE_THE_YEAR_TABLE_TS_SNIPPET, PAYMENT_GATEWAYS_TABLE_TS_SNIPPET, TOP_PROJECT_TABLE_TS_SNIPPET } from './code/basic-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +// table 1 +export interface productsData { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; +} + +const PRODUCT_DATA: productsData[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low' + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium' + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high' + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical' + }, +]; + +// table 2 + +export interface performanceData { + id: number; + imagePath: string; + pname: string; + category: string; + progress: number; + sales: number; + status: string; +} + +const PROJECT_DATA: performanceData[] = [ + { + id: 1, + imagePath: 'assets/images/products/s6.jpg', + pname: 'Gaming Console', + category: 'Electronics', + progress: 78.5, + sales: 3.9, + status: 'low', + }, + { + id: 2, + imagePath: 'assets/images/products/s9.jpg', + pname: 'Leather Purse', + category: 'Fashion', + progress: 58.6, + sales: 3.5, + status: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/products/s7.jpg', + pname: 'Red Velvate Dress', + category: 'Womens Fashion', + progress: 25, + sales: 3.8, + status: 'high', + }, + { + id: 4, + imagePath: 'assets/images/products/s4.jpg', + pname: 'Headphone Boat', + category: 'Electronics', + progress: 96.3, + sales: 3.54, + status: 'critical', + }, +]; + +// table 3 + +export interface paymentData { + id: number; + color: string; + imagePath: string; + pname: string; + category: string; + price: number; +} + +const PAYMENT_DATA: paymentData[] = [ + { + id: 1, + color: 'primary', + imagePath: 'assets/images/svgs/icon-paypal.svg', + pname: 'Paypal', + category: 'Big Brands', + price: 6235, + }, + { + id: 2, + color: 'success', + imagePath: 'assets/images/svgs/icon-office-bag.svg', + pname: 'Wallet', + category: 'Bill payment', + price: 345, + }, + { + id: 3, + color: 'warning', + imagePath: 'assets/images/svgs/icon-master-card.svg', + pname: 'Credit Card', + category: 'Money reversed', + price: 2235, + }, + { + id: 4, + color: 'error', + imagePath: 'assets/images/svgs/icon-pie.svg', + pname: 'Refund', + category: 'Bill Payment', + price: 32, + }, +]; + +export interface Element { + name: string; + post: string; + imgSrc: string; + pname: string; + status: string; + color: string; + budget: string; +} + +const BASIC_DATA: Element[] = [ + { + imgSrc: 'assets/images/profile/user-1.jpg', + name: 'Micheal Doe', + post: 'Web Designer', + pname: 'Elite Admin', + status: 'Active', + color: 'success', + budget: '3.9' + }, + { + imgSrc: 'assets/images/profile/user-2.jpg', + name: 'Andrew McDownland', + post: 'Project Manager', + pname: 'Real Homes WP Theme', + status: 'Pending', + color: 'warning', + budget: '3.9' + }, + { + imgSrc: 'assets/images/profile/user-3.jpg', + name: 'Christopher Jamil', + post: 'Frontend Engineer', + pname: 'MedicalPro WP Theme', + status: 'Cancel', + color: 'error', + budget: '3.9' + }, + { + imgSrc: 'assets/images/profile/user-4.jpg', + name: 'Mathew Anderson', + post: 'Content Writer', + pname: 'Hosting Press HTML', + status: 'Completed', + color: 'primary', + budget: '3.9' + }, +]; + + +@Component({ + selector: 'app-basic-table', + imports: [MatTableModule, CommonModule, MatCardModule, MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './basic-table.component.html' +}) +export class AppBasicTableComponent implements OnInit { + + // 1 [Top Projects with Table] + codeForTopProjects = TOP_PROJECT_TABLE_HTML_SNIPPET; + codeForTopProjectsTs = TOP_PROJECT_TABLE_TS_SNIPPET; + + // 2 [Best Product with Table] + codeForBestProduct = BEST_PRODUCT_TABLE_HTML_SNIPPET; + codeForBestProductTs = BEST_PRODUCT_TABLE_TS_SNIPPET; + + // 3 [Payment Gateways with Table] + codeForPaymentGateways = PAYMENT_GATEWAYS_TABLE_HTML_SNIPPET; + codeForPaymentGatewaysTs = PAYMENT_GATEWAYS_TABLE_TS_SNIPPET; + + // 4 [Employee The Year with Table] + codeForEmployeeTheYear = EMPLOYEE_THE_YEAR_TABLE_HTML_SNIPPET; + codeForEmployeeTheYearTs = EMPLOYEE_THE_YEAR_TABLE_TS_SNIPPET; + + // table 4 + + displayedColumns4 = ['name', 'pname', 'status', 'budget']; + dataSource4 = new MatTableDataSource(BASIC_DATA); + + constructor(breakpointObserver: BreakpointObserver) { + breakpointObserver.observe(['(max-width: 600px)']).subscribe((result) => { + this.displayedColumns4 = result.matches + ? ['name', 'pname', 'status', 'budget'] + : ['name', 'pname', 'status', 'budget']; + }); + } + + // table 1 + displayedColumns1: string[] = ['assigned', 'name', 'priority', 'budget']; + dataSource1 = PRODUCT_DATA; + + // table 2 + displayedColumns2: string[] = ['product', 'progress', 'status', 'sales']; + dataSource2 = PROJECT_DATA; + + // table 3 + displayedColumns3: string[] = ['product', 'price']; + dataSource3 = PAYMENT_DATA; + + ngOnInit(): void {} +} + + diff --git a/theme/packages/main/src/app/pages/tables/basic-table/code/basic-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/basic-table/code/basic-table-html-snippet.ts new file mode 100644 index 0000000..d76afc0 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/basic-table/code/basic-table-html-snippet.ts @@ -0,0 +1,252 @@ +export const TOP_PROJECT_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+ Name + + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + Budget + + {{ element.budget }}k +
+
+`; + +export const BEST_PRODUCT_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Product + +
+ users +
+
+ {{ element.pname }} +
+ + {{ element.category }} + +
+
+
+ Progress + + {{ element.progress }}% + + Status + + @if(element.status == 'low') { + + {{ element.status | titlecase }} + + } @if(element.status == 'medium') { + + {{ element.status | titlecase }} + + } @if(element.status == 'high') { + + {{ element.status | titlecase }} + + } @if(element.status == 'critical') { + + {{ element.status | titlecase }} + + } + + Sales + + {{ element.sales }}k +
+
+`; + +export const PAYMENT_GATEWAYS_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + +
+ Product + +
+ + icon + + +
+
+ {{ element.pname }} +
+ + {{ element.category }} + +
+
+
+ Price + + +{{ element.price }} +
+
+`; + +export const EMPLOYEE_THE_YEAR_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Users + +
+ user +
+
+ {{ element.name }} +
+ {{ element.post }} +
+
+
+ Project Name + + {{ element.pname }} + + Status + + + {{ element.status }} + + Budget + + {{ element.budget }}k +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/basic-table/code/basic-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/basic-table/code/basic-table-ts-snippet.ts new file mode 100644 index 0000000..bc43c1f --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/basic-table/code/basic-table-ts-snippet.ts @@ -0,0 +1,283 @@ +export const TOP_PROJECT_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { MatTableModule } from '@angular/material/table'; + import { CommonModule } from '@angular/common'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface productsData { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; + } + + const PRODUCT_DATA: productsData[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low' + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium' + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high' + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical' + }, + ]; + + /** + * @title basic table */ + */ + @Component({ + selector: 'app-basic-table', + imports: [MatTableModule, CommonModule, MatCardModule, MatDividerModule,], + templateUrl: './basic-table.component.html' + }) + export class AppBasicTableComponent { + + displayedColumns1: string[] = ['assigned', 'name', 'priority', 'budget']; + dataSource1 = PRODUCT_DATA; + + } +`; + +export const BEST_PRODUCT_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { MatTableModule } from '@angular/material/table'; + import { CommonModule } from '@angular/common'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface performanceData { + id: number; + imagePath: string; + pname: string; + category: string; + progress: number; + sales: number; + status: string; + } + + const PROJECT_DATA: performanceData[] = [ + { + id: 1, + imagePath: 'assets/images/products/s6.jpg', + pname: 'Gaming Console', + category: 'Electronics', + progress: 78.5, + sales: 3.9, + status: 'low', + }, + { + id: 2, + imagePath: 'assets/images/products/s9.jpg', + pname: 'Leather Purse', + category: 'Fashion', + progress: 58.6, + sales: 3.5, + status: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/products/s7.jpg', + pname: 'Red Velvate Dress', + category: 'Womens Fashion', + progress: 25, + sales: 3.8, + status: 'high', + }, + { + id: 4, + imagePath: 'assets/images/products/s4.jpg', + pname: 'Headphone Boat', + category: 'Electronics', + progress: 96.3, + sales: 3.54, + status: 'critical', + }, + ]; + + /** + * @title basic table */ + */ + @Component({ + selector: 'app-basic-table', + imports: [MatTableModule, CommonModule, MatCardModule, MatDividerModule,], + templateUrl: './basic-table.component.html' + }) + export class AppBasicTableComponent { + + displayedColumns2: string[] = ['product', 'progress', 'status', 'sales']; + dataSource2 = PROJECT_DATA; + + } +`; + +export const PAYMENT_GATEWAYS_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { MatTableModule } from '@angular/material/table'; + import { CommonModule } from '@angular/common'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface paymentData { + id: number; + color: string; + imagePath: string; + pname: string; + category: string; + price: number; + } + + const PAYMENT_DATA: paymentData[] = [ + { + id: 1, + color: 'primary', + imagePath: 'assets/images/svgs/icon-paypal.svg', + pname: 'Paypal', + category: 'Big Brands', + price: 6235, + }, + { + id: 2, + color: 'success', + imagePath: 'assets/images/svgs/icon-office-bag.svg', + pname: 'Wallet', + category: 'Bill payment', + price: 345, + }, + { + id: 3, + color: 'warning', + imagePath: 'assets/images/svgs/icon-master-card.svg', + pname: 'Credit Card', + category: 'Money reversed', + price: 2235, + }, + { + id: 4, + color: 'error', + imagePath: 'assets/images/svgs/icon-pie.svg', + pname: 'Refund', + category: 'Bill Payment', + price: 32, + }, + ]; + + /** + * @title basic table */ + */ + @Component({ + selector: 'app-basic-table', + imports: [MatTableModule, CommonModule, MatCardModule, MatDividerModule,], + templateUrl: './basic-table.component.html' + }) + export class AppBasicTableComponent { + + displayedColumns3: string[] = ['product', 'price']; + dataSource3 = PAYMENT_DATA; + + } +`; + +export const EMPLOYEE_THE_YEAR_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { MatTableDataSource, MatTableModule } from '@angular/material/table'; + import { BreakpointObserver } from '@angular/cdk/layout'; + import { CommonModule } from '@angular/common'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface Element { + name: string; + post: string; + imgSrc: string; + pname: string; + status: string; + color: string; + budget: string; + } + + const BASIC_DATA: Element[] = [ + { + imgSrc: 'assets/images/profile/user-1.jpg', + name: 'Micheal Doe', + post: 'Web Designer', + pname: 'Elite Admin', + status: 'Active', + color: 'success', + budget: '3.9' + }, + { + imgSrc: 'assets/images/profile/user-2.jpg', + name: 'Andrew McDownland', + post: 'Project Manager', + pname: 'Real Homes WP Theme', + status: 'Pending', + color: 'warning', + budget: '3.9' + }, + { + imgSrc: 'assets/images/profile/user-3.jpg', + name: 'Christopher Jamil', + post: 'Frontend Engineer', + pname: 'MedicalPro WP Theme', + status: 'Cancel', + color: 'error', + budget: '3.9' + }, + { + imgSrc: 'assets/images/profile/user-4.jpg', + name: 'Mathew Anderson', + post: 'Content Writer', + pname: 'Hosting Press HTML', + status: 'Completed', + color: 'primary', + budget: '3.9' + }, + ]; + + /** + * @title basic table */ + */ + @Component({ + selector: 'app-basic-table', + imports: [MatTableModule, CommonModule, MatCardModule, MatDividerModule,], + templateUrl: './basic-table.component.html' + }) + export class AppBasicTableComponent { + + displayedColumns4 = ['name', 'pname', 'status', 'budget']; + dataSource4 = new MatTableDataSource(BASIC_DATA); + + constructor(breakpointObserver: BreakpointObserver) { + breakpointObserver.observe(['(max-width: 600px)']).subscribe((result) => { + this.displayedColumns4 = result.matches + ? ['name', 'pname', 'status', 'budget'] + : ['name', 'pname', 'status', 'budget']; + }); + } + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/dynamic-table/code/dynamic-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/dynamic-table/code/dynamic-table-html-snippet.ts new file mode 100644 index 0000000..d7144d0 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/dynamic-table/code/dynamic-table-html-snippet.ts @@ -0,0 +1,30 @@ +export const DYNAMIC_TABLE_HTML_SNIPPET = `
+ + + +
+ +
+ + @for(column of displayedColumns; track column) { + + + + + } + + + +
+ {{ column | titlecase }} + + {{ element[column] }} +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/dynamic-table/code/dynamic-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/dynamic-table/code/dynamic-table-ts-snippet.ts new file mode 100644 index 0000000..1588518 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/dynamic-table/code/dynamic-table-ts-snippet.ts @@ -0,0 +1,68 @@ +export const DYNAMIC_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { MatTableModule } from '@angular/material/table'; + import { CommonModule } from '@angular/common'; + import { MatButtonModule } from '@angular/material/button'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface PeriodicElement { + name: string; + position: number; + weight: number; + symbol: string; + } + + const ELEMENT_DATA: PeriodicElement[] = [ + { position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' }, + { position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' }, + { position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' }, + { position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be' }, + { position: 5, name: 'Boron', weight: 10.811, symbol: 'B' }, + { position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C' }, + { position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N' }, + { position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O' }, + { position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F' }, + { position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne' }, + ]; + + /** + * @title dynamic table */ + */ + @Component({ + selector: 'app-dynamic-table', + imports: [MatTableModule, MatCardModule, CommonModule, MatButtonModule], + templateUrl: './dynamic-table.component.html' + }) + export class AppDynamicTableComponent { + + displayedColumns: string[] = ['name', 'weight', 'symbol', 'position']; + columnsToDisplay: string[] = this.displayedColumns.slice(); + data: PeriodicElement[] = ELEMENT_DATA; + + addColumn(): void { + const randomColumn = Math.floor( + Math.random() * this.displayedColumns.length + ); + this.columnsToDisplay.push(this.displayedColumns[randomColumn]); + } + + removeColumn(): void { + if (this.columnsToDisplay.length) { + this.columnsToDisplay.pop(); + } + } + + shuffle(): void { + let currentIndex = this.columnsToDisplay.length; + while (0 !== currentIndex) { + const randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + + // Swap + const temp = this.columnsToDisplay[currentIndex]; + this.columnsToDisplay[currentIndex] = this.columnsToDisplay[randomIndex]; + this.columnsToDisplay[randomIndex] = temp; + } + } + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/dynamic-table/dynamic-table.component.html b/theme/packages/main/src/app/pages/tables/dynamic-table/dynamic-table.component.html new file mode 100644 index 0000000..8437760 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/dynamic-table/dynamic-table.component.html @@ -0,0 +1,53 @@ + + +

+ Table dynamically changing the columns displayed + add column dynamically +

+
+
+ + + +
+ +
+ + @for(column of displayedColumns; track column) { + + + + + } + + + +
+ {{ column | titlecase }} + + {{ element[column] }} +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/dynamic-table/dynamic-table.component.ts b/theme/packages/main/src/app/pages/tables/dynamic-table/dynamic-table.component.ts new file mode 100644 index 0000000..d36e200 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/dynamic-table/dynamic-table.component.ts @@ -0,0 +1,84 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatTableModule } from '@angular/material/table'; +import { MatCardModule } from '@angular/material/card'; +import { MatButtonModule } from '@angular/material/button'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { DYNAMIC_TABLE_HTML_SNIPPET } from './code/dynamic-table-html-snippet'; +import { DYNAMIC_TABLE_TS_SNIPPET } from './code/dynamic-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +export interface PeriodicElement { + name: string; + position: number; + weight: number; + symbol: string; +} + +const ELEMENT_DATA: PeriodicElement[] = [ + { position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' }, + { position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' }, + { position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' }, + { position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be' }, + { position: 5, name: 'Boron', weight: 10.811, symbol: 'B' }, + { position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C' }, + { position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N' }, + { position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O' }, + { position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F' }, + { position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne' }, +]; + +@Component({ + selector: 'app-dynamic-table', + imports: [MatTableModule, MatCardModule, CommonModule, MatButtonModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './dynamic-table.component.html' +}) +export class AppDynamicTableComponent implements OnInit { + // 1 [Top Projects with Table] + codeForDynamicTable = DYNAMIC_TABLE_HTML_SNIPPET; + codeForDynamicTableTs = DYNAMIC_TABLE_TS_SNIPPET; + + + displayedColumns: string[] = ['name', 'weight', 'symbol', 'position']; + columnsToDisplay: string[] = this.displayedColumns.slice(); + data: PeriodicElement[] = ELEMENT_DATA; + + addColumn(): void { + const randomColumn = Math.floor( + Math.random() * this.displayedColumns.length + ); + this.columnsToDisplay.push(this.displayedColumns[randomColumn]); + } + + removeColumn(): void { + if (this.columnsToDisplay.length) { + this.columnsToDisplay.pop(); + } + } + + shuffle(): void { + let currentIndex = this.columnsToDisplay.length; + while (0 !== currentIndex) { + const randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + + // Swap + const temp = this.columnsToDisplay[currentIndex]; + this.columnsToDisplay[currentIndex] = this.columnsToDisplay[randomIndex]; + this.columnsToDisplay[randomIndex] = temp; + } + } + + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/tables/expand-table/code/expand-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/expand-table/code/expand-table-html-snippet.ts new file mode 100644 index 0000000..994b968 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/expand-table/code/expand-table-html-snippet.ts @@ -0,0 +1,68 @@ +export const EXPAND_TABLE_HTML_SNIPPET = `
+ + @for(column of columnsToDisplay; track column) { + + + + + } + + + + + + + + + + + + + + +
+ {{ column | titlecase }} + + {{ element[column] }} + +   + + + +
+
+
+ + {{ element.symbol }} + +
+
+ {{ element.name }} +
+
{{ element.project }}
+
+
+ +
+ {{ element.description }} +
+
+
+
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/expand-table/code/expand-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/expand-table/code/expand-table-ts-snippet.ts new file mode 100644 index 0000000..56f37fe --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/expand-table/code/expand-table-ts-snippet.ts @@ -0,0 +1,159 @@ +export const EXPAND_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { animate, state, style, transition, trigger} from '@angular/animations'; + import { CommonModule } from '@angular/common'; + import { MatCardModule } from '@angular/material/card'; + import { MatTableModule } from '@angular/material/table'; + import { MatIconModule } from '@angular/material/icon'; + import { MatButtonModule } from '@angular/material/button'; + import { MatDividerModule } from '@angular/material/divider'; + + + export interface PeriodicElement { + name: string; + position: string; + id: number; + project: string; + symbol: string; + description: string; + } + + const ELEMENT_DATA: PeriodicElement[] = [ + { + id: 1, + position: 'Front end Developer', + name: 'Andrew McDownland', + project: 'Elite Admin', + symbol: 'H', + description: 'Hydrogen is a chemical element with symbol H and atomic number 1. With a standard + atomic weight of 1.008, hydrogen is the lightest element on the periodic table.', + }, + { + id: 2, + position: 'Web Designer', + name: 'Helium', + project: 'Real Homes Theme', + symbol: 'He', + description: 'Helium is a chemical element with symbol He and atomic number 2. It is a + colorless, odorless, tasteless, non-toxic, inert, monatomic gas, the first in the noble gas + group in the periodic table. Its boiling point is the lowest among all the elements.', + }, + { + id: 3, + position: 'Project Manager', + name: 'Lithium', + project: 'MedicalPro Theme', + symbol: 'Li', + description: 'Lithium is a chemical element with symbol Li and atomic number 3. It is a soft, + silvery-white alkali metal. Under standard conditions, it is the lightest metal and the + lightest solid element.', + }, + { + id: 4, + position: 'Medical Assistant', + name: 'Beryllium', + project: 'Hosting Press HTML ', + symbol: 'Be', + description: 'Beryllium is a chemical element with symbol Be and atomic number 4. It is a + relatively rare element in the universe, usually occurring as a product of the spallation of + larger atomic nuclei that have collided with cosmic rays.', + }, + { + id: 5, + position: 'Librarian', + name: 'Boron', + project: 'Flexy Admin', + symbol: 'B', + description: 'Boron is a chemical element with symbol B and atomic number 5. Produced entirely + by cosmic ray spallation and supernovae and not by stellar nucleosynthesis, it is a + low-abundance element in the Solar system and in the Earth's crust.', + }, + { + id: 6, + position: 'Account Executive', + name: 'Carbon', + project: 'Ample Admin', + symbol: 'C', + description: 'Carbon is a chemical element with symbol C and atomic number 6. It is nonmetallic + and tetravalent—making four electrons available to form covalent chemical bonds. It belongs + to group 14 of the periodic table.', + }, + { + id: 7, + position: 'President of Sales', + name: 'Nitrogen', + project: 'Modernize Admin', + symbol: 'N', + description: 'Nitrogen is a chemical element with symbol N and atomic number 7. It was first + discovered and isolated by Scottish physician Daniel Rutherford in 1772.', + }, + { + id: 8, + position: 'Dog Trainer', + name: 'Oxygen', + project: 'MaterialPro Admin', + symbol: 'O', + description: 'Oxygen is a chemical element with symbol O and atomic number 8. It is a member of + the chalcogen group on the periodic table, a highly reactive nonmetal, and an oxidizing + agent that readily forms oxides with most elements as well as with other compounds.', + }, + { + id: 9, + position: 'Web Designer', + name: 'Fluorine', + project: 'Adminpro Admin', + symbol: 'F', + description: 'Fluorine is a chemical element with symbol F and atomic number 9. It is the + lightest halogen and exists as a highly toxic pale yellow diatomic gas at standard + conditions.', + }, + { + id: 10, + position: 'Account Executive', + name: 'Neon', + project: 'SEO Debate', + symbol: 'Ne', + description: 'Neon is a chemical element with symbol Ne and atomic number 10. It is a noble gas. + Neon is a colorless, odorless, inert monatomic gas under standard conditions, with about + two-thirds the density of air.', + }, + ]; + + /** + * @title expand table */ + */ + @Component({ + selector: 'app-expand-table', + imports: [ + MatCardModule, + MatTableModule, + MatIconModule, + MatButtonModule, + CommonModule, + MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './expand-table.component.html', + styleUrls: ['./expand-table.component.scss'], + animations: [ + trigger('detailExpand', [ + state('collapsed', style({ height: '0px', minHeight: '0' })), + state('expanded', style({ height: '*' })), + transition( + 'expanded <=> collapsed', + animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)') + ), + ]), + ], + }) + export class AppExpandTableComponent { + + dataSource = ELEMENT_DATA; + columnsToDisplay = ['id', 'name', 'project', 'symbol', 'position']; + columnsToDisplayWithExpand = [...this.columnsToDisplay, 'expand']; + expandedElement: PeriodicElement | null = null; + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/expand-table/expand-table.component.html b/theme/packages/main/src/app/pages/tables/expand-table/expand-table.component.html new file mode 100644 index 0000000..15a3385 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/expand-table/expand-table.component.html @@ -0,0 +1,91 @@ + + +

+ Table with expandable rows + expandable rows here +

+
+
+ + @for(column of columnsToDisplay; track column) { + + + + + } + + + + + + + + + + + + + + +
+ {{ column | titlecase }} + + {{ element[column] }} + +   + + + +
+
+
+ + {{ element.symbol }} + +
+
+ {{ element.name }} +
+
{{ element.project }}
+
+
+ +
+ {{ element.description }} +
+
+
+
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/expand-table/expand-table.component.scss b/theme/packages/main/src/app/pages/tables/expand-table/expand-table.component.scss new file mode 100644 index 0000000..2f23983 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/expand-table/expand-table.component.scss @@ -0,0 +1,20 @@ +table { + width: 100%; +} + +tr.example-detail-row { + height: 0; + +} + +// tr.example-element-row:not(.example-expanded-row):hover { +// background: whitesmoke; +// } + +// tr.example-element-row:not(.example-expanded-row):active { +// background: #efefef; +// } + +.example-element-row td { + border-bottom-width: 0; +} diff --git a/theme/packages/main/src/app/pages/tables/expand-table/expand-table.component.ts b/theme/packages/main/src/app/pages/tables/expand-table/expand-table.component.ts new file mode 100644 index 0000000..52d04ac --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/expand-table/expand-table.component.ts @@ -0,0 +1,177 @@ +import { Component, OnInit } from '@angular/core'; +import { + animate, + state, + style, + transition, + trigger, +} from '@angular/animations'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatTableModule } from '@angular/material/table'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { EXPAND_TABLE_HTML_SNIPPET } from './code/expand-table-html-snippet'; +import { EXPAND_TABLE_TS_SNIPPET } from './code/expand-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +const ELEMENT_DATA: PeriodicElement[] = [ + { + id: 1, + position: 'Front end Developer', + name: 'Andrew McDownland', + project: 'Elite Admin', + symbol: 'H', + description: `Hydrogen is a chemical element with symbol H and atomic number 1. With a standard + atomic weight of 1.008, hydrogen is the lightest element on the periodic table.`, + }, + { + id: 2, + position: 'Web Designer', + name: 'Helium', + project: 'Real Homes Theme', + symbol: 'He', + description: `Helium is a chemical element with symbol He and atomic number 2. It is a + colorless, odorless, tasteless, non-toxic, inert, monatomic gas, the first in the noble gas + group in the periodic table. Its boiling point is the lowest among all the elements.`, + }, + { + id: 3, + position: 'Project Manager', + name: 'Lithium', + project: 'MedicalPro Theme', + symbol: 'Li', + description: `Lithium is a chemical element with symbol Li and atomic number 3. It is a soft, + silvery-white alkali metal. Under standard conditions, it is the lightest metal and the + lightest solid element.`, + }, + { + id: 4, + position: 'Medical Assistant', + name: 'Beryllium', + project: 'Hosting Press HTML ', + symbol: 'Be', + description: `Beryllium is a chemical element with symbol Be and atomic number 4. It is a + relatively rare element in the universe, usually occurring as a product of the spallation of + larger atomic nuclei that have collided with cosmic rays.`, + }, + { + id: 5, + position: 'Librarian', + name: 'Boron', + project: 'Flexy Admin', + symbol: 'B', + description: `Boron is a chemical element with symbol B and atomic number 5. Produced entirely + by cosmic ray spallation and supernovae and not by stellar nucleosynthesis, it is a + low-abundance element in the Solar system and in the Earth's crust.`, + }, + { + id: 6, + position: 'Account Executive', + name: 'Carbon', + project: 'Ample Admin', + symbol: 'C', + description: `Carbon is a chemical element with symbol C and atomic number 6. It is nonmetallic + and tetravalent—making four electrons available to form covalent chemical bonds. It belongs + to group 14 of the periodic table.`, + }, + { + id: 7, + position: 'President of Sales', + name: 'Nitrogen', + project: 'Modernize Admin', + symbol: 'N', + description: `Nitrogen is a chemical element with symbol N and atomic number 7. It was first + discovered and isolated by Scottish physician Daniel Rutherford in 1772.`, + }, + { + id: 8, + position: 'Dog Trainer', + name: 'Oxygen', + project: 'MaterialPro Admin', + symbol: 'O', + description: `Oxygen is a chemical element with symbol O and atomic number 8. It is a member of + the chalcogen group on the periodic table, a highly reactive nonmetal, and an oxidizing + agent that readily forms oxides with most elements as well as with other compounds.`, + }, + { + id: 9, + position: 'Web Designer', + name: 'Fluorine', + project: 'Adminpro Admin', + symbol: 'F', + description: `Fluorine is a chemical element with symbol F and atomic number 9. It is the + lightest halogen and exists as a highly toxic pale yellow diatomic gas at standard + conditions.`, + }, + { + id: 10, + position: 'Account Executive', + name: 'Neon', + project: 'SEO Debate', + symbol: 'Ne', + description: `Neon is a chemical element with symbol Ne and atomic number 10. It is a noble gas. + Neon is a colorless, odorless, inert monatomic gas under standard conditions, with about + two-thirds the density of air.`, + }, +]; + +@Component({ + selector: 'app-expand-table', + imports: [ + MatCardModule, + MatTableModule, + MatIconModule, + MatButtonModule, + CommonModule, + MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './expand-table.component.html', + styleUrls: ['./expand-table.component.scss'], + animations: [ + trigger('detailExpand', [ + state('collapsed', style({ height: '0px', minHeight: '0' })), + state('expanded', style({ height: '*' })), + transition( + 'expanded <=> collapsed', + animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)') + ), + ]), + ], +}) +export class AppExpandTableComponent implements OnInit { + + // 1 [expand with Table] + codeForExpandTable = EXPAND_TABLE_HTML_SNIPPET; + codeForExpandTableTs = EXPAND_TABLE_TS_SNIPPET; + + + dataSource = ELEMENT_DATA; + columnsToDisplay = ['id', 'name', 'project', 'symbol', 'position']; + columnsToDisplayWithExpand = [...this.columnsToDisplay, 'expand']; + expandedElement: PeriodicElement | null = null; + + constructor() {} + + ngOnInit(): void {} +} + +export interface PeriodicElement { + name: string; + position: string; + id: number; + project: string; + symbol: string; + description: string; +} diff --git a/theme/packages/main/src/app/pages/tables/filterable-table/code/filterable-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/filterable-table/code/filterable-table-html-snippet.ts new file mode 100644 index 0000000..cdb2ed4 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/filterable-table/code/filterable-table-html-snippet.ts @@ -0,0 +1,97 @@ +export const FILTERABLE_TABLE_HTML_SNIPPET = ` Filter + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+ Name + + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + Budget + + {{ element.budget }}k +
+ No data matching the filter "{{ input.value }}" +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/filterable-table/code/filterable-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/filterable-table/code/filterable-table-ts-snippet.ts new file mode 100644 index 0000000..4aff099 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/filterable-table/code/filterable-table-ts-snippet.ts @@ -0,0 +1,90 @@ +export const FILTERABLE_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { MatTableDataSource, MatTableModule } from '@angular/material/table'; + import { CommonModule } from '@angular/common'; + import { MatCardModule } from '@angular/material/card'; + import { MatFormFieldModule } from '@angular/material/form-field'; + import { MatInputModule } from '@angular/material/input'; + import { MatDividerModule } from '@angular/material/divider'; + + + export interface productsData { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; + } + + const ELEMENT_DATA: productsData[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + ]; + + /** + * @title expand table */ + */ + @Component({ + selector: 'app-expand-table', + selector: 'app-filterable-table', + imports: [ + MatTableModule, + MatCardModule, + MatFormFieldModule, + CommonModule, + MatInputModule, + MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './filterable-table.component.html', + }) + export class AppFilterableTableComponent { + + displayedColumns: string[] = ['assigned', 'name', 'priority', 'budget']; + dataSource = new MatTableDataSource(ELEMENT_DATA); + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/filterable-table/filterable-table.component.html b/theme/packages/main/src/app/pages/tables/filterable-table/filterable-table.component.html new file mode 100644 index 0000000..f9ab44c --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/filterable-table/filterable-table.component.html @@ -0,0 +1,121 @@ + +

+ Filterable table + search your items +

+ +
+ + Filter + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+ Name + + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + Budget + + ${{ element.budget }}k +
+ No data matching the filter "{{ input.value }}" +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/filterable-table/filterable-table.component.ts b/theme/packages/main/src/app/pages/tables/filterable-table/filterable-table.component.ts new file mode 100644 index 0000000..59191e9 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/filterable-table/filterable-table.component.ts @@ -0,0 +1,99 @@ +import { Component, OnInit } from '@angular/core'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { FILTERABLE_TABLE_HTML_SNIPPET } from './code/filterable-table-html-snippet'; +import { FILTERABLE_TABLE_TS_SNIPPET } from './code/filterable-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +export interface productsData { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; +} + +const ELEMENT_DATA: productsData[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, +]; + +@Component({ + selector: 'app-filterable-table', + imports: [ + MatTableModule, + MatCardModule, + MatFormFieldModule, + CommonModule, + MatInputModule, + MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './filterable-table.component.html', +}) +export class AppFilterableTableComponent implements OnInit { + // 1 [Filterable with Table] + codeForFilterableTable = FILTERABLE_TABLE_HTML_SNIPPET; + codeForFilterableTableTs = FILTERABLE_TABLE_TS_SNIPPET; + + displayedColumns: string[] = ['assigned', 'name', 'priority', 'budget']; + dataSource = new MatTableDataSource(ELEMENT_DATA); + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/tables/footer-row-table/code/footer-row-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/footer-row-table/code/footer-row-table-html-snippet.ts new file mode 100644 index 0000000..41e61f0 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/footer-row-table/code/footer-row-table-html-snippet.ts @@ -0,0 +1,35 @@ +export const FOOTER_ROW_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + + + + +
+ Item + +
+ product + {{ transaction.item }} +
+
Total + Cost + + {{ transaction.cost | currency }} + + {{ getTotalCost() | currency }} +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/footer-row-table/code/footer-row-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/footer-row-table/code/footer-row-table-ts-snippet.ts new file mode 100644 index 0000000..94b0627 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/footer-row-table/code/footer-row-table-ts-snippet.ts @@ -0,0 +1,87 @@ +export const FOOTER_ROW_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { CommonModule } from '@angular/common'; + import { MatTableModule } from '@angular/material/table'; + import { MatCardModule } from '@angular/material/card'; + import { MatDividerModule } from '@angular/material/divider'; + + + export interface Transaction { + item: string; + img: string; + cost: number; + } + + const ELEMENT_DATA: productsData[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + ]; + + /** + * @title expand table */ + */ + @Component({ + selector: 'app-footer-row-table', + imports: [MatTableModule, MatCardModule, CommonModule, MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './footer-row-table.component.html', + styleUrls: ['./footer-row-table.component.scss'], + }) + export class AppFooterRowTableComponent { + + displayedColumns: string[] = ['item', 'cost']; + transactions: Transaction[] = [ + { img: '/assets/images/products/s1.jpg', item: 'Beach ball', cost: 4 }, + { img: '/assets/images/products/s2.jpg', item: 'Towel', cost: 5 }, + { img: '/assets/images/products/s3.jpg', item: 'Frisbee', cost: 2 }, + { img: '/assets/images/products/s4.jpg', item: 'Sunscreen', cost: 4 }, + { img: '/assets/images/products/s5.jpg', item: 'Cooler', cost: 25 }, + { img: '/assets/images/products/s6.jpg', item: 'Swim suit', cost: 15 }, + ]; + + /** Gets the total cost of all transactions. */ + getTotalCost() { + return this.transactions + .map((t) => t.cost) + .reduce((acc, value) => acc + value, 0); + } + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/footer-row-table/footer-row-table.component.html b/theme/packages/main/src/app/pages/tables/footer-row-table/footer-row-table.component.html new file mode 100644 index 0000000..e46ef69 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/footer-row-table/footer-row-table.component.html @@ -0,0 +1,58 @@ + + +

+ Footer Row table + total is avail at footer +

+
+
+ + + + + + + + + + + + + + + + + + +
+ Item + +
+ product + {{ transaction.item }} +
+
Total + Cost + + {{ transaction.cost | currency }} + + {{ getTotalCost() | currency }} +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/footer-row-table/footer-row-table.component.scss b/theme/packages/main/src/app/pages/tables/footer-row-table/footer-row-table.component.scss new file mode 100644 index 0000000..04787d8 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/footer-row-table/footer-row-table.component.scss @@ -0,0 +1,3 @@ +tr.mat-footer-row { + font-weight: bold; + } \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/footer-row-table/footer-row-table.component.ts b/theme/packages/main/src/app/pages/tables/footer-row-table/footer-row-table.component.ts new file mode 100644 index 0000000..d40107e --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/footer-row-table/footer-row-table.component.ts @@ -0,0 +1,59 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatTableModule } from '@angular/material/table'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { FOOTER_ROW_TABLE_HTML_SNIPPET } from './code/footer-row-table-html-snippet'; +import { FOOTER_ROW_TABLE_TS_SNIPPET } from './code/footer-row-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +export interface Transaction { + item: string; + img: string; + cost: number; +} +@Component({ + selector: 'app-footer-row-table', + imports: [MatTableModule, MatCardModule, CommonModule, MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './footer-row-table.component.html', + styleUrls: ['./footer-row-table.component.scss'], +}) +export class AppFooterRowTableComponent implements OnInit { + // 1 [Footer Row with Table] + codeForFooterRowTable = FOOTER_ROW_TABLE_HTML_SNIPPET; + codeForFooterRowTableTs = FOOTER_ROW_TABLE_TS_SNIPPET; + + + displayedColumns: string[] = ['item', 'cost']; + transactions: Transaction[] = [ + { img: '/assets/images/products/s1.jpg', item: 'Beach ball', cost: 4 }, + { img: '/assets/images/products/s2.jpg', item: 'Towel', cost: 5 }, + { img: '/assets/images/products/s3.jpg', item: 'Frisbee', cost: 2 }, + { img: '/assets/images/products/s4.jpg', item: 'Sunscreen', cost: 4 }, + { img: '/assets/images/products/s5.jpg', item: 'Cooler', cost: 25 }, + { img: '/assets/images/products/s6.jpg', item: 'Swim suit', cost: 15 }, + ]; + + /** Gets the total cost of all transactions. */ + getTotalCost() { + return this.transactions + .map((t) => t.cost) + .reduce((acc, value) => acc + value, 0); + } + + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/tables/http-table/code/http-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/http-table/code/http-table-html-snippet.ts new file mode 100644 index 0000000..d601687 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/http-table/code/http-table-html-snippet.ts @@ -0,0 +1,68 @@ +export const HTTP_TABLE_HTML_SNIPPET = `
+ @if(isLoadingResults || isRateLimitReached) { +
+ @if(isLoadingResults) { + + } @if(isRateLimitReached) { +
+ GitHub's API rate limit has been reached. It will be reset in one + minute. +
+ } +
+ } + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ # + {{ row.number }} + Title + + {{ row.title.slice(0, 50) }}... + + State + + + {{ row.state }} + + + Created + +
+ {{ row.created_at | date }} +
+
+
+ + +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/http-table/code/http-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/http-table/code/http-table-ts-snippet.ts new file mode 100644 index 0000000..a6dba26 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/http-table/code/http-table-ts-snippet.ts @@ -0,0 +1,117 @@ +export const HTTP_TABLE_TS_SNIPPET = ` import { HttpClient } from '@angular/common/http'; + import { Component, ViewChild } from '@angular/core'; + import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; + import { MatSort, MatSortModule } from '@angular/material/sort'; + import { merge, Observable, of as observableOf } from 'rxjs'; + import { catchError, map, startWith, switchMap } from 'rxjs/operators'; + import { CommonModule } from '@angular/common'; + import { TablerIconsModule } from 'angular-tabler-icons'; + import { MatTableModule } from '@angular/material/table'; + import { MatCardModule } from '@angular/material/card'; + import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; + import { MatDividerModule } from '@angular/material/divider'; + + + export interface GithubApi { + items: GithubIssue[]; + total_count: number; + } + + export interface GithubIssue { + created_at: string; + number: string; + state: string; + title: string; + } + + /** An example database that the data source uses to retrieve data for the table. */ + export class ExampleHttpDatabase { + // tslint:disable-next-line - Disables all + constructor(private _httpClient: HttpClient) {} + + getRepoIssues( + sort: string, + order: string, + page: number + ): Observable { + const href = 'https://api.github.com/search/issues'; + const requestUrl = {href}?q=repo:angular/components&sort={sort}&order={order}&page={ + page + 1 + }; + + return this._httpClient.get(requestUrl); + } + } + + /** + * @title expand table */ + */ + @Component({ + selector: 'app-footer-row-table', + selector: 'app-http-table', + imports: [ + MatTableModule, + MatCardModule, + MatPaginatorModule, + MatProgressSpinnerModule, + CommonModule, + TablerIconsModule, + MatSortModule, + MatDividerModule, + ], + templateUrl: './http-table.component.html', + styleUrls: ['./http-table.component.scss'], + }) + export class AppHttpTableComponent { + + displayedColumns: string[] = ['created', 'state', 'number', 'title']; + exampleDatabase: ExampleHttpDatabase | null = null; + data: GithubIssue[] = []; + + resultsLength = 0; + isLoadingResults = true; + isRateLimitReached = false; + + @ViewChild(MatPaginator) paginator: MatPaginator = Object.create(null); + @ViewChild(MatSort) sort: MatSort = Object.create(null); + // tslint:disable-next-line - Disables all + constructor(private _httpClient: HttpClient) {} + + ngAfterViewInit(): void { + this.exampleDatabase = new ExampleHttpDatabase(this._httpClient); + + // If the user changes the sort order, reset back to the first page. + this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); + + merge(this.sort.sortChange, this.paginator.page) + .pipe( + startWith({}), + switchMap(() => { + this.isLoadingResults = true; + // tslint:disable-next-line - Disables all + return this.exampleDatabase!.getRepoIssues( + this.sort.active, + this.sort.direction, + this.paginator.pageIndex + ); + }), + map((data) => { + // Flip flag to show that loading has finished. + this.isLoadingResults = false; + this.isRateLimitReached = false; + this.resultsLength = data.total_count; + + return data.items; + }), + catchError(() => { + this.isLoadingResults = false; + // Catch if the GitHub API has reached its rate limit. Return empty data. + this.isRateLimitReached = true; + return observableOf([]); + }) + ) + .subscribe((data) => (this.data = data)); + } + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/http-table/http-table.component.html b/theme/packages/main/src/app/pages/tables/http-table/http-table.component.html new file mode 100644 index 0000000..29905b4 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/http-table/http-table.component.html @@ -0,0 +1,91 @@ + + +

+ HTTP table + get data with http +

+
+
+ @if(isLoadingResults || isRateLimitReached) { +
+ @if(isLoadingResults) { + + } @if(isRateLimitReached) { +
+ GitHub's API rate limit has been reached. It will be reset in one + minute. +
+ } +
+ } + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ # + {{ row.number }} + Title + + {{ row.title.slice(0, 50) }}... + + State + + + {{ row.state }} + + + Created + +
+ {{ row.created_at | date }} +
+
+
+ + +
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/http-table/http-table.component.scss b/theme/packages/main/src/app/pages/tables/http-table/http-table.component.scss new file mode 100644 index 0000000..17f8d39 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/http-table/http-table.component.scss @@ -0,0 +1,79 @@ +.example-container { + position: relative; + min-height: 200px; + } + + .example-table-container { + position: relative; + max-height: 400px; + overflow: auto; + } + + .example-loading-shade { + position: absolute; + top: 0; + left: 0; + bottom: 56px; + right: 0; + background: rgba(0, 0, 0, 0.15); + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + } + + .example-rate-limit-reached { + color: #980000; + max-width: 360px; + text-align: center; + } + + /* Column Widths */ + .mat-column-number, + .mat-column-state { + max-width: 64px; + } + + .mat-column-created { + max-width: 124px; + } +.example-container { + position: relative; + min-height: 200px; +} + +.example-table-container { + position: relative; + max-height: 400px; + overflow: auto; +} + +.example-loading-shade { + position: absolute; + top: 0; + left: 0; + bottom: 56px; + right: 0; + background: rgba(0, 0, 0, 0.15); + z-index: 1; + display: flex; + align-items: center; + justify-content: center; +} + +.example-rate-limit-reached { + color: #980000; + max-width: 360px; + text-align: center; +} + +/* Column Widths */ +.mat-column-number, +.mat-column-state { + max-width: 64px; +} + +.mat-column-created { + max-width: 124px; +} + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/http-table/http-table.component.ts b/theme/packages/main/src/app/pages/tables/http-table/http-table.component.ts new file mode 100644 index 0000000..37fd076 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/http-table/http-table.component.ts @@ -0,0 +1,126 @@ +import { HttpClient } from '@angular/common/http'; +import { Component, ViewChild } from '@angular/core'; +import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; +import { MatSort, MatSortModule } from '@angular/material/sort'; +import { merge, Observable, of as observableOf } from 'rxjs'; +import { catchError, map, startWith, switchMap } from 'rxjs/operators'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatTableModule } from '@angular/material/table'; +import { MatCardModule } from '@angular/material/card'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { HTTP_TABLE_HTML_SNIPPET } from './code/http-table-html-snippet'; +import { HTTP_TABLE_TS_SNIPPET } from './code/http-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-http-table', + imports: [ + MatTableModule, + MatCardModule, + MatPaginatorModule, + MatProgressSpinnerModule, + CommonModule, + TablerIconsModule, + MatSortModule, + MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './http-table.component.html', + styleUrls: ['./http-table.component.scss'], +}) +export class AppHttpTableComponent { + // 1 [Http Row with Table] + codeForHttpRowTable = HTTP_TABLE_HTML_SNIPPET; + codeForHttpRowTableTs = HTTP_TABLE_TS_SNIPPET; + + displayedColumns: string[] = ['created', 'state', 'number', 'title']; + exampleDatabase: ExampleHttpDatabase | null = null; + data: GithubIssue[] = []; + + resultsLength = 0; + isLoadingResults = true; + isRateLimitReached = false; + + @ViewChild(MatPaginator) paginator: MatPaginator = Object.create(null); + @ViewChild(MatSort) sort: MatSort = Object.create(null); + // tslint:disable-next-line - Disables all + constructor(private _httpClient: HttpClient) {} + + ngAfterViewInit(): void { + this.exampleDatabase = new ExampleHttpDatabase(this._httpClient); + + // If the user changes the sort order, reset back to the first page. + this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); + + merge(this.sort.sortChange, this.paginator.page) + .pipe( + startWith({}), + switchMap(() => { + this.isLoadingResults = true; + // tslint:disable-next-line - Disables all + return this.exampleDatabase!.getRepoIssues( + this.sort.active, + this.sort.direction, + this.paginator.pageIndex + ); + }), + map((data) => { + // Flip flag to show that loading has finished. + this.isLoadingResults = false; + this.isRateLimitReached = false; + this.resultsLength = data.total_count; + + return data.items; + }), + catchError(() => { + this.isLoadingResults = false; + // Catch if the GitHub API has reached its rate limit. Return empty data. + this.isRateLimitReached = true; + return observableOf([]); + }) + ) + .subscribe((data) => (this.data = data)); + } +} + +export interface GithubApi { + items: GithubIssue[]; + total_count: number; +} + +export interface GithubIssue { + created_at: string; + number: string; + state: string; + title: string; +} + +/** An example database that the data source uses to retrieve data for the table. */ +export class ExampleHttpDatabase { + // tslint:disable-next-line - Disables all + constructor(private _httpClient: HttpClient) {} + + getRepoIssues( + sort: string, + order: string, + page: number + ): Observable { + const href = 'https://api.github.com/search/issues'; + const requestUrl = `${href}?q=repo:angular/components&sort=${sort}&order=${order}&page=${ + page + 1 + }`; + + return this._httpClient.get(requestUrl); + } +} diff --git a/theme/packages/main/src/app/pages/tables/mix-table/code/mix-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/mix-table/code/mix-table-html-snippet.ts new file mode 100644 index 0000000..897f48a --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/mix-table/code/mix-table-html-snippet.ts @@ -0,0 +1,50 @@ +export const MIX_TABLE_HTML_SNIPPET = `
+ + + + + ID + + + {{ row.id }} + + + + + + + Progress + + {{ row.progress }}% + + + + + + Name + + +
+ profile + {{ row.name }} +
+
+
+ + + + + Color + + + {{ row.color }} + + + + + +
+ + +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/mix-table/code/mix-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/mix-table/code/mix-table-ts-snippet.ts new file mode 100644 index 0000000..d088951 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/mix-table/code/mix-table-ts-snippet.ts @@ -0,0 +1,124 @@ +export const MIX_TABLE_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; + import { MatSort } from '@angular/material/sort'; + import { MatTableDataSource, MatTableModule } from '@angular/material/table'; + import { BreakpointObserver } from '@angular/cdk/layout'; + import { MatCardModule } from '@angular/material/card'; + import { MatFormFieldModule } from '@angular/material/form-field'; + import { MatInputModule } from '@angular/material/input'; + + + /** Constants used to fill up our data base. */ + const COLORS = [ + 'maroon', + 'red', + 'orange', + 'yellow', + 'olive', + 'green', + 'purple', + 'fuchsia', + 'lime', + 'teal', + 'aqua', + 'blue', + 'navy', + 'black', + 'gray', + ]; + + const NAMES = [ + 'Maia', + 'Asher', + 'Olivia', + 'Atticus', + 'Amelia', + 'Jack', + 'Charlotte', + 'Theodore', + 'Isla', + 'Oliver', + 'Isabella', + 'Jasper', + 'Cora', + 'Levi', + 'Violet', + 'Arthur', + 'Mia', + 'Thomas', + 'Elizabeth', + ]; + + export interface UserData { + id: string; + name: string; + progress: string; + color: string; + } + + /** + * @title mix table */ + */ + @Component({ + selector: 'app-mix-table', + imports: [MatTableModule, MatCardModule, MatPaginatorModule, MatFormFieldModule, MatInputModule], + templateUrl: './mix-table.component.html' + }) + export class AppMixTableComponent { + + displayedColumns = ['id', 'name', 'progress', 'color']; + dataSource: MatTableDataSource; + + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator = + Object.create(null); + @ViewChild(MatSort, { static: true }) sort: MatSort = Object.create(null); + + constructor(breakpointObserver: BreakpointObserver) { + breakpointObserver.observe(['(max-width: 600px)']).subscribe((result) => { + this.displayedColumns = result.matches + ? ['id', 'name', 'progress', 'color'] + : ['id', 'name', 'progress', 'color']; + }); + + // Create 100 users + const users: UserData[] = []; + for (let i = 1; i <= 100; i++) { + users.push(createNewUser(i)); + } + + // Assign the data to the data source for the table to render + this.dataSource = new MatTableDataSource(users); + } + + /** + * Set the paginator and sort after the view init since this component will + * be able to query its view for the initialized paginator and sort. + */ + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + } + + /** Builds and returns a new User. */ + function createNewUser(id: number): UserData { + const name = + NAMES[Math.round(Math.random() * (NAMES.length - 1))] + + ' ' + + NAMES[Math.round(Math.random() * (NAMES.length - 1))].charAt(0) + + '.'; + // tslint:disable-next-line - Disables all + return { + id: id.toString(), + name: name, + progress: Math.round(Math.random() * 100).toString(), + color: COLORS[Math.round(Math.random() * (COLORS.length - 1))], + }; + } +`; diff --git a/theme/packages/main/src/app/pages/tables/mix-table/mix-table.component.html b/theme/packages/main/src/app/pages/tables/mix-table/mix-table.component.html new file mode 100644 index 0000000..76d404e --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/mix-table/mix-table.component.html @@ -0,0 +1,78 @@ + + +

+ Data table with sorting, pagination, and filtering + all functionality is in one table +

+ +
+ + Search Here + + +
+ + + + + ID + + + {{ row.id }} + + + + + + + Progress + + {{ row.progress }}% + + + + + + Name + + +
+ profile + {{ row.name }} +
+
+
+ + + + + Color + + + {{ row.color }} + + + + + +
+ + +
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/mix-table/mix-table.component.ts b/theme/packages/main/src/app/pages/tables/mix-table/mix-table.component.ts new file mode 100644 index 0000000..d0ef4c3 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/mix-table/mix-table.component.ts @@ -0,0 +1,136 @@ +import { Component, ViewChild } from '@angular/core'; +import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { BreakpointObserver } from '@angular/cdk/layout'; +import { MatCardModule } from '@angular/material/card'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { MIX_TABLE_HTML_SNIPPET } from './code/mix-table-html-snippet'; +import { MIX_TABLE_TS_SNIPPET } from './code/mix-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +/** Constants used to fill up our data base. */ +const COLORS = [ + 'maroon', + 'red', + 'orange', + 'yellow', + 'olive', + 'green', + 'purple', + 'fuchsia', + 'lime', + 'teal', + 'aqua', + 'blue', + 'navy', + 'black', + 'gray', +]; + +const NAMES = [ + 'Maia', + 'Asher', + 'Olivia', + 'Atticus', + 'Amelia', + 'Jack', + 'Charlotte', + 'Theodore', + 'Isla', + 'Oliver', + 'Isabella', + 'Jasper', + 'Cora', + 'Levi', + 'Violet', + 'Arthur', + 'Mia', + 'Thomas', + 'Elizabeth', +]; + +@Component({ + selector: 'app-mix-table', + imports: [MatTableModule, MatCardModule, MatPaginatorModule, MatFormFieldModule, MatInputModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './mix-table.component.html' +}) +export class AppMixTableComponent { + // 1 [mix with Table] + codeForMixTable = MIX_TABLE_HTML_SNIPPET; + codeForMixTableTs = MIX_TABLE_TS_SNIPPET; + + displayedColumns = ['id', 'name', 'progress', 'color']; + dataSource: MatTableDataSource; + + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator = + Object.create(null); + @ViewChild(MatSort, { static: true }) sort: MatSort = Object.create(null); + + constructor(breakpointObserver: BreakpointObserver) { + breakpointObserver.observe(['(max-width: 600px)']).subscribe((result) => { + this.displayedColumns = result.matches + ? ['id', 'name', 'progress', 'color'] + : ['id', 'name', 'progress', 'color']; + }); + + // Create 100 users + const users: UserData[] = []; + for (let i = 1; i <= 100; i++) { + users.push(createNewUser(i)); + } + + // Assign the data to the data source for the table to render + this.dataSource = new MatTableDataSource(users); + } + + /** + * Set the paginator and sort after the view init since this component will + * be able to query its view for the initialized paginator and sort. + */ + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.dataSource.filter = filterValue.trim().toLowerCase(); + } +} + +/** Builds and returns a new User. */ +function createNewUser(id: number): UserData { + const name = + NAMES[Math.round(Math.random() * (NAMES.length - 1))] + + ' ' + + NAMES[Math.round(Math.random() * (NAMES.length - 1))].charAt(0) + + '.'; + // tslint:disable-next-line - Disables all + return { + id: id.toString(), + name: name, + progress: Math.round(Math.random() * 100).toString(), + color: COLORS[Math.round(Math.random() * (COLORS.length - 1))], + }; +} + +export interface UserData { + id: string; + name: string; + progress: string; + color: string; +} diff --git a/theme/packages/main/src/app/pages/tables/multi-header-footer-table/code/multi-header-footer-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/multi-header-footer-table/code/multi-header-footer-table-html-snippet.ts new file mode 100644 index 0000000..b88cdf9 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/multi-header-footer-table/code/multi-header-footer-table-html-snippet.ts @@ -0,0 +1,65 @@ +export const MULTI_HEADER_FOOTER_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Item + +
+ product + {{ transaction.item }} +
+
+ Total + + Cost + + {{ transaction.cost | currency }} + + {{ getTotalCost() | currency }} + + Name of the item purchased + + Cost of the item in USD + + Please note that the cost of items displayed are completely and + totally made up. +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/multi-header-footer-table/code/multi-header-footer-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/multi-header-footer-table/code/multi-header-footer-table-ts-snippet.ts new file mode 100644 index 0000000..4304c7b --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/multi-header-footer-table/code/multi-header-footer-table-ts-snippet.ts @@ -0,0 +1,42 @@ +export const MULTI_HEADER_FOOTER_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { CommonModule } from '@angular/common'; + import { MatCardModule } from '@angular/material/card'; + import { MatTableModule } from '@angular/material/table'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface Transaction { + item: string; + img: string; + cost: number; + } + + /** + * @title multi-header-footer table */ + */ + @Component({ + selector: 'app-multi-header-footer-table', + imports: [MatCardModule, MatTableModule, CommonModule, MatDividerModule], + templateUrl: './multi-header-footer-table.component.html', + styleUrls: ['./multi-header-footer-table.component.scss'], + }) + export class AppMultiHeaderFooterTableComponent { + + displayedColumns: string[] = ['item', 'cost']; + transactions: Transaction[] = [ + { img: '/assets/images/products/s1.jpg', item: 'Beach ball', cost: 4 }, + { img: '/assets/images/products/s2.jpg', item: 'Towel', cost: 5 }, + { img: '/assets/images/products/s3.jpg', item: 'Frisbee', cost: 2 }, + { img: '/assets/images/products/s4.jpg', item: 'Sunscreen', cost: 4 }, + { img: '/assets/images/products/s5.jpg', item: 'Cooler', cost: 25 }, + { img: '/assets/images/products/s6.jpg', item: 'Swim suit', cost: 15 }, + ]; + + /** Gets the total cost of all transactions. */ + getTotalCost(): any { + return this.transactions + .map((t) => t.cost) + .reduce((acc, value) => acc + value, 0); + } + + } +`; diff --git a/theme/packages/main/src/app/pages/tables/multi-header-footer-table/multi-header-footer-table.component.html b/theme/packages/main/src/app/pages/tables/multi-header-footer-table/multi-header-footer-table.component.html new file mode 100644 index 0000000..b3b09a0 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/multi-header-footer-table/multi-header-footer-table.component.html @@ -0,0 +1,88 @@ + + +

+ Table with multiple header and footer rows + Pagination and search is avail +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Item + +
+ product + {{ transaction.item }} +
+
+ Total + + Cost + + {{ transaction.cost | currency }} + + {{ getTotalCost() | currency }} + + Name of the item purchased + + Cost of the item in USD + + Please note that the cost of items displayed are completely and + totally made up. +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/multi-header-footer-table/multi-header-footer-table.component.scss b/theme/packages/main/src/app/pages/tables/multi-header-footer-table/multi-header-footer-table.component.scss new file mode 100644 index 0000000..478913e --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/multi-header-footer-table/multi-header-footer-table.component.scss @@ -0,0 +1,11 @@ +.example-first-header-row th { + border-bottom: none; +} + +.example-second-header-row { + font-style: italic; +} + +.example-first-footer-row { + font-weight: bold; +} diff --git a/theme/packages/main/src/app/pages/tables/multi-header-footer-table/multi-header-footer-table.component.ts b/theme/packages/main/src/app/pages/tables/multi-header-footer-table/multi-header-footer-table.component.ts new file mode 100644 index 0000000..c270b9d --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/multi-header-footer-table/multi-header-footer-table.component.ts @@ -0,0 +1,58 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatTableModule } from '@angular/material/table'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { MULTI_HEADER_FOOTER_TABLE_HTML_SNIPPET } from './code/multi-header-footer-table-html-snippet'; +import { MULTI_HEADER_FOOTER_TABLE_TS_SNIPPET } from './code/multi-header-footer-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +export interface Transaction { + item: string; + img: string; + cost: number; +} + +@Component({ + selector: 'app-multi-header-footer-table', + imports: [MatCardModule, MatTableModule, CommonModule, MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './multi-header-footer-table.component.html', + styleUrls: ['./multi-header-footer-table.component.scss'], +}) +export class AppMultiHeaderFooterTableComponent implements OnInit { + // 1 [Multi Header Footer with Table] + codeForMultiHeaderFooterTable = MULTI_HEADER_FOOTER_TABLE_HTML_SNIPPET; + codeForMultiHeaderFooterTableTs = MULTI_HEADER_FOOTER_TABLE_TS_SNIPPET; + + displayedColumns: string[] = ['item', 'cost']; + transactions: Transaction[] = [ + { img: '/assets/images/products/s1.jpg', item: 'Beach ball', cost: 4 }, + { img: '/assets/images/products/s2.jpg', item: 'Towel', cost: 5 }, + { img: '/assets/images/products/s3.jpg', item: 'Frisbee', cost: 2 }, + { img: '/assets/images/products/s4.jpg', item: 'Sunscreen', cost: 4 }, + { img: '/assets/images/products/s5.jpg', item: 'Cooler', cost: 25 }, + { img: '/assets/images/products/s6.jpg', item: 'Swim suit', cost: 15 }, + ]; + + /** Gets the total cost of all transactions. */ + getTotalCost(): any { + return this.transactions + .map((t) => t.cost) + .reduce((acc, value) => acc + value, 0); + } + + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/tables/pagination-table/code/pagination-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/pagination-table/code/pagination-table-html-snippet.ts new file mode 100644 index 0000000..bf6acda --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/pagination-table/code/pagination-table-html-snippet.ts @@ -0,0 +1,86 @@ +export const PAGINATION_TABLE_HTML_SNIPPET = `
+ + + + + Assigned + + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+
+ + + + + Name + + + {{ element.productName }} + + + + + + Priority + + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + + + + + + Budget + + + {{ element.budget }}k + + + + +
+ + + +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/pagination-table/code/pagination-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/pagination-table/code/pagination-table-ts-snippet.ts new file mode 100644 index 0000000..c593949 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/pagination-table/code/pagination-table-ts-snippet.ts @@ -0,0 +1,245 @@ +export const PAGINATION_TABLE_TS_SNIPPET = ` import { Component, ViewChild } from '@angular/core'; + import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; + import { MatTableDataSource, MatTableModule } from '@angular/material/table'; + import { BreakpointObserver } from '@angular/cdk/layout'; + import { CommonModule } from '@angular/common'; + import { MatCardModule } from '@angular/material/card'; + import { MatDividerModule } from '@angular/material/divider'; + + + export interface Element { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; + } + + const PRODUCT_DATA: Element[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + ]; + + /** + * @title pagination table */ + */ + @Component({ + selector: 'app-pagination-table', + imports: [ + MatCardModule, + MatTableModule, + CommonModule, + MatPaginatorModule, + MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './pagination-table.component.html', + }) + export class AppPaginationTableComponent { + + displayedColumns = ['assigned', 'name', 'priority', 'budget']; + dataSource = new MatTableDataSource(PRODUCT_DATA); + + constructor(breakpointObserver: BreakpointObserver) { + breakpointObserver.observe(['(max-width: 600px)']).subscribe((result) => { + this.displayedColumns = result.matches + ? ['assigned', 'name', 'priority', 'budget'] + : ['assigned', 'name', 'priority', 'budget']; + }); + } + + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator = + Object.create(null); + + /** + * Set the paginator after the view init since this component will + * be able to query its view for the initialized paginator. + */ + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + } + } +`; diff --git a/theme/packages/main/src/app/pages/tables/pagination-table/pagination-table.component.html b/theme/packages/main/src/app/pages/tables/pagination-table/pagination-table.component.html new file mode 100644 index 0000000..775ddb0 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/pagination-table/pagination-table.component.html @@ -0,0 +1,110 @@ + + +

+ Pagination Table + get nore item with pagination +

+ +
+
+ + + + + Assigned + + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+
+ + + + + Name + + + {{ element.productName }} + + + + + + Priority + + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + + + + + + Budget + + + ${{ element.budget }}k + + + + +
+ + + +
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/pagination-table/pagination-table.component.ts b/theme/packages/main/src/app/pages/tables/pagination-table/pagination-table.component.ts new file mode 100644 index 0000000..9cc5540 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/pagination-table/pagination-table.component.ts @@ -0,0 +1,253 @@ +import { Component, ViewChild } from '@angular/core'; +import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { BreakpointObserver } from '@angular/cdk/layout'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { PAGINATION_TABLE_HTML_SNIPPET } from './code/pagination-table-html-snippet'; +import { PAGINATION_TABLE_TS_SNIPPET } from './code/pagination-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +const PRODUCT_DATA: Element[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, +]; + +@Component({ + selector: 'app-pagination-table', + imports: [ + MatCardModule, + MatTableModule, + CommonModule, + MatPaginatorModule, + MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './pagination-table.component.html', +}) +export class AppPaginationTableComponent { + // 1 [Pagination with Table] + codeForPaginationTable = PAGINATION_TABLE_HTML_SNIPPET; + codeForPaginationTableTs = PAGINATION_TABLE_TS_SNIPPET; + + displayedColumns = ['assigned', 'name', 'priority', 'budget']; + dataSource = new MatTableDataSource(PRODUCT_DATA); + + constructor(breakpointObserver: BreakpointObserver) { + breakpointObserver.observe(['(max-width: 600px)']).subscribe((result) => { + this.displayedColumns = result.matches + ? ['assigned', 'name', 'priority', 'budget'] + : ['assigned', 'name', 'priority', 'budget']; + }); + } + + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator = + Object.create(null); + + /** + * Set the paginator after the view init since this component will + * be able to query its view for the initialized paginator. + */ + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + } +} + +export interface Element { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; +} diff --git a/theme/packages/main/src/app/pages/tables/row-context-table/code/row-context-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/row-context-table/code/row-context-table-html-snippet.ts new file mode 100644 index 0000000..c823f28 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/row-context-table/code/row-context-table-html-snippet.ts @@ -0,0 +1,63 @@ +export const ROW_CONTEXT_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ $implicit + {{ data }} + index + {{ index }} + count + {{ count }} + first + {{ first }} + last + {{ last }} + even + {{ even }} + odd + {{ odd }}
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/row-context-table/code/row-context-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/row-context-table/code/row-context-table-ts-snippet.ts new file mode 100644 index 0000000..a459495 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/row-context-table/code/row-context-table-ts-snippet.ts @@ -0,0 +1,28 @@ +export const ROW_CONTEXT_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { MatCardModule } from '@angular/material/card'; + import { MatDividerModule } from '@angular/material/divider'; + import { MatTableModule } from '@angular/material/table'; + + + /** + * @title Row Context table */ + */ + @Component({ + selector: 'app-row-context-table', + imports: [MatCardModule, MatTableModule, MatDividerModule], + templateUrl: './row-context-table.component.html', + }) + export class AppRowContextTableComponent { + + displayedColumns: string[] = [ + '$implicit', + 'index', + 'count', + 'first', + 'last', + 'even', + 'odd', + ]; + data: string[] = ['one', 'two', 'three', 'four', 'five']; + } +`; diff --git a/theme/packages/main/src/app/pages/tables/row-context-table/row-context-table.component.html b/theme/packages/main/src/app/pages/tables/row-context-table/row-context-table.component.html new file mode 100644 index 0000000..9ce2cb1 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/row-context-table/row-context-table.component.html @@ -0,0 +1,87 @@ + + +

+ Row context table + Sell new products +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ $implicit + {{ data }} + index + {{ index }} + count + {{ count }} + first + {{ first }} + last + {{ last }} + even + {{ even }} + odd + {{ odd }}
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/row-context-table/row-context-table.component.ts b/theme/packages/main/src/app/pages/tables/row-context-table/row-context-table.component.ts new file mode 100644 index 0000000..9fcdf65 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/row-context-table/row-context-table.component.ts @@ -0,0 +1,44 @@ +import { Component, OnInit } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatTableModule } from '@angular/material/table'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { ROW_CONTEXT_TABLE_HTML_SNIPPET } from './code/row-context-table-html-snippet'; +import { ROW_CONTEXT_TABLE_TS_SNIPPET } from './code/row-context-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-row-context-table', + imports: [MatCardModule, MatTableModule, MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './row-context-table.component.html', +}) +export class AppRowContextTableComponent implements OnInit { + // 1 [Row Context with Table] + codeForRowContextTable = ROW_CONTEXT_TABLE_HTML_SNIPPET; + codeForRowContextTableTs = ROW_CONTEXT_TABLE_TS_SNIPPET; + + displayedColumns: string[] = [ + '$implicit', + 'index', + 'count', + 'first', + 'last', + 'even', + 'odd', + ]; + data: string[] = ['one', 'two', 'three', 'four', 'five']; + + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/tables/selection-table/code/selection-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/selection-table/code/selection-table-html-snippet.ts new file mode 100644 index 0000000..df0c476 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/selection-table/code/selection-table-html-snippet.ts @@ -0,0 +1,99 @@ +export const SELECTION_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+ Name + + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + Budget + + {{ element.budget }}k +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/selection-table/code/selection-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/selection-table/code/selection-table-ts-snippet.ts new file mode 100644 index 0000000..d11fe22 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/selection-table/code/selection-table-ts-snippet.ts @@ -0,0 +1,127 @@ +export const SELECTION_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { SelectionModel } from '@angular/cdk/collections'; + import { MatTableDataSource, MatTableModule } from '@angular/material/table'; + import { CommonModule } from '@angular/common'; + import { MatCardModule } from '@angular/material/card'; + import { MatCheckboxModule } from '@angular/material/checkbox'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface PeriodicElement { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; + } + + const ELEMENT_DATA: PeriodicElement[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + ]; + + /** + * @title selection table */ + */ + @Component({ + selector: 'app-selection-table', + imports: [ + MatCardModule, + MatTableModule, + CommonModule, + MatCheckboxModule, + MatDividerModule + ], + templateUrl: './selection-table.component.html', + }) + export class AppSelectionTableComponent { + + displayedColumns: string[] = [ + 'select', + 'assigned', + 'name', + 'priority', + 'budget', + ]; + dataSource = new MatTableDataSource(ELEMENT_DATA); + selection = new SelectionModel(true, []); + + /** Whether the number of selected elements matches the total number of rows. */ + isAllSelected(): any { + const numSelected = this.selection.selected.length; + const numRows = this.dataSource.data.length; + return numSelected === numRows; + } + + /** Selects all rows if they are not all selected; otherwise clear selection. */ + masterToggle(): void { + this.isAllSelected() + ? this.selection.clear() + : this.dataSource.data.forEach((row) => this.selection.select(row)); + } + + /** The label for the checkbox on the passed row */ + checkboxLabel(row?: PeriodicElement): string { + if (!row) { + return {this.isAllSelected() ? 'select' : 'deselect'} all; + } + return {this.selection.isSelected(row) ? 'deselect' : 'select'} row { + row.position + 1 + }; + } + + } +`; diff --git a/theme/packages/main/src/app/pages/tables/selection-table/selection-table.component.html b/theme/packages/main/src/app/pages/tables/selection-table/selection-table.component.html new file mode 100644 index 0000000..6d50881 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/selection-table/selection-table.component.html @@ -0,0 +1,123 @@ + + +

+ Selection Table + single one or more then one item +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+ Name + + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + Budget + + ${{ element.budget }}k +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/selection-table/selection-table.component.ts b/theme/packages/main/src/app/pages/tables/selection-table/selection-table.component.ts new file mode 100644 index 0000000..48720b6 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/selection-table/selection-table.component.ts @@ -0,0 +1,143 @@ +import { Component, OnInit } from '@angular/core'; +import { SelectionModel } from '@angular/cdk/collections'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { SELECTION_TABLE_HTML_SNIPPET } from './code/selection-table-html-snippet'; +import { SELECTION_TABLE_TS_SNIPPET } from './code/selection-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +export interface PeriodicElement { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; +} + +const ELEMENT_DATA: PeriodicElement[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, +]; + +@Component({ + selector: 'app-selection-table', + imports: [ + MatCardModule, + MatTableModule, + CommonModule, + MatCheckboxModule, + MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './selection-table.component.html', +}) +export class AppSelectionTableComponent implements OnInit { + + // 1 [Selection with Table] + codeForSelectionTable = SELECTION_TABLE_HTML_SNIPPET; + codeForSelectionTableTs = SELECTION_TABLE_TS_SNIPPET; + + displayedColumns: string[] = [ + 'select', + 'assigned', + 'name', + 'priority', + 'budget', + ]; + dataSource = new MatTableDataSource(ELEMENT_DATA); + selection = new SelectionModel(true, []); + + /** Whether the number of selected elements matches the total number of rows. */ + isAllSelected(): any { + const numSelected = this.selection.selected.length; + const numRows = this.dataSource.data.length; + return numSelected === numRows; + } + + /** Selects all rows if they are not all selected; otherwise clear selection. */ + masterToggle(): void { + this.isAllSelected() + ? this.selection.clear() + : this.dataSource.data.forEach((row) => this.selection.select(row)); + } + + /** The label for the checkbox on the passed row */ + checkboxLabel(row?: PeriodicElement): string { + if (!row) { + return `${this.isAllSelected() ? 'select' : 'deselect'} all`; + } + return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${ + row.position + 1 + }`; + } + + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/tables/sortable-table/code/sortable-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/sortable-table/code/sortable-table-html-snippet.ts new file mode 100644 index 0000000..de9b3eb --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sortable-table/code/sortable-table-html-snippet.ts @@ -0,0 +1,86 @@ +export const SORTABLE_TABLE_HTML_SNIPPET = `
+ + + + + Assigned + + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+
+ + + + + Name + + + {{ element.name }} + + + + + + + Priority + + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + + + + + + Budget + + + {{ element.budget }}k + + + + + +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/sortable-table/code/sortable-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/sortable-table/code/sortable-table-ts-snippet.ts new file mode 100644 index 0000000..f0b03b2 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sortable-table/code/sortable-table-ts-snippet.ts @@ -0,0 +1,116 @@ +export const SORTABLE_TABLE_TS_SNIPPET = ` import { LiveAnnouncer } from '@angular/cdk/a11y'; + import { Component, inject, OnInit, ViewChild } from '@angular/core'; + import { MatTableDataSource, MatTableModule } from '@angular/material/table'; + import { MatSort, MatSortModule, Sort } from '@angular/material/sort'; + import { CommonModule } from '@angular/common'; + import { MatCardModule } from '@angular/material/card'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface Element { + id: number; + imagePath: string; + uname: string; + position: string; + name: string; + budget: number; + priority: string; + } + + const ELEMENT_DATA: Element[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + name: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + name: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + name: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + name: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 5, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + name: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 6, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + name: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + ]; + + /** + * @title selection table */ + */ + @Component({ + selector: 'app-sortable-table', + imports: [MatCardModule, MatTableModule, CommonModule, MatDividerModule, MatSortModule], + templateUrl: './sortable-table.component.html', + }) + export class AppSortableTableComponent { + + private _liveAnnouncer = inject(LiveAnnouncer); + + displayedColumns = ['assigned', 'name', 'priority', 'budget']; + dataSource = new MatTableDataSource(ELEMENT_DATA); + + @ViewChild(MatSort, { static: true }) sort: MatSort = Object.create(null); + + /** + * Set the sort after the view init since this component will + * be able to query its view for the initialized sort. + */ + ngAfterViewInit(): void { + this.dataSource.sort = this.sort; + } + + announceSortChange(sortState: Sort) { + // This example uses English messages. If your application supports + // multiple language, you would internationalize these strings. + // Furthermore, you can customize the message to add additional + // details about the values being sorted. + if (sortState.direction) { + this._liveAnnouncer.announce('Sorted {sortState.direction}ending'); + } else { + this._liveAnnouncer.announce('Sorting cleared'); + } + } + + ngOnInit(): void {} + + } +`; diff --git a/theme/packages/main/src/app/pages/tables/sortable-table/sortable-table.component.html b/theme/packages/main/src/app/pages/tables/sortable-table/sortable-table.component.html new file mode 100644 index 0000000..23f328a --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sortable-table/sortable-table.component.html @@ -0,0 +1,110 @@ + + +

+ Sortable Table + sort your item +

+ +
+
+ + + + + Assigned + + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+
+ + + + + Name + + + {{ element.name }} + + + + + + + Priority + + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + + + + + + Budget + + + ${{ element.budget }}k + + + + + +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/sortable-table/sortable-table.component.ts b/theme/packages/main/src/app/pages/tables/sortable-table/sortable-table.component.ts new file mode 100644 index 0000000..f30a48c --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sortable-table/sortable-table.component.ts @@ -0,0 +1,130 @@ +import { LiveAnnouncer } from '@angular/cdk/a11y'; +import { Component, inject, OnInit, ViewChild } from '@angular/core'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { MatSort, MatSortModule, Sort } from '@angular/material/sort'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { SORTABLE_TABLE_HTML_SNIPPET } from './code/sortable-table-html-snippet'; +import { SORTABLE_TABLE_TS_SNIPPET } from './code/sortable-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +const ELEMENT_DATA: Element[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + name: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + name: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + name: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + name: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 5, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + name: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 6, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + name: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, +]; + +@Component({ + selector: 'app-sortable-table', + imports: [MatCardModule, MatTableModule, CommonModule, MatDividerModule, MatSortModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './sortable-table.component.html', +}) +export class AppSortableTableComponent implements OnInit { + // 1 [Sortable with Table] + codeForSortableTable = SORTABLE_TABLE_HTML_SNIPPET; + codeForSortableTableTs = SORTABLE_TABLE_TS_SNIPPET; + + private _liveAnnouncer = inject(LiveAnnouncer); + + constructor() {} + displayedColumns = ['assigned', 'name', 'priority', 'budget']; + dataSource = new MatTableDataSource(ELEMENT_DATA); + + @ViewChild(MatSort, { static: true }) sort: MatSort = Object.create(null); + + /** + * Set the sort after the view init since this component will + * be able to query its view for the initialized sort. + */ + ngAfterViewInit(): void { + this.dataSource.sort = this.sort; + } + + /** Announce the change in sort state for assistive technology. */ + announceSortChange(sortState: Sort) { + // This example uses English messages. If your application supports + // multiple language, you would internationalize these strings. + // Furthermore, you can customize the message to add additional + // details about the values being sorted. + if (sortState.direction) { + this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`); + } else { + this._liveAnnouncer.announce('Sorting cleared'); + } + } + + ngOnInit(): void {} +} + +export interface Element { + id: number; + imagePath: string; + uname: string; + position: string; + name: string; + budget: number; + priority: string; +} diff --git a/theme/packages/main/src/app/pages/tables/sticky-column-table/code/sticky-column-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/sticky-column-table/code/sticky-column-table-html-snippet.ts new file mode 100644 index 0000000..4a61e17 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sticky-column-table/code/sticky-column-table-html-snippet.ts @@ -0,0 +1,91 @@ +export const STICKY_COLUMN_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+ Name + + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + Budget + {{ element.budget }}k + + more_vert +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/sticky-column-table/code/sticky-column-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/sticky-column-table/code/sticky-column-table-ts-snippet.ts new file mode 100644 index 0000000..6d9cb56 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sticky-column-table/code/sticky-column-table-ts-snippet.ts @@ -0,0 +1,123 @@ +export const STICKY_COLUMN_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { CommonModule } from '@angular/common'; + import { MatCardModule } from '@angular/material/card'; + import { MatTableModule } from '@angular/material/table'; + import { MatIconModule } from '@angular/material/icon'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface PeriodicElement { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; + } + + const ELEMENT_DATA: PeriodicElement[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 5, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 6, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 7, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 8, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + ]; + + /** + * @title sticky column table */ + */ + @Component({ + selector: 'app-sticky-column-table', + imports: [ + MatCardModule, + MatTableModule, + MatIconModule, + CommonModule, + MatDividerModule + ], + templateUrl: './sticky-column-table.component.html', + styleUrls: ['./sticky-column-table.component.scss'], + }) + export class AppStickyColumnTableComponent { + + displayedColumns = [ + 'assigned', + 'name', + 'priority', + 'budget', + 'priority', + 'name', + 'budget', + 'name', + ]; + dataSource = ELEMENT_DATA; + + } +`; diff --git a/theme/packages/main/src/app/pages/tables/sticky-column-table/sticky-column-table.component.html b/theme/packages/main/src/app/pages/tables/sticky-column-table/sticky-column-table.component.html new file mode 100644 index 0000000..3062ff8 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sticky-column-table/sticky-column-table.component.html @@ -0,0 +1,115 @@ + + +

+ Sticky Column table + sticky column with table +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+ Name + + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } + + @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + Budget + ${{ element.budget }}k + + more_vert +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/sticky-column-table/sticky-column-table.component.scss b/theme/packages/main/src/app/pages/tables/sticky-column-table/sticky-column-table.component.scss new file mode 100644 index 0000000..e499ec2 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sticky-column-table/sticky-column-table.component.scss @@ -0,0 +1,27 @@ +.example-container { + height: 400px; + width: 550px; + overflow: auto; +} + +table { + width: 800px; +} + +td.mat-column-star { + width: 20px; + padding-right: 8px; +} + +th.mat-column-position, +td.mat-column-position { + padding-left: 8px; +} + +.mat-table-sticky:first-child { + border-right: 1px solid #e0e0e0; +} + +.mat-table-sticky:last-child { + border-left: 1px solid #e0e0e0; +} diff --git a/theme/packages/main/src/app/pages/tables/sticky-column-table/sticky-column-table.component.ts b/theme/packages/main/src/app/pages/tables/sticky-column-table/sticky-column-table.component.ts new file mode 100644 index 0000000..994aad9 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sticky-column-table/sticky-column-table.component.ts @@ -0,0 +1,138 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatTableModule } from '@angular/material/table'; +import { MatIconModule } from '@angular/material/icon'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { STICKY_COLUMN_TABLE_HTML_SNIPPET } from './code/sticky-column-table-html-snippet'; +import { STICKY_COLUMN_TABLE_TS_SNIPPET } from './code/sticky-column-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +export interface PeriodicElement { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; +} + +const ELEMENT_DATA: PeriodicElement[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 5, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 6, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 7, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 8, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, +]; + +@Component({ + selector: 'app-sticky-column-table', + imports: [ + MatCardModule, + MatTableModule, + MatIconModule, + CommonModule, + MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './sticky-column-table.component.html', + styleUrls: ['./sticky-column-table.component.scss'], +}) +export class AppStickyColumnTableComponent implements OnInit { + // 1 [Sticky Column with Table] + codeForStickyColumnTable = STICKY_COLUMN_TABLE_HTML_SNIPPET; + codeForStickyColumnTableTs = STICKY_COLUMN_TABLE_TS_SNIPPET; + + displayedColumns = [ + 'assigned', + 'name', + 'priority', + 'budget', + 'priority', + 'name', + 'budget', + 'name', + ]; + dataSource = ELEMENT_DATA; + + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/code/sticky-header-footer-table-html-snippet.ts b/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/code/sticky-header-footer-table-html-snippet.ts new file mode 100644 index 0000000..898bb95 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/code/sticky-header-footer-table-html-snippet.ts @@ -0,0 +1,113 @@ +export const STICKY_FOOTER_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + + + + +
+ Item + +
+ product + {{ transaction.item }} +
+
Total + Cost + + {{ transaction.cost | currency }} + + {{ getTotalCost() | currency }} +
+
+`; + +export const STICKY_HEADER_TABLE_HTML_SNIPPET = `
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+ Name + + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + Budget + + {{ element.budget }}k +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/code/sticky-header-footer-table-ts-snippet.ts b/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/code/sticky-header-footer-table-ts-snippet.ts new file mode 100644 index 0000000..4ff8b47 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/code/sticky-header-footer-table-ts-snippet.ts @@ -0,0 +1,133 @@ +export const STICKY_FOOTER_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { CommonModule } from '@angular/common'; + import { MatCardModule } from '@angular/material/card'; + import { MatTableModule } from '@angular/material/table'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface Transaction { + item: string; + img: string; + cost: number; + } + + /** + * @title sticky Footer table */ + */ + @Component({ + selector: 'app-sticky-header-footer-table', + imports: [MatCardModule, MatTableModule, CommonModule, MatDividerModule], + templateUrl: './sticky-header-footer-table.component.html', + styleUrls: ['./sticky-header-footer-table.component.scss'], + }) + export class AppStickyHeaderFooterTableComponent { + + displayedColumns = ['item', 'cost']; + transactions: Transaction[] = [ + { img: '/assets/images/products/s1.jpg', item: 'Beach ball', cost: 4 }, + { img: '/assets/images/products/s2.jpg', item: 'Towel', cost: 5 }, + { img: '/assets/images/products/s3.jpg', item: 'Frisbee', cost: 2 }, + { img: '/assets/images/products/s4.jpg', item: 'Sunscreen', cost: 4 }, + { img: '/assets/images/products/s5.jpg', item: 'Cooler', cost: 25 }, + { img: '/assets/images/products/s6.jpg', item: 'Swim suit', cost: 15 }, + ]; + + /** Gets the total cost of all transactions. */ + getTotalCost(): any { + return this.transactions + .map((t) => t.cost) + .reduce((acc, value) => acc + value, 0); + } + + } +`; + + +export const STICKY_HEADER_TABLE_TS_SNIPPET = ` import { Component, OnInit } from '@angular/core'; + import { CommonModule } from '@angular/common'; + import { MatCardModule } from '@angular/material/card'; + import { MatTableModule } from '@angular/material/table'; + import { MatDividerModule } from '@angular/material/divider'; + + export interface PeriodicElement { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; + } + + const ELEMENT_DATA: PeriodicElement[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + ]; + + /** + * @title sticky header table */ + */ + @Component({ + selector: 'app-sticky-header-footer-table', + imports: [MatCardModule, MatTableModule, CommonModule, MatDividerModule], + templateUrl: './sticky-header-footer-table.component.html', + styleUrls: ['./sticky-header-footer-table.component.scss'], + }) + export class AppStickyHeaderFooterTableComponent { + + displayedColumns1 = ['assigned', 'name', 'priority', 'budget']; + dataSource = ELEMENT_DATA; + + } +`; diff --git a/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/sticky-header-footer-table.component.html b/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/sticky-header-footer-table.component.html new file mode 100644 index 0000000..40b2794 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/sticky-header-footer-table.component.html @@ -0,0 +1,161 @@ + + +

+ Sticky Footer table + Fixed footer with total items +

+ +
+
+ + + + + + + + + + + + + + + + + + +
+ Item + +
+ product + {{ transaction.item }} +
+
Total + Cost + + {{ transaction.cost | currency }} + + {{ getTotalCost() | currency }} +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
+ + + +

+ Sticky header table + Fixed header +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Assigned + +
+ users +
+
+ {{ element.uname }} +
+ + {{ element.position }} + +
+
+
+ Name + + {{ element.productName }} + + Priority + + @if(element.priority == 'low') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'medium') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'high') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'critical') { + + {{ element.priority | titlecase }} + + } @if(element.priority == 'moderate') { + + {{ element.priority | titlecase }} + + } + + Budget + + ${{ element.budget }}k +
+
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/sticky-header-footer-table.component.scss b/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/sticky-header-footer-table.component.scss new file mode 100644 index 0000000..3c7797d --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/sticky-header-footer-table.component.scss @@ -0,0 +1,13 @@ +.example-container { + height: 270px; + overflow: auto; + } + + tr.mat-footer-row { + font-weight: bold; + } + + .mat-table-sticky { + border-top: 1px solid #e0e0e0; + } + \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/sticky-header-footer-table.component.ts b/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/sticky-header-footer-table.component.ts new file mode 100644 index 0000000..f56110f --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/sticky-header-footer-table/sticky-header-footer-table.component.ts @@ -0,0 +1,131 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatTableModule } from '@angular/material/table'; +import { MatDividerModule } from '@angular/material/divider'; + +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { STICKY_FOOTER_TABLE_HTML_SNIPPET, STICKY_HEADER_TABLE_HTML_SNIPPET } from './code/sticky-header-footer-table-html-snippet'; +import { STICKY_FOOTER_TABLE_TS_SNIPPET, STICKY_HEADER_TABLE_TS_SNIPPET } from './code/sticky-header-footer-table-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +export interface Transaction { + item: string; + img: string; + cost: number; +} + +export interface PeriodicElement { + id: number; + imagePath: string; + uname: string; + position: string; + productName: string; + budget: number; + priority: string; +} + +const ELEMENT_DATA: PeriodicElement[] = [ + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, + { + id: 3, + imagePath: 'assets/images/profile/user-3.jpg', + uname: 'Christopher Jamil', + position: 'Project Manager', + productName: 'MedicalPro Theme', + budget: 12.8, + priority: 'high', + }, + { + id: 4, + imagePath: 'assets/images/profile/user-4.jpg', + uname: 'Nirav Joshi', + position: 'Frontend Engineer', + productName: 'Hosting Press HTML', + budget: 2.4, + priority: 'critical', + }, + { + id: 1, + imagePath: 'assets/images/profile/user-1.jpg', + uname: 'Sunil Joshi', + position: 'Web Designer', + productName: 'Elite Admin', + budget: 3.9, + priority: 'low', + }, + { + id: 2, + imagePath: 'assets/images/profile/user-2.jpg', + uname: 'Andrew McDownland', + position: 'Project Manager', + productName: 'Real Homes Theme', + budget: 24.5, + priority: 'medium', + }, +]; +@Component({ + selector: 'app-sticky-header-footer-table', + imports: [MatCardModule, MatTableModule, CommonModule, MatDividerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './sticky-header-footer-table.component.html', + styleUrls: ['./sticky-header-footer-table.component.scss'], +}) +export class AppStickyHeaderFooterTableComponent implements OnInit { + // 1 [Sticky Footer with Table] + codeForStickyFooterTable = STICKY_FOOTER_TABLE_HTML_SNIPPET; + codeForStickyFooterTableTs = STICKY_FOOTER_TABLE_TS_SNIPPET; + + // 2 [Sticky Header with Table] + codeForStickyHeaderTable = STICKY_HEADER_TABLE_HTML_SNIPPET; + codeForStickyHeaderTableTs = STICKY_HEADER_TABLE_TS_SNIPPET; + + // Fixed header + displayedColumns1 = ['assigned', 'name', 'priority', 'budget']; + dataSource = ELEMENT_DATA; + + displayedColumns = ['item', 'cost']; + transactions: Transaction[] = [ + { img: '/assets/images/products/s1.jpg', item: 'Beach ball', cost: 4 }, + { img: '/assets/images/products/s2.jpg', item: 'Towel', cost: 5 }, + { img: '/assets/images/products/s3.jpg', item: 'Frisbee', cost: 2 }, + { img: '/assets/images/products/s4.jpg', item: 'Sunscreen', cost: 4 }, + { img: '/assets/images/products/s5.jpg', item: 'Cooler', cost: 25 }, + { img: '/assets/images/products/s6.jpg', item: 'Swim suit', cost: 15 }, + ]; + + /** Gets the total cost of all transactions. */ + getTotalCost(): any { + return this.transactions + .map((t) => t.cost) + .reduce((acc, value) => acc + value, 0); + } + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/tables/tables.module.ts b/theme/packages/main/src/app/pages/tables/tables.module.ts new file mode 100644 index 0000000..0e38cc6 --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/tables.module.ts @@ -0,0 +1,43 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { TablesRoutes } from './tables.routing'; + +// tables components +import { AppBasicTableComponent } from './basic-table/basic-table.component'; +import { AppDynamicTableComponent } from './dynamic-table/dynamic-table.component'; +import { AppExpandTableComponent } from './expand-table/expand-table.component'; +import { AppFooterRowTableComponent } from './footer-row-table/footer-row-table.component'; +import { AppHttpTableComponent } from './http-table/http-table.component'; +import { AppMixTableComponent } from './mix-table/mix-table.component'; +import { AppMultiHeaderFooterTableComponent } from './multi-header-footer-table/multi-header-footer-table.component'; +import { AppPaginationTableComponent } from './pagination-table/pagination-table.component'; +import { AppRowContextTableComponent } from './row-context-table/row-context-table.component'; +import { AppSelectionTableComponent } from './selection-table/selection-table.component'; +import { AppSortableTableComponent } from './sortable-table/sortable-table.component'; +import { AppStickyColumnTableComponent } from './sticky-column-table/sticky-column-table.component'; +import { AppStickyHeaderFooterTableComponent } from './sticky-header-footer-table/sticky-header-footer-table.component'; +import { AppFilterableTableComponent } from './filterable-table/filterable-table.component'; + +@NgModule({ + imports: [ + RouterModule.forChild(TablesRoutes), + + AppBasicTableComponent, + AppDynamicTableComponent, + AppExpandTableComponent, + AppFooterRowTableComponent, + AppHttpTableComponent, + AppMixTableComponent, + AppMultiHeaderFooterTableComponent, + AppPaginationTableComponent, + AppRowContextTableComponent, + AppSelectionTableComponent, + AppSortableTableComponent, + AppStickyColumnTableComponent, + AppStickyHeaderFooterTableComponent, + AppFilterableTableComponent, + ], + declarations: [], +}) +export class TablesModule {} diff --git a/theme/packages/main/src/app/pages/tables/tables.routes.ts b/theme/packages/main/src/app/pages/tables/tables.routes.ts new file mode 100644 index 0000000..180da2b --- /dev/null +++ b/theme/packages/main/src/app/pages/tables/tables.routes.ts @@ -0,0 +1,179 @@ +import { Routes } from '@angular/router'; + +// tables +import { AppBasicTableComponent } from './basic-table/basic-table.component'; +import { AppDynamicTableComponent } from './dynamic-table/dynamic-table.component'; +import { AppExpandTableComponent } from './expand-table/expand-table.component'; +import { AppFooterRowTableComponent } from './footer-row-table/footer-row-table.component'; +import { AppHttpTableComponent } from './http-table/http-table.component'; +import { AppMixTableComponent } from './mix-table/mix-table.component'; +import { AppMultiHeaderFooterTableComponent } from './multi-header-footer-table/multi-header-footer-table.component'; +import { AppPaginationTableComponent } from './pagination-table/pagination-table.component'; +import { AppRowContextTableComponent } from './row-context-table/row-context-table.component'; +import { AppSelectionTableComponent } from './selection-table/selection-table.component'; +import { AppSortableTableComponent } from './sortable-table/sortable-table.component'; +import { AppStickyColumnTableComponent } from './sticky-column-table/sticky-column-table.component'; +import { AppStickyHeaderFooterTableComponent } from './sticky-header-footer-table/sticky-header-footer-table.component'; +import { AppFilterableTableComponent } from './filterable-table/filterable-table.component'; + +export const TablesRoutes: Routes = [ + { + path: '', + children: [ + { + path: 'basic-table', + component: AppBasicTableComponent, + data: { + title: 'Basic Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Basic Table' }, + ], + }, + }, + { + path: 'dynamic-table', + component: AppDynamicTableComponent, + data: { + title: 'Dynamic Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Dynamic Table' }, + ], + }, + }, + { + path: 'expand-table', + component: AppExpandTableComponent, + data: { + title: 'Expand Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Expand Table' }, + ], + }, + }, + { + path: 'filterable-table', + component: AppFilterableTableComponent, + data: { + title: 'Filterable Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Filterable Table' }, + ], + }, + }, + { + path: 'footer-row-table', + component: AppFooterRowTableComponent, + data: { + title: 'Footer Row Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Footer Row Table' }, + ], + }, + }, + { + path: 'http-table', + component: AppHttpTableComponent, + data: { + title: 'HTTP Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'HTTP Table' }, + ], + }, + }, + { + path: 'mix-table', + component: AppMixTableComponent, + data: { + title: 'Mix Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Mix Table' }, + ], + }, + }, + { + path: 'multi-header-footer-table', + component: AppMultiHeaderFooterTableComponent, + data: { + title: 'Multi Header Footer Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Multi Header Footer Table' }, + ], + }, + }, + { + path: 'pagination-table', + component: AppPaginationTableComponent, + data: { + title: 'Pagination Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Pagination Table' }, + ], + }, + }, + { + path: 'row-context-table', + component: AppRowContextTableComponent, + data: { + title: 'Row Context Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Row Context Table' }, + ], + }, + }, + { + path: 'selection-table', + component: AppSelectionTableComponent, + data: { + title: 'Selection Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Selection Table' }, + ], + }, + }, + { + path: 'sortable-table', + component: AppSortableTableComponent, + data: { + title: 'Sortable Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Sortable Table' }, + ], + }, + }, + { + path: 'sticky-column-table', + component: AppStickyColumnTableComponent, + data: { + title: 'Sticky Column Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Sticky Column Table' }, + ], + }, + }, + { + path: 'sticky-header-footer-table', + component: AppStickyHeaderFooterTableComponent, + data: { + title: 'Sticky Header Footer Table', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Sticky Header Footer Table' }, + ], + }, + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/pages/theme-pages/account-setting/account-setting.component.html b/theme/packages/main/src/app/pages/theme-pages/account-setting/account-setting.component.html new file mode 100644 index 0000000..695b1a7 --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/account-setting/account-setting.component.html @@ -0,0 +1,724 @@ + + + + + +
+ + + +
+ Account +
+ +
+
+ + + Change Profile + Change your profile picture from here +
+ +
+ + +
+ Allowed JPG, GIF or PNG. Max size of 800K +
+
+
+
+
+ + + Change Password + To change your password please confirm + here +
+ + Current Password + + + + + New Password + + + + + Confirm Password + + + +
+
+
+
+
+ + + Personal Details + To change your personal detail , edit and save from + here + +
+
+ + Your Name + + + + + Location + + + India + United States + United Kingdom + Russia + + + + Email + + + +
+
+ + Store Name + + + + + Currency + + + India (INR) + Us Dollar ($) + United Kingdom(Pound) + Russia (Ruble) + + + + Phone + + + +
+
+ + Address + + + +
+
+
+
+
+
+
+
+ + +
+ + + +
+ Notifications +
+ +
+
+ + + Notification Preferences + Select the notificaitons ou would like to receive via + email. Please note that you cannot opt out of receving + service messages, such as payment, security or legal + notifications. + + + Email Address* + + + Required for notificaitons. + + +
+ +
+
Our newsletter
+
+ We'll always let you know about important + changes + +
+
+
+
+ +
+
+ Order Confirmation +
+
+ You will be notified when customer order any + product + +
+
+
+
+ +
+
+ Order Status Changed +
+
+ You will be notified when customer make changes to + the order + +
+
+
+
+ +
+
Order Delivered
+
+ You will be notified once the order is + delivered + +
+
+
+
+ +
+
+ Email Notification +
+
+ Turn on email notificaiton to get updates through + email + +
+
+
+
+
+ + + + Date & Time + Time zones and calendar display + settings. + +
+ +
+ Time zone +
+ (UTC + 02:00) Athens, Bucharet +
+
+ + + +
+
+
+ + + + Ignore Tracking + +
+ +
+
+ Ignore Browser Tracking +
+ Browser Cookie +
+ +
+
+
+
+
+
+
+ + +
+ + + +
+ Bills +
+ +
+
+ + + Billing Information + +
+
+ + Business Name* + + + + + Business Address* + + + + + First Name* + + + +
+
+ + Business Sector* + + + + + Country* + + + + + Last Name* + + + +
+
+
+
+ + + + Current Plan : Execusive + + Thanks for being a premium member and supporting our + development. + +
+ +
+ Current Plan +
+ 750.000 Monthly Visits +
+
+ + + +
+ +
+ + +
+
+
+ + + + Payment Method + On 26 December, 2023 + +
+ +
+ Visa +
*****2102
+
+ + + +
+ +
+ +
+
+
+
+
+
+
+ + +
+ + + +
+ Security +
+ +
+
+ + + Two-factor Authentication +
+ Lorem ipsum, dolor sit amet consectetur adipisicing elit. + Corporis sapiente sunt earum officiis laboriosam + ut. + +
+ +
+
+
Authentication App
+ Google auth app +
+ + +
+ +
+
+
Another e-mail
+ E-mail to send verification link +
+ + +
+ +
+
+
SMS Recovery
+ Your phone number or something +
+ + +
+ +
+
+
+
+ + + + Devices + Lorem ipsum dolor sit amet consectetur adipisicing elit + Rem. + + +
+ + + +
+ iPhone 14 + London UK, Oct 23 at 1:15 AM + +
+ +
+
+ + + +
+ Macbook Air + Gujarat India, Oct 24 at 3:15 AM + +
+ +
+ +
+
+
+
+
+
+
+
+ + +
+
diff --git a/theme/packages/main/src/app/pages/theme-pages/account-setting/account-setting.component.ts b/theme/packages/main/src/app/pages/theme-pages/account-setting/account-setting.component.ts new file mode 100644 index 0000000..67ae4ea --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/account-setting/account-setting.component.ts @@ -0,0 +1,20 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatSelectModule } from '@angular/material/select'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatTabsModule } from '@angular/material/tabs'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import {MatDividerModule} from '@angular/material/divider'; + +@Component({ + selector: 'app-account-setting', + imports: [MatCardModule, MatIconModule, TablerIconsModule, MatTabsModule, MatFormFieldModule, MatSlideToggleModule, MatSelectModule, MatInputModule, MatButtonModule, MatDividerModule], + templateUrl: './account-setting.component.html' +}) +export class AppAccountSettingComponent { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/theme-pages/faq/faq.component.html b/theme/packages/main/src/app/pages/theme-pages/faq/faq.component.html new file mode 100644 index 0000000..850314e --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/faq/faq.component.html @@ -0,0 +1,86 @@ +
+
+ Frequently asked questions + Get to know more about ready-to-use admin dashboard + templates + + + + + + What is an Admin Dashboard? + + +

+ Admin Dashboard is the backend interface of a website or an + application that helps to manage the website's overall content and + settings. It is widely used by the site owners to keep track of their + website, make changes to their content, and more. +

+
+ + + + What should an admin dashboard template include? + + +

+ Admin dashboard template should include user & SEO friendly design + with a variety of components and application designs to help create + your own web application with ease. This could include customization + options, technical support and about 6 months of future updates. +

+
+ + + + Why should I buy admin templates from AdminMart? + + +

+ Adminmart offers high-quality templates that are easy to use and fully + customizable. With over 101,801 happy customers & trusted by 10,000+ + Companies. AdminMart is recognized as the leading online source for + buying admin templates. +

+
+ + + + Do Adminmart offers a money back guarantee? + + +

+ There is no money back guarantee in most companies, but if you are + unhappy with our product, Adminmart gives you a 100% money back + guarantee. +

+
+
+
+ +
+ + + +
+ user1 + user2 + user3 +
+ + +

Still have questions

+ Can't find the answer your're looking for ? Please chat to our + friendly team. + +
+
+
+
diff --git a/theme/packages/main/src/app/pages/theme-pages/faq/faq.component.ts b/theme/packages/main/src/app/pages/theme-pages/faq/faq.component.ts new file mode 100644 index 0000000..5201cf1 --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/faq/faq.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatExpansionModule } from '@angular/material/expansion'; +@Component({ + selector: 'app-faq', + imports: [MatCardModule, MatExpansionModule, MatButtonModule], + templateUrl: './faq.component.html' +}) +export class AppFaqComponent { + constructor() {} + + // 1 basic + panelOpenState = false; +} diff --git a/theme/packages/main/src/app/pages/theme-pages/landingpage/landingpage.component.html b/theme/packages/main/src/app/pages/theme-pages/landingpage/landingpage.component.html new file mode 100644 index 0000000..7cebc95 --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/landingpage/landingpage.component.html @@ -0,0 +1,751 @@ + + + + +
+ +
+ +
+ + + + + +
+ + + + + + + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently + Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ + Documentation + Support + Login +
+ + + +
+
+ + + + + + + + +
+
+
+
+
+ + 52,589+ developers & agencies + using our templates +
+

+ Production Ready & Developer Friendly Material Angular Admin + Template +

+
+
+
+ + Demos + +
+
+ +
+ @for(demo of demos; track demo.url) { +
+
+ + {{ + demo.name + }} +
+
+ } +
+
+ + Apps + +
+ +
+ @for(app of appdemos; track app.url) { +
+
+ + {{ + app.name + }} +
+
+ } +
+
+
+
+ + + +
+
+
+
+

+ Increase speed of your development and launch quickly with + Modernize +

+
+
+
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+ + + + +
+
+
+
+

+ Don’t just take our words for it, See what developers like you are + saying +

+
+
+ +
+ @for(testimonial of testimonials; track testimonial.name) { +
+ + +
+ profile +
+
+ {{ testimonial.name }} +
+ {{ testimonial.subtext }} +
+
+
+ + + + + +
+
+
+

+ {{ testimonial.feedback }} +

+
+
+
+ } +
+
+
+ + + +
+
+
+
+ ALMOST COVERED EVERYTHING +

+ Other Amazing Features & Flexibility Provided +

+
+
+ + +
+ @for(feature of features; track feature.title) { +
+ +
{{ feature.title }}
+ {{ + feature.subtext + }} +
+ } +
+
+
+ + + + +
+
+
+ + +

+ Haven't found an answer to your question? +

+ Connect with us either on discord or email us + +
+
+
+
+
+ + + + +
+
+
+
+
+

+ Build your app with our highly customizable Angular based + Dashboard +

+
+ Login + Register +
+
+
+
+ img +
+
+
+
+ + + + +
+
+
+
+ + logo + +
+ All rights reserved by Modernize. Designed & Developed by + AdminMart . +
+
+
+
+
+ + +
+ + + +
+
+ @if(options.theme === 'light') { + + logo + + } @if(options.theme === 'dark') { + + logo + + } +
+ + + + + Demos + +
+
Different Demos
+ Included with the package +
+ @for(demo of demos; track demo.url) { +
+
+ + {{ + demo.name + }} +
+
+ } +
+ +
Different Apps
+
+ @for(app of appdemos; track app.url) { +
+
+ + {{ + app.name + }} +
+
+ } +
+
+
+ + + Pages + +
+
+ @for(appdd of apps; track appdd.img) { + + } +
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+ + +
+
+
diff --git a/theme/packages/main/src/app/pages/theme-pages/landingpage/landingpage.component.ts b/theme/packages/main/src/app/pages/theme-pages/landingpage/landingpage.component.ts new file mode 100644 index 0000000..db361ed --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/landingpage/landingpage.component.ts @@ -0,0 +1,410 @@ +import { Component, Output, EventEmitter, Input } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { ViewportScroller } from '@angular/common'; +import { MaterialModule } from 'src/app/material.module'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { RouterLink } from '@angular/router'; +import { BrandingComponent } from '../../../layouts/full/vertical/sidebar/branding.component'; + +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +interface demos { + id: number; + name: string; + url: string; + imgSrc: string; +} + +interface testimonials { + id: number; + name: string; + subtext: string; + imgSrc: string; + feedback: string; +} + +interface features { + id: number; + icon: string; + title: string; + subtext: string; +} + +@Component({ + selector: 'app-landingpage', + imports: [MaterialModule, TablerIconsModule, RouterLink, BrandingComponent], + templateUrl: './landingpage.component.html', +}) +export class AppLandingpageComponent { + @Input() showToggle = true; + @Output() toggleMobileNav = new EventEmitter(); + @Output() toggleMobileFilterNav = new EventEmitter(); + @Output() toggleCollapsed = new EventEmitter(); + + options = this.settings.getOptions(); + + constructor( + private settings: CoreService, + private scroller: ViewportScroller + ) {} + + ngOnInit(): void {} + + // scroll to demos + gotoDemos() { + this.scroller.scrollToAnchor('demos'); + } + + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/apps/chat', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'Todo App', + subtitle: 'New task', + link: '/apps/todo', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/apps/invoice', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/apps/calendar', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/apps/contacts', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/apps/tickets', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/apps/email/inbox', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Contact List', + subtitle: 'Create new contact', + link: '/apps/contact-list', + }, + ]; + + demos: demos[] = [ + { + id: 1, + imgSrc: '/assets/images/landingpage/demos/demo-main.jpg', + name: 'Main', + url: 'https://modernize-angular-main.netlify.app/dashboards/dashboard1', + }, + { + id: 2, + imgSrc: '/assets/images/landingpage/demos/demo-dark.jpg', + name: 'Dark', + url: 'https://modernize-angular-dark.netlify.app/dashboards/dashboard2', + }, + { + id: 3, + imgSrc: '/assets/images/landingpage/demos/demo-firebase.jpg', + name: 'Authguard', + url: 'https://modernize-angular-authguard.netlify.app/authentication/login', + }, + { + id: 4, + imgSrc: '/assets/images/landingpage/demos/demo-rtl.jpg', + name: 'RTL', + url: 'https://modernize-angular-rtl.netlify.app/dashboards/dashboard1', + }, + { + id: 5, + imgSrc: '/assets/images/landingpage/demos/demo-minisidebar.jpg', + name: 'Minisidebar', + url: 'https://modernize-angular-minisidebar.netlify.app/dashboards/dashboard1', + }, + { + id: 6, + imgSrc: '/assets/images/landingpage/demos/demo-horizontal.jpg', + name: 'Horizontal', + url: 'https://modernize-angular-horizontal.netlify.app/dashboards/dashboard2', + }, + ]; + + appdemos: demos[] = [ + { + id: 1, + imgSrc: '/assets/images/landingpage/apps/app-calendar.jpg', + name: 'Calendar', + url: 'https://modernize-angular-main.netlify.app/apps/calendar', + }, + { + id: 2, + imgSrc: '/assets/images/landingpage/apps/app-chat.jpg', + name: 'Chat', + url: 'https://modernize-angular-main.netlify.app/apps/chat', + }, + { + id: 3, + imgSrc: '/assets/images/landingpage/apps/app-contact.jpg', + name: 'Contact', + url: 'https://modernize-angular-main.netlify.app/apps/contacts', + }, + { + id: 4, + imgSrc: '/assets/images/landingpage/apps/app-email.jpg', + name: 'Email', + url: 'https://modernize-angular-main.netlify.app/apps/email/inbox', + }, + { + id: 5, + imgSrc: '/assets/images/landingpage/apps/app-contact-list.jpg', + name: 'Contact List', + url: 'https://modernize-angular-main.netlify.app/apps/contact-list', + }, + { + id: 6, + imgSrc: '/assets/images/landingpage/apps/app-employee.jpg', + name: 'Employee', + url: 'https://modernize-angular-main.netlify.app/apps/employee', + }, + { + id: 7, + imgSrc: '/assets/images/landingpage/apps/app-note.jpg', + name: 'Notes', + url: 'https://modernize-angular-main.netlify.app/apps/notes', + }, + { + id: 8, + imgSrc: '/assets/images/landingpage/apps/app-ticket.jpg', + name: 'Tickets', + url: 'https://modernize-angular-main.netlify.app/apps/tickets', + }, + { + id: 9, + imgSrc: '/assets/images/landingpage/apps/app-invoice.jpg', + name: 'Invoice', + url: 'https://modernize-angular-main.netlify.app/apps/invoice', + }, + { + id: 10, + imgSrc: '/assets/images/landingpage/apps/app-todo.jpg', + name: 'Todo', + url: 'https://modernize-angular-main.netlify.app/apps/todo', + }, + { + id: 11, + imgSrc: '/assets/images/landingpage/apps/app-taskboard.jpg', + name: 'Kanban', + url: 'https://modernize-angular-main.netlify.app/apps/kanban', + }, + { + id: 12, + imgSrc: '/assets/images/landingpage/apps/app-blog.jpg', + name: 'Blog List', + url: 'https://modernize-angular-main.netlify.app/apps/blog/post', + }, + ]; + + testimonials: testimonials[] = [ + { + id: 1, + imgSrc: '/assets/images/profile/user-1.jpg', + name: 'Jenny Wilson', + subtext: 'Features avaibility', + feedback: + ' The quality of design is excellent, customizability and flexibility much better than the other products available in the market. I strongly recommend the AdminMart to other buyers.', + }, + { + id: 2, + imgSrc: '/assets/images/profile/user-2.jpg', + name: 'Minshan Cui', + subtext: 'Features avaibility', + feedback: + ' The dashboard template from adminmart has helped me provide a clean and sleek look to my dashboard and made it look exactly the way I wanted it to, mainly without having. ', + }, + { + id: 3, + imgSrc: '/assets/images/profile/user-3.jpg', + name: 'Eminson Mendoza', + subtext: 'Features avaibility', + feedback: + 'This template is great, UI-rich and up-to-date. Although it is pretty much complete, I suggest to improve a bit of documentation. Thanks & Highly recomended! ', + }, + ]; + + features: features[] = [ + { + id: 1, + icon: 'wand', + title: '6 Theme Colors', + subtext: + 'We have included 6 pre-defined Theme Colors with Modernize Admin.', + }, + { + id: 2, + icon: 'shield-lock', + title: 'Authguard', + subtext: + 'AuthGuard is used to protect the routes from unauthorized access in angular.', + }, + { + id: 15, + icon: 'code', + title: 'Based on M3', + subtext: + 'Material Design 3 is the latest iteration of Google Material Design system', + }, + { + id: 3, + icon: 'archive', + title: '80+ Page Templates', + subtext: 'Yes, we have 6 demos & 80+ Pages per demo to make it easier.', + }, + { + id: 4, + icon: 'adjustments', + title: '50+ UI Components', + subtext: + 'Almost 50+ UI Components being given with Modernize Admin Pack.', + }, + { + id: 5, + icon: 'tag', + title: 'Material ', + subtext: 'Its been made with Material and full responsive layout.', + }, + { + id: 6, + icon: 'diamond', + title: '3400+ Font Icons', + subtext: + 'Lots of Icon Fonts are included here in the package of Modernize Admin.', + }, + { + id: 7, + icon: 'language-katakana', + title: 'i18 Angular', + subtext: 'i18 is a powerful internationalization framework for Angular.', + }, + { + id: 8, + icon: 'arrows-shuffle', + title: 'Easy to Customize', + subtext: 'Customization will be easy as we understand your pain.', + }, + { + id: 9, + icon: 'chart-pie', + title: 'Lots of Chart Options', + subtext: 'You name it and we have it, Yes lots of variations for Charts.', + }, + { + id: 10, + icon: 'layers-intersect', + title: 'Lots of Table Examples', + subtext: 'Data Tables are initial requirement and we added them.', + }, + { + id: 11, + icon: 'refresh', + title: 'Regular Updates', + subtext: 'We are constantly updating our pack with new features.', + }, + { + id: 12, + icon: 'book', + title: 'Detailed Documentation', + subtext: 'We have made detailed documentation, so it will easy to use.', + }, + { + id: 13, + icon: 'calendar', + title: 'Calendar Design', + subtext: 'Calendar is available with our package & in nice design.', + }, + { + id: 14, + icon: 'messages', + title: 'Dedicated Support', + subtext: 'We believe in supreme support is key and we offer that.', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/theme-pages/pricing', + }, + { + id: 2, + title: 'Authentication Design', + link: '/authentication/login', + }, + { + id: 3, + title: 'Register Now', + link: '/authentication/side-register', + }, + { + id: 4, + title: '404 Error Page', + link: '/authentication/error', + }, + { + id: 5, + title: 'Notes App', + link: '/apps/notes', + }, + { + id: 6, + title: 'Employee App', + link: '/apps/employee', + }, + { + id: 7, + title: 'Todo Application', + link: '/apps/todo', + }, + { + id: 8, + title: 'Treeview', + link: '/theme-pages/treeview', + }, + ]; +} diff --git a/theme/packages/main/src/app/pages/theme-pages/landingpage/landingpage.routes.ts b/theme/packages/main/src/app/pages/theme-pages/landingpage/landingpage.routes.ts new file mode 100644 index 0000000..80d9ec2 --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/landingpage/landingpage.routes.ts @@ -0,0 +1,16 @@ +import { Routes } from '@angular/router'; + +// theme pages +import { AppLandingpageComponent } from './landingpage.component'; + +export const LandingPageRoutes: Routes = [ + { + path: '', + children: [ + { + path: '', + component: AppLandingpageComponent, + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/pages/theme-pages/pricing/pricing.component.html b/theme/packages/main/src/app/pages/theme-pages/pricing/pricing.component.html new file mode 100644 index 0000000..8c9d56b --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/pricing/pricing.component.html @@ -0,0 +1,74 @@ +
+
+

+ Flexible Plans Tailored to Fit Your Community's Unique Needs! +

+
+ Monthly + Yearly +
+
+
+ +
+ @for(pricecard of pricecards; track pricecard.plan) { +
+ + + @if(pricecard.popular) { + Popular + } + + {{ + pricecard.plan + }} + badge + + @if(pricecard.free) { +

Free

+ } @else { +
+ @if(show) { +
+
+ $ +

+ {{ yearlyPrice(pricecard.planPrice) }} +

+ /mo +
+
+ } @else { +
+ $ +

+ {{ pricecard.planPrice }} +

+ /mo +
+ } +
+ } + @for(rule of pricecard.rules; track rule){ +
+ @if(rule.limit) { +
+ + {{ rule.title }} +
+ + } @else { + + {{ rule.title }} + } +
+ } + +
+
+
+ } +
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/theme-pages/pricing/pricing.component.ts b/theme/packages/main/src/app/pages/theme-pages/pricing/pricing.component.ts new file mode 100644 index 0000000..316f79e --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/pricing/pricing.component.ts @@ -0,0 +1,133 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +// card 1 +interface rules { + title: string; + limit: boolean; +} + +interface pricecards { + id: number; + imgSrc: string; + plan: string; + btnText: string; + free: boolean; + planPrice?: Number; + popular?: boolean; + rules: rules[]; +} + +@Component({ + selector: 'app-pricing', + imports: [TablerIconsModule, MatCardModule, MatSlideToggleModule, MatButtonModule, MatSlideToggleModule], + templateUrl: './pricing.component.html', +}) +export class AppPricingComponent { + show = false; + + // yearlyPrice: any = (a: any, b: number) => ; + + yearlyPrice(a: any) { + return a * 12; + } + + // card 1 + pricecards: pricecards[] = [ + { + id: 1, + plan: 'Silver', + imgSrc: '/assets/images/backgrounds/silver.png', + btnText: 'Choose Silver', + free: true, + rules: [ + { + title: '3 Members', + limit: true, + }, + { + title: 'Single Device', + limit: true, + }, + { + title: '50GB Storage', + limit: false, + }, + { + title: 'Monthly Backups', + limit: false, + }, + { + title: 'Permissions & workflows', + limit: false, + }, + ], + }, + { + id: 2, + plan: 'Bronze', + imgSrc: '/assets/images/backgrounds/bronze.png', + btnText: 'Choose Bronze', + free: false, + popular: true, + planPrice: 10.99, + rules: [ + { + title: '5 Members', + limit: true, + }, + { + title: 'Multiple Device', + limit: true, + }, + { + title: '80GB Storage', + limit: false, + }, + { + title: 'Monthly Backups', + limit: false, + }, + { + title: 'Permissions & workflows', + limit: false, + }, + ], + }, + { + id: 3, + plan: 'Gold', + imgSrc: '/assets/images/backgrounds/gold.png', + btnText: 'Choose Gold ', + free: false, + planPrice: 22.99, + rules: [ + { + title: 'Unlimited Members', + limit: true, + }, + { + title: 'Multiple Device', + limit: true, + }, + { + title: '150GB Storage', + limit: true, + }, + { + title: 'Monthly Backups', + limit: true, + }, + { + title: 'Permissions & workflows', + limit: true, + }, + ], + }, + ]; + + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/theme-pages/theme-pages.routes.ts b/theme/packages/main/src/app/pages/theme-pages/theme-pages.routes.ts new file mode 100644 index 0000000..b51fd7c --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/theme-pages.routes.ts @@ -0,0 +1,59 @@ +import { Routes } from '@angular/router'; + +// theme pages +import { AppAccountSettingComponent } from './account-setting/account-setting.component'; +import { AppFaqComponent } from './faq/faq.component'; +import { AppPricingComponent } from './pricing/pricing.component'; +import { AppTreeviewComponent } from './treeview/treeview.component'; + +export const ThemePagesRoutes: Routes = [ + { + path: '', + children: [ + { + path: 'account-setting', + component: AppAccountSettingComponent, + data: { + title: 'Account Setting', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Account Setting' }, + ], + }, + }, + { + path: 'faq', + component: AppFaqComponent, + data: { + title: 'FAQ', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'FAQ' }, + ], + }, + }, + { + path: 'pricing', + component: AppPricingComponent, + data: { + title: 'Pricing', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Pricing' }, + ], + }, + }, + { + path: 'treeview', + component: AppTreeviewComponent, + data: { + title: 'Treeview', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Treeview' }, + ], + }, + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/pages/theme-pages/treeview/treeview.component.html b/theme/packages/main/src/app/pages/theme-pages/treeview/treeview.component.html new file mode 100644 index 0000000..a4f7528 --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/treeview/treeview.component.html @@ -0,0 +1,66 @@ + +
+ Treeview +
+ + + + + {{ node.item }} + + + + +
+ + New item... + + + +
+
+ + + + {{ node.item }} + + +
+
+
diff --git a/theme/packages/main/src/app/pages/theme-pages/treeview/treeview.component.ts b/theme/packages/main/src/app/pages/theme-pages/treeview/treeview.component.ts new file mode 100644 index 0000000..de8875d --- /dev/null +++ b/theme/packages/main/src/app/pages/theme-pages/treeview/treeview.component.ts @@ -0,0 +1,279 @@ +import { SelectionModel } from '@angular/cdk/collections'; +import { FlatTreeControl } from '@angular/cdk/tree'; +import { Component, Injectable } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { + MatTreeFlatDataSource, + MatTreeFlattener, + MatTreeModule, +} from '@angular/material/tree'; +import { BehaviorSubject } from 'rxjs'; + +export class TodoItemNode { + children: TodoItemNode[]; + item: string; +} + +/** Flat to-do item node with expandable and level information */ +export class TodoItemFlatNode { + item: string; + level: number; + expandable: boolean; +} + +const TREE_DATA = { + Groceries: { + 'Almond Meal flour': null, + 'Organic eggs': null, + 'Protein Powder': null, + Fruits: { + Apple: null, + Berries: ['Blueberry', 'Raspberry'], + Orange: null, + }, + }, + Reminders: [ + 'Cook dinner', + 'Read the Material Design spec', + 'Upgrade Application to Angular', + ], +}; + +@Injectable() +export class ChecklistDatabase { + dataChange = new BehaviorSubject([]); + + get data(): TodoItemNode[] { + return this.dataChange.value; + } + + constructor() { + this.initialize(); + } + + initialize() { + // Build the tree nodes from Json object. The result is a list of `TodoItemNode` with nested + // file node as children. + const data = this.buildFileTree(TREE_DATA, 0); + + // Notify the change. + this.dataChange.next(data); + } + + /** + * Build the file structure tree. The `value` is the Json object, or a sub-tree of a Json object. + * The return value is the list of `TodoItemNode`. + */ + buildFileTree(obj: { [key: string]: any }, level: number): TodoItemNode[] { + return Object.keys(obj).reduce((accumulator, key) => { + const value = obj[key]; + const node = new TodoItemNode(); + node.item = key; + + if (value != null) { + if (typeof value === 'object') { + node.children = this.buildFileTree(value, level + 1); + } else { + node.item = value; + } + } + + return accumulator.concat(node); + }, []); + } + + /** Add an item to to-do list */ + insertItem(parent: TodoItemNode, name: string) { + if (parent.children) { + parent.children.push({ item: name } as TodoItemNode); + this.dataChange.next(this.data); + } + } + + updateItem(node: TodoItemNode, name: string) { + node.item = name; + this.dataChange.next(this.data); + } +} + +@Component({ + selector: 'app-treeview', + imports: [MatIconModule, MatCheckboxModule, MatFormFieldModule, MatTreeModule, MatCardModule, MatButtonModule, MatFormFieldModule, MatInputModule], + templateUrl: './treeview.component.html', + providers: [ChecklistDatabase] +}) +export class AppTreeviewComponent { + /** Map from flat node to nested node. This helps us finding the nested node to be modified */ + flatNodeMap = new Map(); + + /** Map from nested node to flattened node. This helps us to keep the same object for selection */ + nestedNodeMap = new Map(); + + /** A selected parent node to be inserted */ + selectedParent: TodoItemFlatNode | null = null; + + /** The new item's name */ + newItemName = ''; + + treeControl: FlatTreeControl; + + treeFlattener: MatTreeFlattener; + + dataSource: MatTreeFlatDataSource; + + /** The selection for checklist */ + checklistSelection = new SelectionModel( + true /* multiple */ + ); + + constructor(private _database: ChecklistDatabase) { + this.treeFlattener = new MatTreeFlattener( + this.transformer, + this.getLevel, + this.isExpandable, + this.getChildren + ); + this.treeControl = new FlatTreeControl( + this.getLevel, + this.isExpandable + ); + this.dataSource = new MatTreeFlatDataSource( + this.treeControl, + this.treeFlattener + ); + + _database.dataChange.subscribe((data) => { + this.dataSource.data = data; + }); + } + + getLevel = (node: TodoItemFlatNode) => node.level; + + isExpandable = (node: TodoItemFlatNode) => node.expandable; + + getChildren = (node: TodoItemNode): TodoItemNode[] => node.children; + + hasChild = (_: number, _nodeData: TodoItemFlatNode) => _nodeData.expandable; + + hasNoContent = (_: number, _nodeData: TodoItemFlatNode) => + _nodeData.item === ''; + + /** + * Transformer to convert nested node to flat node. Record the nodes in maps for later use. + */ + transformer = (node: TodoItemNode, level: number) => { + const existingNode = this.nestedNodeMap.get(node); + const flatNode = + existingNode && existingNode.item === node.item + ? existingNode + : new TodoItemFlatNode(); + flatNode.item = node.item; + flatNode.level = level; + flatNode.expandable = !!node.children?.length; + this.flatNodeMap.set(flatNode, node); + this.nestedNodeMap.set(node, flatNode); + return flatNode; + }; + + /** Whether all the descendants of the node are selected. */ + descendantsAllSelected(node: TodoItemFlatNode): boolean { + const descendants = this.treeControl.getDescendants(node); + const descAllSelected = + descendants.length > 0 && + descendants.every((child) => { + return this.checklistSelection.isSelected(child); + }); + return descAllSelected; + } + + /** Whether part of the descendants are selected */ + descendantsPartiallySelected(node: TodoItemFlatNode): boolean { + const descendants = this.treeControl.getDescendants(node); + const result = descendants.some((child) => + this.checklistSelection.isSelected(child) + ); + return result && !this.descendantsAllSelected(node); + } + + /** Toggle the to-do item selection. Select/deselect all the descendants node */ + todoItemSelectionToggle(node: TodoItemFlatNode): void { + this.checklistSelection.toggle(node); + const descendants = this.treeControl.getDescendants(node); + this.checklistSelection.isSelected(node) + ? this.checklistSelection.select(...descendants) + : this.checklistSelection.deselect(...descendants); + + // Force update for the parent + descendants.forEach((child) => this.checklistSelection.isSelected(child)); + this.checkAllParentsSelection(node); + } + + /** Toggle a leaf to-do item selection. Check all the parents to see if they changed */ + todoLeafItemSelectionToggle(node: TodoItemFlatNode): void { + this.checklistSelection.toggle(node); + this.checkAllParentsSelection(node); + } + + /* Checks all the parents when a leaf node is selected/unselected */ + checkAllParentsSelection(node: TodoItemFlatNode): void { + let parent: TodoItemFlatNode | null = this.getParentNode(node); + while (parent) { + this.checkRootNodeSelection(parent); + parent = this.getParentNode(parent); + } + } + + /** Check root node checked state and change it accordingly */ + checkRootNodeSelection(node: TodoItemFlatNode): void { + const nodeSelected = this.checklistSelection.isSelected(node); + const descendants = this.treeControl.getDescendants(node); + const descAllSelected = + descendants.length > 0 && + descendants.every((child) => { + return this.checklistSelection.isSelected(child); + }); + if (nodeSelected && !descAllSelected) { + this.checklistSelection.deselect(node); + } else if (!nodeSelected && descAllSelected) { + this.checklistSelection.select(node); + } + } + + /* Get the parent node of a node */ + getParentNode(node: TodoItemFlatNode): TodoItemFlatNode | null { + const currentLevel = this.getLevel(node); + + if (currentLevel < 1) { + return null; + } + + const startIndex = this.treeControl.dataNodes.indexOf(node) - 1; + + for (let i = startIndex; i >= 0; i--) { + const currentNode = this.treeControl.dataNodes[i]; + + if (this.getLevel(currentNode) < currentLevel) { + return currentNode; + } + } + return null; + } + + /** Select the category so we can insert the new item. */ + addNewItem(node: TodoItemFlatNode) { + const parentNode = this.flatNodeMap.get(node); + this._database.insertItem(parentNode!, ''); + this.treeControl.expand(node); + } + + /** Save the node to database */ + saveNode(node: TodoItemFlatNode, itemValue: string) { + const nestedNode = this.flatNodeMap.get(node); + this._database.updateItem(nestedNode!, itemValue); + } +} diff --git a/theme/packages/main/src/app/pages/ui-components/badge/badge.component.html b/theme/packages/main/src/app/pages/ui-components/badge/badge.component.html new file mode 100644 index 0000000..4b4ba42 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/badge/badge.component.html @@ -0,0 +1,140 @@ + +
+ Badges +
+ + + + +
+
+ Text with a badge +
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +
+
+ Text with small badge +
+

+
+ Text with large badge +
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +
+

+ Button with a badge on the left + +

+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +
+

+ Icon with a badge + home +

+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +
+

+ Button toggles badge visibility + +

+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/badge/badge.component.ts b/theme/packages/main/src/app/pages/ui-components/badge/badge.component.ts new file mode 100644 index 0000000..0333e69 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/badge/badge.component.ts @@ -0,0 +1,63 @@ +import { Component, OnInit } from '@angular/core'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatCardModule } from '@angular/material/card'; +import { MatTabsModule } from '@angular/material/tabs'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { AppCodeViewComponent } from '../../../components/code-view/code-view.component'; + +// snippets +import { TEXT_WITH_BADGE_TS_SNIPPET, BUTTON_LEFT_WITH_BADGE_TS_SNIPPET, BUTTON_TOGGLES_WITH_BADGE_TS_SNIPPET } from './code/badge-ts-snippet'; +import { TEXT_WITH_BADGE_HTML_SNIPPET, SIZE_WITH_BADGE_HTML_SNIPPET, BUTTON_LEFT_WITH_BADGE_HTML_SNIPPET, ICON_WITH_BADGE_HTML_SNIPPET, BUTTON_TOGGLES_WITH_BADGE_HTML_SNIPPET } from './code/badge-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-badge', + templateUrl: './badge.component.html', + imports: [ + MatBadgeModule, + MatButtonModule, + MatIconModule, + MatCardModule, + MatTabsModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + TablerIconsModule, + AppCodeViewComponent, + ], +}) +export class AppBadgeComponent implements OnInit { + constructor() {} + + ngOnInit(): void {} + + hidden = false; + + toggleBadgeVisibility() { + this.hidden = !this.hidden; + } + + // 1 [text with badge] + codeForTextBadge = TEXT_WITH_BADGE_HTML_SNIPPET; + codeForTextBadgeTs = TEXT_WITH_BADGE_TS_SNIPPET; + + // 2 [size with badge] + codeForSizeBadge = SIZE_WITH_BADGE_HTML_SNIPPET; + codeForSizeBadgeTs = TEXT_WITH_BADGE_TS_SNIPPET; + + // 3 [button left position with badge] + codeForButtonBadge = BUTTON_LEFT_WITH_BADGE_HTML_SNIPPET; + codeForButtonBadgeTs = BUTTON_LEFT_WITH_BADGE_TS_SNIPPET; + + // 4 [icon with badge] + codeForIconBadge = ICON_WITH_BADGE_HTML_SNIPPET; + codeForIconBadgeTs = TEXT_WITH_BADGE_TS_SNIPPET; + + // 5 [button toggles with badge] + codeForButtonTogglesBadge = BUTTON_TOGGLES_WITH_BADGE_HTML_SNIPPET; + codeForButtonTogglesBadgeTs = BUTTON_TOGGLES_WITH_BADGE_TS_SNIPPET; +} diff --git a/theme/packages/main/src/app/pages/ui-components/badge/code/badge-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/badge/code/badge-html-snippet.ts new file mode 100644 index 0000000..ab1b4d0 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/badge/code/badge-html-snippet.ts @@ -0,0 +1,46 @@ +export const TEXT_WITH_BADGE_HTML_SNIPPET = `
+ Text with a badge +
+`; + +export const SIZE_WITH_BADGE_HTML_SNIPPET = `
+ Text with small badge +
+
+ Text with large badge +
+`; + +export const BUTTON_LEFT_WITH_BADGE_HTML_SNIPPET = `

+ Button with a badge on the left + +

+`; + +export const ICON_WITH_BADGE_HTML_SNIPPET = `

+ Icon with a badge + home +

+`; + +export const BUTTON_TOGGLES_WITH_BADGE_HTML_SNIPPET = `

+ Button toggles badge visibility + +

+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/badge/code/badge-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/badge/code/badge-ts-snippet.ts new file mode 100644 index 0000000..de4d11c --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/badge/code/badge-ts-snippet.ts @@ -0,0 +1,55 @@ +export const TEXT_WITH_BADGE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatBadgeModule} from '@angular/material/badge'; + + /** + * @title Badge overview + */ + @Component({ + selector: 'badge-overview-example', + templateUrl: 'badge-overview-example.html', + styleUrl: 'badge-overview-example.css', + imports: [MatBadgeModule], + }) + export class AppTextWithBadgeComponent { + + } +`; + +export const BUTTON_LEFT_WITH_BADGE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatBadgeModule} from '@angular/material/badge'; + import { MatButtonModule } from '@angular/material/button'; + + /** + * @title Badge overview + */ + @Component({ + selector: 'badge-overview-example', + templateUrl: 'badge-overview-example.html', + styleUrl: 'badge-overview-example.css', + imports: [MatBadgeModule, MatButtonModule], + }) + export class AppTextWithBadgeComponent { + + } +`; + + +export const BUTTON_TOGGLES_WITH_BADGE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatBadgeModule} from '@angular/material/badge'; + import { MatButtonModule } from '@angular/material/button'; + + /** + * @title Badge overview + */ + @Component({ + selector: 'badge-overview-example', + templateUrl: 'badge-overview-example.html', + styleUrl: 'badge-overview-example.css', + imports: [MatBadgeModule, MatButtonModule], + }) + export class AppTextWithBadgeComponent { + toggleBadgeVisibility() { + this.hidden = !this.hidden; + } + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/chips/chips.component.html b/theme/packages/main/src/app/pages/ui-components/chips/chips.component.html new file mode 100644 index 0000000..8cc6785 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/chips/chips.component.html @@ -0,0 +1,262 @@ + +
+ Chips +
+ +
+
+ + + + + + +

+ Basic +

+
+ + One fish + Two fish + Accent fish + Warn fish + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + + +

+ Avatar +

+
+ + + Photo of a Shiba Inu + Anderson + + + Photo of a Shiba Inu + Monty + + + Photo of a Shiba Inu + Mathew + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + + +

+ Drag n Drop +

+
+ + @for (vegetable of vegetables(); track vegetable.name) { + {{ + vegetable.name + }} + } + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + +

+ Stacked +

+ +
+ + @for (dog of bestBoys; track dog) { + {{dog}} + } + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + + +

+ Input +

+
+ + Favorite Fruits + + @for(fruit of fruits; track fruit.name) { + + {{ fruit.name }} + + + } + + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + + +

+ Form Control +

+
+
+ + +
+ + Video keywords + + @for (keyword of keywords(); track keyword) { + + {{ keyword }} + + + } + + + + +

+ The following keywords are entered: + {{ formControl.value }} +

+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/chips/chips.component.scss b/theme/packages/main/src/app/pages/ui-components/chips/chips.component.scss new file mode 100644 index 0000000..10964e6 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/chips/chips.component.scss @@ -0,0 +1,7 @@ +.example-box.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.example-chip .cdk-drop-list-dragging { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/chips/chips.component.ts b/theme/packages/main/src/app/pages/ui-components/chips/chips.component.ts new file mode 100644 index 0000000..28ae8e6 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/chips/chips.component.ts @@ -0,0 +1,195 @@ +import { COMMA, ENTER } from '@angular/cdk/keycodes'; +import { ThemePalette } from '@angular/material/core'; +import { + ChangeDetectionStrategy, + Component, + inject, + signal, +} from '@angular/core'; +import { + CdkDrag, + CdkDragDrop, + CdkDropList, + moveItemInArray, +} from '@angular/cdk/drag-drop'; +import { MatCardModule } from '@angular/material/card'; +import { + MatChipEditedEvent, + MatChipInputEvent, + MatChipsModule, +} from '@angular/material/chips'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { LiveAnnouncer } from '@angular/cdk/a11y'; +import { MatButtonModule } from '@angular/material/button'; + + +// snippets +import { BASIC_CHIPS_TS_SNIPPET, DRAG_DROP_CHIPS_TS_SNIPPET, FORM_CONTROL_CHIPS_TS_SNIPPET, INPUT_CHIPS_TS_SNIPPET, STACKED_CHIPS_TS_SNIPPET } from './code/chips-ts-snippet'; +import { BASIC_CHIPS_HTML_SNIPPET, AVATAR_CHIPS_HTML_SNIPPET, DRAG_DROP_CHIPS_HTML_SNIPPET, STACKED_CHIPS_HTML_SNIPPET, INPUT_CHIPS_HTML_SNIPPET, FORM_CONTROL_CHIPS_HTML_SNIPPET } from './code/chips-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +export interface ChipColor { + name: string; + color: ThemePalette; +} + +export interface Fruit { + name: string; +} + +export interface Vegetable { + name: string; +} + +@Component({ + selector: 'app-chips', + templateUrl: './chips.component.html', + styleUrls: ['./chips.component.scss'], + imports: [ + MatFormFieldModule, + MatChipsModule, + MatIconModule, + MatCardModule, + CdkDropList, + CdkDrag, + FormsModule, + ReactiveFormsModule, + MatButtonModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent + ], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class AppChipsComponent { + + // 1 [basic with chip] + codeForBasicChips = BASIC_CHIPS_HTML_SNIPPET; + codeForBasicChipsTs = BASIC_CHIPS_TS_SNIPPET; + + // 2 [avatar with chip] + codeForAvatarChips = AVATAR_CHIPS_HTML_SNIPPET; + codeForAvatarChipsTs = BASIC_CHIPS_TS_SNIPPET; + + // 3 [avatar with chip] + codeForDragDropChips = DRAG_DROP_CHIPS_HTML_SNIPPET; + codeForDragDropChipsTs = DRAG_DROP_CHIPS_TS_SNIPPET; + + // 4 [Stacked with chip] + codeForStackedChips = STACKED_CHIPS_HTML_SNIPPET; + codeForStackedChipsTs = STACKED_CHIPS_TS_SNIPPET; + + // 5 [Input with chip] + codeForInputChips = INPUT_CHIPS_HTML_SNIPPET; + codeForInputChipsTs = INPUT_CHIPS_TS_SNIPPET; + + // 6 [Form Control with chip] + codeForFormControlChips = FORM_CONTROL_CHIPS_HTML_SNIPPET; + codeForFormControlChipsTs = FORM_CONTROL_CHIPS_TS_SNIPPET; + + // drag n drop + readonly vegetables = signal([ + { name: 'apple' }, + { name: 'banana' }, + { name: 'strawberry' }, + { name: 'orange' }, + { name: 'kiwi' }, + { name: 'cherry' }, + ]); + + drop(event: CdkDragDrop) { + this.vegetables.update((vegetables) => { + moveItemInArray(vegetables, event.previousIndex, event.currentIndex); + return [...vegetables]; + }); + } + + // + // Stacked + // + readonly bestBoys: string[] = ['Samoyed', 'Akita Inu', 'Alaskan Malamute', 'Siberian Husky']; + + // + // chips with input + // + addOnBlur = true; + readonly separatorKeysCodes = [ENTER, COMMA] as const; + fruits: Fruit[] = [{ name: 'Lemon' }, { name: 'Lime' }, { name: 'Apple' }]; + + add(event: MatChipInputEvent): void { + const value = (event.value || '').trim(); + + // Add our fruit + if (value) { + this.fruits.push({ name: value }); + } + + // Clear the input value + event.chipInput!.clear(); + } + + remove(fruit: Fruit): void { + const index = this.fruits.indexOf(fruit); + + if (index >= 0) { + this.fruits.splice(index, 1); + } + } + + edit(fruit: Fruit, event: MatChipEditedEvent) { + const value = event.value.trim(); + + // Remove fruit if it no longer has a name + if (!value) { + this.remove(fruit); + return; + } + + // Edit existing fruit + const index = this.fruits.indexOf(fruit); + if (index >= 0) { + this.fruits[index].name = value; + } + } + + // form control + + readonly keywords = signal(['angular', 'how-to', 'tutorial', 'accessibility']); + readonly formControl = new FormControl(['angular']); + + announcer = inject(LiveAnnouncer); + + removeKeyword(keyword: string) { + this.keywords.update(keywords => { + const index = keywords.indexOf(keyword); + if (index < 0) { + return keywords; + } + + keywords.splice(index, 1); + this.announcer.announce(`removed ${keyword}`); + return [...keywords]; + }); + } + + addForm(event: MatChipInputEvent): void { + const value = (event.value || '').trim(); + + // Add our keyword + if (value) { + this.keywords.update(keywords => [...keywords, value]); + } + + // Clear the input value + event.chipInput!.clear(); + } +} +function isDragDrop(object: any): object is CdkDragDrop { + return 'previousIndex' in object; +} diff --git a/theme/packages/main/src/app/pages/ui-components/chips/code/chips-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/chips/code/chips-html-snippet.ts new file mode 100644 index 0000000..85ccf31 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/chips/code/chips-html-snippet.ts @@ -0,0 +1,79 @@ +export const BASIC_CHIPS_HTML_SNIPPET = ` + One fish + Two fish + Accent fish + Warn fish + +`; + +export const AVATAR_CHIPS_HTML_SNIPPET = ` + + Photo of a Shiba Inu + Anderson + + + Photo of a Shiba Inu + Monty + + + Photo of a Shiba Inu + Mathew + + +`; + +export const DRAG_DROP_CHIPS_HTML_SNIPPET = ` + @for (vegetable of vegetables(); track vegetable.name) { + {{ + vegetable.name + }} + } +`; + +export const STACKED_CHIPS_HTML_SNIPPET = ` + @for (dog of bestBoys; track dog) { + {{dog}} + } + +`; + +export const INPUT_CHIPS_HTML_SNIPPET = ` + Favorite Fruits + + @for(fruit of fruits; track fruit.name) { + + {{ fruit.name }} + + + } + + + + +`; + +export const FORM_CONTROL_CHIPS_HTML_SNIPPET = ` + Favorite Fruits + + @for(fruit of fruits; track fruit.name) { + + {{ fruit.name }} + + + } + + + + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/chips/code/chips-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/chips/code/chips-ts-snippet.ts new file mode 100644 index 0000000..d443e5d --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/chips/code/chips-ts-snippet.ts @@ -0,0 +1,200 @@ +export const BASIC_CHIPS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatChipsModule } from '@angular/material/chips'; + + /** + * @title chips overview + */ + @Component({ + selector: 'app-chips', + templateUrl: './chips.component.html', + styleUrls: ['./chips.component.scss'], + imports: [ + MatChipsModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush + }) + export class AppChipsComponent { + + } +`; + +export const DRAG_DROP_CHIPS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatChipsModule } from '@angular/material/chips'; + import { CdkDrag, CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop'; + + /** + * @title chips overview + */ + @Component({ + selector: 'app-chips', + templateUrl: './chips.component.html', + styleUrls: ['./chips.component.scss'], + imports: [ + MatChipsModule, + CdkDropList, + CdkDragDrop, + CdkDrag, + ], + changeDetection: ChangeDetectionStrategy.OnPush + }) + export class AppChipsComponent { + // drag n drop + readonly vegetables = signal([ + { name: 'apple' }, + { name: 'banana' }, + { name: 'strawberry' }, + { name: 'orange' }, + { name: 'kiwi' }, + { name: 'cherry' }, + ]); + + drop(event: CdkDragDrop) { + this.vegetables.update((vegetables) => { + moveItemInArray(vegetables, event.previousIndex, event.currentIndex); + return [...vegetables]; + }); + } + } + function isDragDrop(object: any): object is CdkDragDrop { + return 'previousIndex' in object; + } +`; + +export const STACKED_CHIPS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatChipsModule } from '@angular/material/chips'; + import { CdkDrag, CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop'; + + /** + * @title chips overview + */ + @Component({ + selector: 'app-chips', + templateUrl: './chips.component.html', + styleUrls: ['./chips.component.scss'], + imports: [ + MatChipsModule, + CdkDropList, + CdkDragDrop, + CdkDrag, + ], + changeDetection: ChangeDetectionStrategy.OnPush + }) + export class AppChipsComponent { + // + // Stacked + // + readonly bestBoys: string[] = ['Samoyed', 'Akita Inu', 'Alaskan Malamute', 'Siberian Husky']; + } +`; + +export const INPUT_CHIPS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatChipEditedEvent, MatChipInputEvent, MatChipsModule } from '@angular/material/chips'; + + /** + * @title chips overview + */ + @Component({ + selector: 'app-chips', + templateUrl: './chips.component.html', + styleUrls: ['./chips.component.scss'], + imports: [ + MatChipsModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush + }) + export class AppChipsComponent { + // + // chips with input + // + addOnBlur = true; + readonly separatorKeysCodes = [ENTER, COMMA] as const; + fruits: Fruit[] = [{ name: 'Lemon' }, { name: 'Lime' }, { name: 'Apple' }]; + + add(event: MatChipInputEvent): void { + const value = (event.value || '').trim(); + + // Add our fruit + if (value) { + this.fruits.push({ name: value }); + } + + // Clear the input value + event.chipInput!.clear(); + } + + remove(fruit: Fruit): void { + const index = this.fruits.indexOf(fruit); + + if (index >= 0) { + this.fruits.splice(index, 1); + } + } + + edit(fruit: Fruit, event: MatChipEditedEvent) { + const value = event.value.trim(); + + // Remove fruit if it no longer has a name + if (!value) { + this.remove(fruit); + return; + } + + // Edit existing fruit + const index = this.fruits.indexOf(fruit); + if (index >= 0) { + this.fruits[index].name = value; + } + } +`; + +export const FORM_CONTROL_CHIPS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatChipEditedEvent, MatChipInputEvent, MatChipsModule } from '@angular/material/chips'; + import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; + /** + * @title chips overview + */ + @Component({ + selector: 'app-chips', + templateUrl: './chips.component.html', + styleUrls: ['./chips.component.scss'], + imports: [ + MatChipsModule, + FormsModule, + ReactiveFormsModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush + }) + export class AppChipsComponent { + // form control + + readonly keywords = signal(['angular', 'how-to', 'tutorial', 'accessibility']); + readonly formControl = new FormControl(['angular']); + + announcer = inject(LiveAnnouncer); + + removeKeyword(keyword: string) { + this.keywords.update(keywords => { + const index = keywords.indexOf(keyword); + if (index < 0) { + return keywords; + } + + keywords.splice(index, 1); + this.announcer.announce('removed keyword'); + return [...keywords]; + }); + } + + addForm(event: MatChipInputEvent): void { + const value = (event.value || '').trim(); + + // Add our keyword + if (value) { + this.keywords.update(keywords => [...keywords, value]); + } + + // Clear the input value + event.chipInput!.clear(); + } + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/dialog/code/dialog-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/dialog/code/dialog-html-snippet.ts new file mode 100644 index 0000000..3cccbfc --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/dialog/code/dialog-html-snippet.ts @@ -0,0 +1,188 @@ +export const DIALOG_ANIMATION_HTML_SNIPPET = `
+
+ +
+
+ +
+
+ + +
Delete file
+
+ Would you like to delete cat.jpeg? +
+
+ + +
+`; + +export const DIALOG_SCROLLABLE_HTML_SNIPPET = ` + + +

Install Angular

+ +

Develop across all platforms

+

+ Learn one way to build applications with Angular and reuse your code and + abilities to build apps for any deployment target. For web, mobile web, + native mobile and native desktop. +

+ +

Speed & Performance

+

+ Achieve the maximum speed possible on the Web Platform today, and take it + further, via Web Workers and server-side rendering. Angular puts you in + control over scalability. Meet huge data requirements by building data + models on RxJS, Immutable.js or another push-model. +

+ +

Incredible tooling

+

+ Build features quickly with simple, declarative templates. Extend the + template language with your own components and use a wide array of existing + components. Get immediate Angular-specific help and feedback with nearly + every IDE and editor. All this comes together so you can focus on building + amazing apps rather than trying to make the code work. +

+ +

Loved by millions

+

+ From prototype through global deployment, Angular delivers the productivity + and scalable infrastructure that supports Google's largest applications. +

+ +

What is Angular?

+ +

+ Angular is a platform that makes it easy to build applications with the web. + Angular combines declarative templates, dependency injection, end to end + tooling, and integrated best practices to solve development challenges. + Angular empowers developers to build applications that live on the web, + mobile, or the desktop +

+ +

Architecture overview

+ +

+ Angular is a platform and framework for building client applications in HTML + and TypeScript. Angular is itself written in TypeScript. It implements core + and optional functionality as a set of TypeScript libraries that you import + into your apps. +

+ +

+ The basic building blocks of an Angular application are NgModules, which + provide a compilation context for components. NgModules collect related code + into functional sets; an Angular app is defined by a set of NgModules. An + app always has at least a root module that enables bootstrapping, and + typically has many more feature modules. +

+ +

+ Components define views, which are sets of screen elements that Angular can + choose among and modify according to your program logic and data. Every app + has at least a root component. +

+ +

+ Components use services, which provide specific functionality not directly + related to views. Service providers can be injected into components as + dependencies, making your code modular, reusable, and efficient. +

+ +

+ Both components and services are simply classes, with decorators that mark + their type and provide metadata that tells Angular how to use them. +

+ +

+ The metadata for a component class associates it with a template that + defines a view. A template combines ordinary HTML with Angular directives + and binding markup that allow Angular to modify the HTML before rendering it + for display. +

+ +

+ The metadata for a service class provides the information Angular needs to + make it available to components through Dependency Injection (DI). +

+ +

+ An app's components typically define many views, arranged hierarchically. + Angular provides the Router service to help you define navigation paths + among views. The router provides sophisticated in-browser navigational + capabilities. +

+
+ + + + + + +`; + + +export const DIALOG_INJECTING_HTML_SNIPPET = ` + + +

Favorite Animal

+
+ My favorite animal is: +
    +
  • + @if(data.animal === 'panda') { + + } Panda +
  • +
  • + @if(data.animal === 'unicorn') { + + } Unicorn +
  • +
  • + @if(data.animal === 'lion') { + + } Lion +
  • +
+
+ +`; + +export const DIALOG_MENU_HTML_SNIPPET = ` + + + + +`; + +export const DIALOG_OVERVIEW_HTML_SNIPPET = ` + What's your name? + + + + @if (animal()) { + + You chose: {{ animal() }} + + } + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/dialog/code/dialog-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/dialog/code/dialog-ts-snippet.ts new file mode 100644 index 0000000..69f231e --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/dialog/code/dialog-ts-snippet.ts @@ -0,0 +1,283 @@ +export const DIALOG_ANIMATION_TS_SNIPPET = ` import {Component} from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; + import { + MatDialog, + MatDialogRef, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatDialogModule, + } from '@angular/material/dialog'; + + /** + * @title chips overview + */ + @Component({ + selector: 'app-dialog', + templateUrl: 'dialog.component.html', + imports: [ + MatButtonModule, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatDialogModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush + }) + + // 1 + @Component({ + selector: 'dialog-overview', + imports: [MatDialogActions, MatDialogClose, MatDialogTitle, MatDialogContent, MatButtonModule], + templateUrl: 'dialog-overview.component.html' + }) + export class AppDialogOverviewComponent { + constructor(public dialogRef: MatDialogRef) {} + } + + export class AppDialogComponent { + // 1 + openDialog( + enterAnimationDuration: string, + exitAnimationDuration: string + ): void { + this.dialog.open(AppDialogOverviewComponent, { + width: '290px', + enterAnimationDuration, + exitAnimationDuration, + }); + } + } +`; + + +export const DIALOG_SCROLLABLE_TS_SNIPPET = ` import {Component} from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; + import { + MatDialog, + MatDialogRef, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatDialogModule, + } from '@angular/material/dialog'; + + /** + * @title chips overview + */ + @Component({ + selector: 'app-dialog', + templateUrl: 'dialog.component.html', + imports: [ + MatButtonModule, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatDialogModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush + }) + + /** + * @title 2 Dialog with header, scrollable content and actions + */ + @Component({ + selector: 'dialog-content', + imports: [MatDialogActions, MatDialogClose, MatDialogTitle, MatDialogContent, MatButtonModule], + templateUrl: 'dialog-content.component.html' + }) + export class AppDialogContentComponent {} + + export class AppDialogComponent { + // 2 + openHeaderDialog() { + const dialogRef = this.dialog.open(AppDialogContentComponent); + + dialogRef.afterClosed().subscribe((result) => { + console.log('Dialog result: result'); + }); + } + } +`; + + +export const DIALOG_INJECTING_TS_SNIPPET = ` import {Component} from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; + import { + MatDialog, + MatDialogRef, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatDialogModule, + } from '@angular/material/dialog'; + + export interface DialogData { + animal: 'panda' | 'unicorn' | 'lion'; + } + + /** + * @title chips overview + */ + @Component({ + selector: 'app-dialog', + templateUrl: 'dialog.component.html', + imports: [ + MatButtonModule, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatDialogModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush + }) + + // 3 + @Component({ + selector: 'dialog-data-example-dialog', + imports: [MatDialogActions, MatDialogClose, MatDialogTitle, MatDialogContent, MatButtonModule], + templateUrl: 'dialog-data.component.html' + }) + export class AppDialogDataComponent { + constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {} + } + + export class AppDialogComponent { + // 3 + openInjectDialog() { + this.dialog.open(AppDialogDataComponent, { + data: { + animal: 'panda', + }, + }); + } + } +`; + + +export const DIALOG_MENU_TS_SNIPPET = ` import {Component} from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; + import { + MatDialog, + MatDialogRef, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatDialogModule, + } from '@angular/material/dialog'; + + /** + * @title chips overview + */ + @Component({ + selector: 'app-dialog', + templateUrl: 'dialog.component.html', + imports: [ + MatButtonModule, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatDialogModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush + }) + + // 4 + @Component({ + selector: 'dialog-menu', + imports: [MatDialogActions, MatDialogClose, MatDialogTitle, MatDialogContent, MatButtonModule], + templateUrl: 'dialog-menu.component.html' + }) + export class AppDialogMenuComponent {} + + export class AppDialogComponent { + // 4 + @ViewChild('menuTrigger') menuTrigger: MatMenuTrigger; + + constructor(public dialog: MatDialog) {} + + openMenuDialog() { + const dialogRef = this.dialog.open(AppDialogMenuComponent, { + restoreFocus: false, + }); + + // Manually restore focus to the menu trigger since the element that + // opens the dialog won't be in the DOM any more when the dialog closes. + dialogRef.afterClosed().subscribe(() => this.menuTrigger.focus()); + } + } +`; + + +export const DIALOG_OVERVIEW_TS_SNIPPET = ` import {Component} from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; + import { + MatDialog, + MatDialogRef, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatDialogModule, + } from '@angular/material/dialog'; + + @Component({ + selector: 'dialog-form-overview', + templateUrl: 'dialog-form-overview.component.html', + imports: [ + MatFormFieldModule, + MatInputModule, + FormsModule, + MatButtonModule, + MatDialogTitle, + MatDialogContent, + MatDialogActions, + MatDialogClose, + ], + changeDetection: ChangeDetectionStrategy.OnPush + }) + export class DialogOverviewExampleDialog { + readonly dialogRef = inject(MatDialogRef); + readonly data = inject(MAT_DIALOG_DATA); + readonly animal = model(this.data.animal); + + onNoClick(): void { + this.dialogRef.close(); + } + } + + // 5 + + export interface DialogData2 { + animal: any; + name: string; + } + + export class AppDialogComponent { + // 5 + readonly animal = signal(''); + readonly name = model(''); + readonly dialogEx = inject(MatDialog); + + openDialogEx(): void { + const dialogRef = this.dialogEx.open(DialogOverviewExampleDialog, { + data: {name: this.name(), animal: this.animal()}, + }); + + dialogRef.afterClosed().subscribe(result => { + console.log('The dialog was closed'); + if (result !== undefined) { + this.animal.set(result); + } + }); + } + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/dialog/dialog-content.component.html b/theme/packages/main/src/app/pages/ui-components/dialog/dialog-content.component.html new file mode 100644 index 0000000..45e29d5 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/dialog/dialog-content.component.html @@ -0,0 +1,99 @@ +

Install Angular

+ +

Develop across all platforms

+

+ Learn one way to build applications with Angular and reuse your code and + abilities to build apps for any deployment target. For web, mobile web, + native mobile and native desktop. +

+ +

Speed & Performance

+

+ Achieve the maximum speed possible on the Web Platform today, and take it + further, via Web Workers and server-side rendering. Angular puts you in + control over scalability. Meet huge data requirements by building data + models on RxJS, Immutable.js or another push-model. +

+ +

Incredible tooling

+

+ Build features quickly with simple, declarative templates. Extend the + template language with your own components and use a wide array of existing + components. Get immediate Angular-specific help and feedback with nearly + every IDE and editor. All this comes together so you can focus on building + amazing apps rather than trying to make the code work. +

+ +

Loved by millions

+

+ From prototype through global deployment, Angular delivers the productivity + and scalable infrastructure that supports Google's largest applications. +

+ +

What is Angular?

+ +

+ Angular is a platform that makes it easy to build applications with the web. + Angular combines declarative templates, dependency injection, end to end + tooling, and integrated best practices to solve development challenges. + Angular empowers developers to build applications that live on the web, + mobile, or the desktop +

+ +

Architecture overview

+ +

+ Angular is a platform and framework for building client applications in HTML + and TypeScript. Angular is itself written in TypeScript. It implements core + and optional functionality as a set of TypeScript libraries that you import + into your apps. +

+ +

+ The basic building blocks of an Angular application are NgModules, which + provide a compilation context for components. NgModules collect related code + into functional sets; an Angular app is defined by a set of NgModules. An + app always has at least a root module that enables bootstrapping, and + typically has many more feature modules. +

+ +

+ Components define views, which are sets of screen elements that Angular can + choose among and modify according to your program logic and data. Every app + has at least a root component. +

+ +

+ Components use services, which provide specific functionality not directly + related to views. Service providers can be injected into components as + dependencies, making your code modular, reusable, and efficient. +

+ +

+ Both components and services are simply classes, with decorators that mark + their type and provide metadata that tells Angular how to use them. +

+ +

+ The metadata for a component class associates it with a template that + defines a view. A template combines ordinary HTML with Angular directives + and binding markup that allow Angular to modify the HTML before rendering it + for display. +

+ +

+ The metadata for a service class provides the information Angular needs to + make it available to components through Dependency Injection (DI). +

+ +

+ An app's components typically define many views, arranged hierarchically. + Angular provides the Router service to help you define navigation paths + among views. The router provides sophisticated in-browser navigational + capabilities. +

+
+ + + + diff --git a/theme/packages/main/src/app/pages/ui-components/dialog/dialog-data.component.html b/theme/packages/main/src/app/pages/ui-components/dialog/dialog-data.component.html new file mode 100644 index 0000000..e6ade98 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/dialog/dialog-data.component.html @@ -0,0 +1,21 @@ +

Favorite Animal

+
+ My favorite animal is: +
    +
  • + @if(data.animal === 'panda') { + + } Panda +
  • +
  • + @if(data.animal === 'unicorn') { + + } Unicorn +
  • +
  • + @if(data.animal === 'lion') { + + } Lion +
  • +
+
diff --git a/theme/packages/main/src/app/pages/ui-components/dialog/dialog-form-overview.component.html b/theme/packages/main/src/app/pages/ui-components/dialog/dialog-form-overview.component.html new file mode 100644 index 0000000..1d07238 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/dialog/dialog-form-overview.component.html @@ -0,0 +1,16 @@ +

Hi {{ data.name }}

+ +

What's your favorite animal?

+ + Favorite Animal + + +
+ + + + diff --git a/theme/packages/main/src/app/pages/ui-components/dialog/dialog-menu.component.html b/theme/packages/main/src/app/pages/ui-components/dialog/dialog-menu.component.html new file mode 100644 index 0000000..031c802 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/dialog/dialog-menu.component.html @@ -0,0 +1,4 @@ + This is a dialog + + + diff --git a/theme/packages/main/src/app/pages/ui-components/dialog/dialog-overview.component.html b/theme/packages/main/src/app/pages/ui-components/dialog/dialog-overview.component.html new file mode 100644 index 0000000..c8df3eb --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/dialog/dialog-overview.component.html @@ -0,0 +1,10 @@ +
Delete file
+
+ Would you like to delete cat.jpeg? +
+
+ + +
diff --git a/theme/packages/main/src/app/pages/ui-components/dialog/dialog.component.html b/theme/packages/main/src/app/pages/ui-components/dialog/dialog.component.html new file mode 100644 index 0000000..2a12f26 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/dialog/dialog.component.html @@ -0,0 +1,182 @@ + +
+ Dialog +
+ +
+ +
+ + +

+ Animations +

+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + +

+ Scrollable content and actions +

+
+ + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + +

+ Injecting data on Open +

+
+ + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + +

+ Dialog launched from a menu +

+
+ + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ +

+ Dialog Overview +

+ +
+ + What's your name? + + + + @if (animal()) { + + You chose: {{ animal() }} + + } +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/dialog/dialog.component.ts b/theme/packages/main/src/app/pages/ui-components/dialog/dialog.component.ts new file mode 100644 index 0000000..07b599d --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/dialog/dialog.component.ts @@ -0,0 +1,244 @@ +import { + ChangeDetectionStrategy, + Component, + Inject, + ViewChild, + inject, + model, + signal, +} from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { + MatDialog, + MatDialogRef, + MAT_DIALOG_DATA, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatDialogModule, +} from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu'; + +// snippets +import { + DIALOG_ANIMATION_HTML_SNIPPET, + DIALOG_INJECTING_HTML_SNIPPET, + DIALOG_MENU_HTML_SNIPPET, + DIALOG_OVERVIEW_HTML_SNIPPET, + DIALOG_SCROLLABLE_HTML_SNIPPET, +} from './code/dialog-html-snippet'; +import { + DIALOG_ANIMATION_TS_SNIPPET, + DIALOG_INJECTING_TS_SNIPPET, + DIALOG_MENU_TS_SNIPPET, + DIALOG_OVERVIEW_TS_SNIPPET, + DIALOG_SCROLLABLE_TS_SNIPPET, +} from './code/dialog-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +export interface DialogData { + animal: 'panda' | 'unicorn' | 'lion'; +} + +// 1 +@Component({ + selector: 'dialog-overview', + imports: [ + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatButtonModule, + ], + templateUrl: 'dialog-overview.component.html', +}) +export class AppDialogOverviewComponent { + constructor(public dialogRef: MatDialogRef) {} +} + +/** + * @title 2 Dialog with header, scrollable content and actions + */ +@Component({ + selector: 'dialog-content', + imports: [ + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + MatButtonModule, + ], + templateUrl: 'dialog-content.component.html', +}) +export class AppDialogContentComponent {} + +// 3 +@Component({ + selector: 'dialog-data-example-dialog', + imports: [ + MatDialogTitle, + MatDialogContent, + MatButtonModule, + ], + templateUrl: 'dialog-data.component.html', +}) +export class AppDialogDataComponent { + constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {} +} + +// 4 +@Component({ + selector: 'dialog-menu', + imports: [ + MatDialogActions, + MatDialogClose, + MatDialogContent, + MatButtonModule, + ], + templateUrl: 'dialog-menu.component.html', +}) +export class AppDialogMenuComponent {} + +// 5 + +export interface DialogData2 { + animal: any; + name: string; +} + +@Component({ + selector: 'dialog-form-overview', + templateUrl: 'dialog-form-overview.component.html', + imports: [ + MatFormFieldModule, + MatInputModule, + FormsModule, + MatButtonModule, + MatDialogTitle, + MatDialogContent, + MatDialogActions, + MatDialogClose, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class DialogOverviewExampleDialog { + readonly dialogRef = inject(MatDialogRef); + readonly data = inject(MAT_DIALOG_DATA); + readonly animal = model(this.data.animal); + + onNoClick(): void { + this.dialogRef.close(); + } +} + +@Component({ + selector: 'app-dialog', + imports: [ + MatButtonModule, + MatMenuModule, + MatCardModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + FormsModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './dialog.component.html', +}) +export class AppDialogComponent { + // 1 [dialog with Animations] + codeFordialogAnimations = DIALOG_ANIMATION_HTML_SNIPPET; + codeFordialogAnimationsTs = DIALOG_ANIMATION_TS_SNIPPET; + + // 2 [Scrollable with dialog] + codeForScrollable = DIALOG_SCROLLABLE_HTML_SNIPPET; + codeForScrollableTs = DIALOG_SCROLLABLE_TS_SNIPPET; + + // 3 [Injecting with dialog] + codeForInjecting = DIALOG_INJECTING_HTML_SNIPPET; + codeForInjectingTs = DIALOG_INJECTING_TS_SNIPPET; + + // 4 [menu with dialog] + codeForMenu = DIALOG_MENU_HTML_SNIPPET; + codeForMenuTs = DIALOG_MENU_TS_SNIPPET; + + // 5 [menu with dialog] + codeForOverview = DIALOG_OVERVIEW_HTML_SNIPPET; + codeForOverviewTs = DIALOG_OVERVIEW_TS_SNIPPET; + + // 4 + @ViewChild('menuTrigger') menuTrigger: MatMenuTrigger; + + constructor(public dialog: MatDialog) {} + + // 5 + readonly animal = signal(''); + readonly name = model(''); + readonly dialogEx = inject(MatDialog); + + openDialogEx(): void { + const dialogRef = this.dialogEx.open(DialogOverviewExampleDialog, { + data: { name: this.name(), animal: this.animal() }, + }); + + dialogRef.afterClosed().subscribe((result) => { + console.log('The dialog was closed'); + if (result !== undefined) { + this.animal.set(result); + } + }); + } + + // 1 + openDialog( + enterAnimationDuration: string, + exitAnimationDuration: string + ): void { + this.dialog.open(AppDialogOverviewComponent, { + width: '290px', + enterAnimationDuration, + exitAnimationDuration, + }); + } + + // 2 + openHeaderDialog() { + const dialogRef = this.dialog.open(AppDialogContentComponent); + + dialogRef.afterClosed().subscribe((result) => { + console.log(`Dialog result: ${result}`); + }); + } + + // 3 + openInjectDialog() { + this.dialog.open(AppDialogDataComponent, { + data: { + animal: 'panda', + }, + }); + } + + // 4 + + openMenuDialog() { + const dialogRef = this.dialog.open(AppDialogMenuComponent, { + restoreFocus: false, + }); + + // Manually restore focus to the menu trigger since the element that + // opens the dialog won't be in the DOM any more when the dialog closes. + dialogRef.afterClosed().subscribe(() => this.menuTrigger.focus()); + } +} diff --git a/theme/packages/main/src/app/pages/ui-components/divider/code/divider-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/divider/code/divider-html-snippet.ts new file mode 100644 index 0000000..7b3fcbb --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/divider/code/divider-html-snippet.ts @@ -0,0 +1,26 @@ +export const DIVIDER_BASIC_HTML_SNIPPET = ` + Item 1 + + Item 2 + + Item 3 + +`; + +export const DIVIDER_INSET_HTML_SNIPPET = ` + Home + + UI + + Forms + +`; + +export const DIVIDER_VERTICAL_HTML_SNIPPET = ` + Home + + UI + + Forms + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/divider/code/divider-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/divider/code/divider-ts-snippet.ts new file mode 100644 index 0000000..f0e4aeb --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/divider/code/divider-ts-snippet.ts @@ -0,0 +1,16 @@ +export const DIVIDER_BASIC_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatDividerModule} from '@angular/material/divider'; + import { MatListModule } from '@angular/material/list'; + + /** + * @title Divider overview + */ + @Component({ + selector: 'app-divider', + imports: [MatDividerModule, MatListModule, MatCardModule], + templateUrl: './divider.component.html' + }) + export class AppDividerComponent { + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/divider/divider.component.html b/theme/packages/main/src/app/pages/ui-components/divider/divider.component.html new file mode 100644 index 0000000..cf56acc --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/divider/divider.component.html @@ -0,0 +1,106 @@ + +
+ Divider +
+ +
+
+ + +

+ Basic +

+
+ + Item 1 + + Item 2 + + Item 3 + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+
+ + +

+ Inset +

+
+ + Home + + UI + + Forms + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + +

+ Vertical +

+
+ + Home + + UI + + Forms + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/divider/divider.component.ts b/theme/packages/main/src/app/pages/ui-components/divider/divider.component.ts new file mode 100644 index 0000000..7cebf1b --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/divider/divider.component.ts @@ -0,0 +1,34 @@ +import { Component } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; +import {MatDividerModule} from '@angular/material/divider'; +import { MatListModule } from '@angular/material/list'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { DIVIDER_BASIC_HTML_SNIPPET, DIVIDER_INSET_HTML_SNIPPET, DIVIDER_VERTICAL_HTML_SNIPPET } from './code/divider-html-snippet'; +import { DIVIDER_BASIC_TS_SNIPPET } from './code/divider-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-divider', + imports: [MatDividerModule, MatListModule, MatCardModule,Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent,], + templateUrl: './divider.component.html' +}) +export class AppDividerComponent { + // 1 [basic with divider] + codeForDividerBasic = DIVIDER_BASIC_HTML_SNIPPET; + codeForDividerBasicTs = DIVIDER_BASIC_TS_SNIPPET; + + // 2 [inset with divider] + codeForDividerInset = DIVIDER_INSET_HTML_SNIPPET; + codeForDividerInsetTs = DIVIDER_BASIC_TS_SNIPPET; + + // 3 [Vertical with divider] + codeForDividerVertical = DIVIDER_VERTICAL_HTML_SNIPPET; + codeForDividerVerticalTs = DIVIDER_BASIC_TS_SNIPPET; +} diff --git a/theme/packages/main/src/app/pages/ui-components/expansion/code/expansion-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/expansion/code/expansion-html-snippet.ts new file mode 100644 index 0000000..9919ae4 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/expansion/code/expansion-html-snippet.ts @@ -0,0 +1,134 @@ +export const BASIC_EXPANSION_HTML_SNIPPET = ` + + + + This is the expansion title + + + This is a summary of the content + + +

This is the primary content of the panel.

+
+ + + + Self aware panel + + + Currently I am {{panelOpenState ? 'open' : 'closed'}} + + +

I'm visible because I am open

+
+
+`; + +export const EXPAND_EXPANSION_HTML_SNIPPET = `
+ + +
+ + + + + Personal data + + Type your name and age + + + + + + +
+
+ + First name + + +
+
+ + Age + + +
+
+
+ + + + + Destination + + Type the country name + + + + + + + + Country + + + + + + + + + Day of the trip + + + Inform the date you wish to travel + + + + + + +
+
+ + Date of Trip + + +
+
+
+
+`; + +export const ACCORDIAN_EXPANSION_HTML_SNIPPET = ` + + + + This is the expansion title + + + This is a summary of the content + + +

This is the primary content of the panel.

+
+ + + + Self aware panel + + + Currently I am {{panelOpenState ? 'open' : 'closed'}} + + +

I'm visible because I am open

+
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/expansion/code/expansion-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/expansion/code/expansion-ts-snippet.ts new file mode 100644 index 0000000..d22ae97 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/expansion/code/expansion-ts-snippet.ts @@ -0,0 +1,75 @@ +export const BASIC_EXPANSION_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatExpansionModule } from '@angular/material/expansion'; + + /** + * @title Expansion overview + */ + @Component({ + selector: 'app-expansion', + providers: [provideNativeDateAdapter()], + imports: [ + MatExpansionModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './expansion.component.html' + }) + export class AppExpansionComponent { + // basic + panelOpenState = false; + } +`; + +export const EXPAND_EXPANSION_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatExpansionModule } from '@angular/material/expansion'; + + /** + * @title Expansion overview + */ + @Component({ + selector: 'app-expansion', + providers: [provideNativeDateAdapter()], + imports: [ + MatExpansionModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './expansion.component.html' + }) + export class AppExpansionComponent { + // expand all + @ViewChild(MatAccordion) accordion: MatAccordion; + constructor() {} + } +`; + +export const ACCORDIAN_EXPANSION_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatExpansionModule } from '@angular/material/expansion'; + + /** + * @title Expansion overview + */ + @Component({ + selector: 'app-expansion', + providers: [provideNativeDateAdapter()], + imports: [ + MatExpansionModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './expansion.component.html' + }) + export class AppExpansionComponent { + // accordian + step = 0; + + setStep(index: number) { + this.step = index; + } + + nextStep() { + this.step++; + } + + prevStep() { + this.step--; + } + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/expansion/expansion.component.html b/theme/packages/main/src/app/pages/ui-components/expansion/expansion.component.html new file mode 100644 index 0000000..2af593f --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/expansion/expansion.component.html @@ -0,0 +1,283 @@ + +
+ Expansion Panel +
+ + + + + + +

+ Basic +

+
+ + + + + This is the expansion title + + + This is a summary of the content + + +

This is the primary content of the panel.

+
+ + + + Self aware panel + + + Currently I am {{panelOpenState ? 'open' : 'closed'}} + + +

I'm visible because I am open

+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + + + + +

+ Expand/collapse all toggles +

+
+
+ + +
+ + + + + Personal data + + Type your name and age + + + + + + +
+
+ + First name + + +
+
+ + Age + + +
+
+
+ + + + + Destination + + Type the country name + + + + + + + + Country + + + + + + + + + Day of the trip + + + Inform the date you wish to travel + + + + + + +
+
+ + Date of Trip + + +
+
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + + + + +

+ Accordian +

+
+ + + + Personal data + + Type your name and age + + + + + + +
+
+ + First name + + +
+
+ + Age + + +
+
+ + + + +
+ + + + Destination + + Type the country name + + + + + + + + Country + + + + + + + + + + + + + Day of the trip + + + Inform the date you wish to travel + + + + + + +
+
+ + Date of Trip + + +
+
+ + + + + +
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/expansion/expansion.component.ts b/theme/packages/main/src/app/pages/ui-components/expansion/expansion.component.ts new file mode 100644 index 0000000..f3a3dc6 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/expansion/expansion.component.ts @@ -0,0 +1,78 @@ +import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { provideNativeDateAdapter } from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatAccordion, MatExpansionModule } from '@angular/material/expansion'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatTabsModule } from '@angular/material/tabs'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { ACCORDIAN_EXPANSION_TS_SNIPPET, BASIC_EXPANSION_TS_SNIPPET, EXPAND_EXPANSION_TS_SNIPPET } from './code/expansion-ts-snippet'; +import { ACCORDIAN_EXPANSION_HTML_SNIPPET, BASIC_EXPANSION_HTML_SNIPPET, EXPAND_EXPANSION_HTML_SNIPPET } from './code/expansion-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +@Component({ + selector: 'app-expansion', + providers: [provideNativeDateAdapter()], + imports: [ + MatButtonModule, + MatExpansionModule, + MatIconModule, + MatFormFieldModule, + MatInputModule, + MatDatepickerModule, + TablerIconsModule, + MatCardModule, + MatTabsModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent + ], + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './expansion.component.html' +}) +export class AppExpansionComponent { + // 2 expand all + @ViewChild(MatAccordion) accordion: MatAccordion; + constructor() {} + + // 1 basic + panelOpenState = false; + + // 3 accordian + step = 0; + + setStep(index: number) { + this.step = index; + } + + nextStep() { + this.step++; + } + + prevStep() { + this.step--; + } + + // 1 [basic with expansion] + codeForBasicExpansion = BASIC_EXPANSION_HTML_SNIPPET; + codeForBasicExpansionTs = BASIC_EXPANSION_TS_SNIPPET; + + // 2 [Expand with expansion] + codeForExpandExpansion = EXPAND_EXPANSION_HTML_SNIPPET; + codeForExpandExpansionTs = EXPAND_EXPANSION_TS_SNIPPET; + + // 3 [Expand with expansion] + codeForAccordianExpansion = ACCORDIAN_EXPANSION_HTML_SNIPPET; + codeForAccordianExpansionTs = ACCORDIAN_EXPANSION_TS_SNIPPET; + +} diff --git a/theme/packages/main/src/app/pages/ui-components/lists/code/list-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/lists/code/list-html-snippet.ts new file mode 100644 index 0000000..5874f70 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/lists/code/list-html-snippet.ts @@ -0,0 +1,116 @@ +export const LIST_BASIC_HTML_SNIPPET = ` + Item 1 + Item 2 + Item 3 + +`; + +export const LIST_TWOLINE_HTML_SNIPPET = ` + + Title + Second line + + + Title + Second line + + +`; + +export const LIST_THREELINE_HTML_SNIPPET = ` + + Title + Second line + Third line + + + Title + Second line. This line will truncate. + Third line + + +`; + + +export const LIST_THREELINE_TEXT_WRAPPING_HTML_SNIPPET = ` + + Title + Secondary line that will wrap because the list lines is + explicitly set to 3 lines. Text inside of a 'matListItemTitle' + or 'matListItemLine' will never wrap. + + + + Title + Secondary line that will wrap because the list lines is + explicitly set to 3 lines. Text inside of a 'matListItemTitle' + or 'matListItemLine' will never wrap. + + + +`; + +export const LIST_SELECTION_HTML_SNIPPET = ` + @for(shoe of typesOfShoes; track shoe) { + + {{ shoe }} + + } + + +

+ Options selected: {{ shoes.selectedOptions.selected.length }} +

+`; + +export const LIST_SINGLE_SELECTION_HTML_SNIPPET = ` + @for(shoe of typesOfShoes; track shoe) { + + {{ shoe }} + + } + + +

+ Option selected: + {{ + shoes2.selectedOptions.hasValue() + ? shoes2.selectedOptions.selected[0].value + : "None" + }} +

+`; + +export const LIST_SECTIONS_HTML_SNIPPET = ` +
Folders
+ @for(folder of folders; track folder.name) { + + folder +
+ {{ folder.name }} +
+
+ {{ folder.updated | date }} +
+
+ } + + +
Notes
+ @for(note of notes; track note.name) { + + note +
+ {{ note.name }} +
+
+ {{ note.updated | date }} +
+
+ } +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/lists/code/list-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/lists/code/list-ts-snippet.ts new file mode 100644 index 0000000..d721786 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/lists/code/list-ts-snippet.ts @@ -0,0 +1,83 @@ +export const LIST_BASIC_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatListModule } from '@angular/material/list'; + + /** + * @title List overview + */ + @Component({ + selector: 'app-lists', + imports: [MatListModule], + templateUrl: './lists.component.html' + }) + export class AppListsComponent { + + } +`; + + +export const LIST_SELECTION_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatListModule } from '@angular/material/list'; + import { MaterialModule } from 'src/app/material.module'; + import {DatePipe} from '@angular/common'; + + /** + * @title List overview + */ + @Component({ + selector: 'app-lists', + imports: [MatListModule, MaterialModule, DatePipe], + templateUrl: './lists.component.html' + }) + export class AppListsComponent { + typesOfShoes: string[] = ['Loafers', 'Sneakers']; + } +`; + + +export const LIST_SECTIONS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatListModule } from '@angular/material/list'; + import { MaterialModule } from 'src/app/material.module'; + import {DatePipe} from '@angular/common'; + + export interface Section { + name: string; + updated: Date; + } + + /** + * @title List overview + */ + @Component({ + selector: 'app-lists', + imports: [MatListModule, MaterialModule, DatePipe], + templateUrl: './lists.component.html' + }) + export class AppListsComponent { + typesOfShoes: string[] = ['Loafers', 'Sneakers']; + + folders: Section[] = [ + { + name: 'Photos', + updated: new Date('1/1/16'), + }, + { + name: 'Recipes', + updated: new Date('1/17/16'), + }, + { + name: 'Work', + updated: new Date('1/28/16'), + }, + ]; + notes: Section[] = [ + { + name: 'Vacation Itinerary', + updated: new Date('2/20/16'), + }, + { + name: 'Kitchen Remodel', + updated: new Date('1/18/16'), + }, + ]; + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/lists/lists.component.html b/theme/packages/main/src/app/pages/ui-components/lists/lists.component.html new file mode 100644 index 0000000..7930d25 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/lists/lists.component.html @@ -0,0 +1,309 @@ + +
+ Lists +
+ +
+
+ + + + + +

+ Basic +

+
+ + Item 1 + Item 2 + Item 3 + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + + +

+ Two Line +

+
+ + + Title + Second line + + + Title + Second line + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + + +

+ Three Line +

+
+ + + Title + Second line + Third line + + + Title + Second line. This line will truncate. + Third line + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + + +

+ Three Line with Text wrapping +

+
+ + + Title + Secondary line that will wrap because the list lines is + explicitly set to 3 lines. Text inside of a `matListItemTitle` + or `matListItemLine` will never wrap. + + + + Title + Secondary line that will wrap because the list lines is + explicitly set to 3 lines. Text inside of a `matListItemTitle` + or `matListItemLine` will never wrap. + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + + +

+ List with Selection +

+
+ + @for(shoe of typesOfShoes; track shoe) { + + {{ shoe }} + + } + + +

+ Options selected: {{ shoes.selectedOptions.selected.length }} +

+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + + +

+ List with single Selection +

+
+ + @for(shoe of typesOfShoes; track shoe) { + + {{ shoe }} + + } + + +

+ Option selected: + {{ + shoes2.selectedOptions.hasValue() + ? shoes2.selectedOptions.selected[0].value + : "None" + }} +

+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + + + + +

+ List with sections +

+
+ +
Folders
+ @for(folder of folders; track folder.name) { + + folder +
+ {{ folder.name }} +
+
+ {{ folder.updated | date }} +
+
+ } + + +
Notes
+ @for(note of notes; track note.name) { + + note +
+ {{ note.name }} +
+
+ {{ note.updated | date }} +
+
+ } +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/lists/lists.component.ts b/theme/packages/main/src/app/pages/ui-components/lists/lists.component.ts new file mode 100644 index 0000000..97c1725 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/lists/lists.component.ts @@ -0,0 +1,89 @@ +import { Component } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; +import { MatListModule } from '@angular/material/list'; +import {MatIconModule} from '@angular/material/icon'; +import {DatePipe} from '@angular/common'; +import { MaterialModule } from 'src/app/material.module'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + +// snippets +import { LIST_BASIC_HTML_SNIPPET, LIST_SECTIONS_HTML_SNIPPET, LIST_SELECTION_HTML_SNIPPET, LIST_SINGLE_SELECTION_HTML_SNIPPET, LIST_THREELINE_HTML_SNIPPET, LIST_THREELINE_TEXT_WRAPPING_HTML_SNIPPET, LIST_TWOLINE_HTML_SNIPPET } from './code/list-html-snippet'; +import { LIST_BASIC_TS_SNIPPET, LIST_SELECTION_TS_SNIPPET } from './code/list-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +export interface Section { + name: string; + updated: Date; +} + +@Component({ + selector: 'app-lists', + imports: [MatListModule, MatCardModule, DatePipe, MatIconModule, MaterialModule, Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent,], + templateUrl: './lists.component.html' +}) +export class AppListsComponent { + constructor() {} + + // 1 [Basic with list] + codeForBasicList = LIST_BASIC_HTML_SNIPPET; + codeForBasicListTs = LIST_BASIC_TS_SNIPPET; + + // 2 [Twoline with list] + codeForTwolineList = LIST_TWOLINE_HTML_SNIPPET; + codeForTwolineListTs = LIST_BASIC_TS_SNIPPET; + + // 3 [Threeline with list] + codeForThreelineList = LIST_THREELINE_HTML_SNIPPET; + codeForThreelineListTs = LIST_BASIC_TS_SNIPPET; + + // 4 [Threeline with TextWrapping list] + codeForThreelineTextWrappingList = LIST_THREELINE_TEXT_WRAPPING_HTML_SNIPPET; + codeForThreelineTextWrappingListTs = LIST_BASIC_TS_SNIPPET; + + // 5 [Selection with list] + codeForSelectionList = LIST_SELECTION_HTML_SNIPPET; + codeForSelectionListTs = LIST_SELECTION_TS_SNIPPET; + + // 6 [Single Selection with list] + codeForSingleSelectionList = LIST_SINGLE_SELECTION_HTML_SNIPPET; + codeForSingleSelectionListTs = LIST_SELECTION_TS_SNIPPET; + + // 6 [sections with list] + codeForSectionsList = LIST_SECTIONS_HTML_SNIPPET; + codeForSectionsListTs = LIST_SELECTION_TS_SNIPPET; + + + typesOfShoes: string[] = ['Loafers', 'Sneakers']; + + folders: Section[] = [ + { + name: 'Photos', + updated: new Date('1/1/16'), + }, + { + name: 'Recipes', + updated: new Date('1/17/16'), + }, + { + name: 'Work', + updated: new Date('1/28/16'), + }, + ]; + notes: Section[] = [ + { + name: 'Vacation Itinerary', + updated: new Date('2/20/16'), + }, + { + name: 'Kitchen Remodel', + updated: new Date('1/18/16'), + }, + ]; +} diff --git a/theme/packages/main/src/app/pages/ui-components/menu/code/menu-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/menu/code/menu-html-snippet.ts new file mode 100644 index 0000000..faf2922 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/menu/code/menu-html-snippet.ts @@ -0,0 +1,128 @@ +export const MENU_BASIC_HTML_SNIPPET = ` + + + + +`; + +export const MENU_ICONS_HTML_SNIPPET = ` + + + + + +`; + +export const MENU_NESTED_HTML_SNIPPET = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + + +export const MENU_POSITIONS_HTML_SNIPPET = `
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/menu/code/menu-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/menu/code/menu-ts-snippet.ts new file mode 100644 index 0000000..db7780b --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/menu/code/menu-ts-snippet.ts @@ -0,0 +1,17 @@ +export const MENU_BASIC_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatButtonModule } from '@angular/material/button'; + import { MatIconModule } from '@angular/material/icon'; + import { MatMenuModule } from '@angular/material/menu'; + + /** + * @title Divider menu + */ + @Component({ + selector: 'app-menu', + imports: [ MatMenuModule, MatIconModule, MatButtonModule], + templateUrl: './menu.component.html' + }) + export class AppMenuComponent { + constructor() {} + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/menu/menu.component.html b/theme/packages/main/src/app/pages/ui-components/menu/menu.component.html new file mode 100644 index 0000000..ec1917b --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/menu/menu.component.html @@ -0,0 +1,230 @@ + +
+ Menu +
+ +
+
+ + +

+ Basic +

+
+ + + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+
+ + +

+ with Icons +

+
+ + + + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+
+ + +

+ Nested Menu +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+ +
+ + +

+ Positions +

+
+
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/menu/menu.component.ts b/theme/packages/main/src/app/pages/ui-components/menu/menu.component.ts new file mode 100644 index 0000000..c3ad736 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/menu/menu.component.ts @@ -0,0 +1,44 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { MENU_BASIC_HTML_SNIPPET, MENU_ICONS_HTML_SNIPPET, MENU_NESTED_HTML_SNIPPET, MENU_POSITIONS_HTML_SNIPPET } from './code/menu-html-snippet'; +import { MENU_BASIC_TS_SNIPPET } from './code/menu-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-menu', + imports: [MatCardModule, MatMenuModule, MatIconModule, TablerIconsModule, MatButtonModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './menu.component.html' +}) +export class AppMenuComponent { + constructor() {} + + // 1 [basic with menu] + codeForMenuBasic = MENU_BASIC_HTML_SNIPPET; + codeForMenuBasicTs = MENU_BASIC_TS_SNIPPET; + + // 2 [icons with menu] + codeForMenuIcons = MENU_ICONS_HTML_SNIPPET; + codeForMenuIconsTs = MENU_BASIC_TS_SNIPPET; + + // 3 [Nested with menu] + codeForMenuNested = MENU_NESTED_HTML_SNIPPET; + codeForMenuNestedTs = MENU_BASIC_TS_SNIPPET; + + // 4 [Positions with menu] + codeForMenuPositions = MENU_POSITIONS_HTML_SNIPPET; + codeForMenuPositionsTs = MENU_BASIC_TS_SNIPPET; +} diff --git a/theme/packages/main/src/app/pages/ui-components/paginator/code/paginator-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/paginator/code/paginator-html-snippet.ts new file mode 100644 index 0000000..29da4e3 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/paginator/code/paginator-html-snippet.ts @@ -0,0 +1,8 @@ +export const PAGINATOR_BASIC_HTML_SNIPPET = ` + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/paginator/code/paginator-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/paginator/code/paginator-ts-snippet.ts new file mode 100644 index 0000000..665bfca --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/paginator/code/paginator-ts-snippet.ts @@ -0,0 +1,27 @@ +export const PAGINATOR_BASIC_TS_SNIPPET = ` import {Component} from '@angular/core'; + import { MatPaginatorModule} from '@angular/material/paginator'; + import {JsonPipe} from '@angular/common'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {FormsModule} from '@angular/forms'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + /** + * @title Divider paginator + */ + @Component({ + selector: 'app-paginator', + imports: [ + MatFormFieldModule, + MatInputModule, + FormsModule, + MatSlideToggleModule, + MatPaginatorModule, + JsonPipe, + ], + templateUrl: './paginator.component.html' + }) + export class AppPaginatorComponent { + constructor() {} + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/paginator/paginator.component.html b/theme/packages/main/src/app/pages/ui-components/paginator/paginator.component.html new file mode 100644 index 0000000..4ad8f95 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/paginator/paginator.component.html @@ -0,0 +1,32 @@ + +
+ Paginator +
+ + + +

+ Basic +

+
+ + +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/paginator/paginator.component.ts b/theme/packages/main/src/app/pages/ui-components/paginator/paginator.component.ts new file mode 100644 index 0000000..736e95d --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/paginator/paginator.component.ts @@ -0,0 +1,40 @@ +import { Component } from '@angular/core'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { JsonPipe } from '@angular/common'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { FormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatCardModule } from '@angular/material/card'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { PAGINATOR_BASIC_HTML_SNIPPET } from './code/paginator-html-snippet'; +import { PAGINATOR_BASIC_TS_SNIPPET } from './code/paginator-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-paginator', + imports: [ + MatFormFieldModule, + MatInputModule, + FormsModule, + MatSlideToggleModule, + MatPaginatorModule, + MatCardModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './paginator.component.html', +}) +export class AppPaginatorComponent { + constructor() {} + + // 1 [basic with paginator] + codeForPaginatorBasic = PAGINATOR_BASIC_HTML_SNIPPET; + codeForPaginatorBasicTs = PAGINATOR_BASIC_TS_SNIPPET; +} diff --git a/theme/packages/main/src/app/pages/ui-components/progress-snipper/code/progress-snipper-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/progress-snipper/code/progress-snipper-html-snippet.ts new file mode 100644 index 0000000..4b3cb15 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/progress-snipper/code/progress-snipper-html-snippet.ts @@ -0,0 +1,36 @@ +export const PROGRESS_SPINNER_BASIC_HTML_SNIPPET = ` +`; + +export const PROGRESS_SPINNER_CONFIGURABLE_HTML_SNIPPET = `

Progress spinner configuration

+ +
+ + + + Determinate + + + Indeterminate + + +
+ + @if (mode === 'determinate') { +
+ + + + +
+ } + +
+

Result

+ + + +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/progress-snipper/code/progress-snipper-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/progress-snipper/code/progress-snipper-ts-snippet.ts new file mode 100644 index 0000000..1ad5ad2 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/progress-snipper/code/progress-snipper-ts-snippet.ts @@ -0,0 +1,35 @@ +export const PROGRESS_SPINNER_BASIC_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; + + /** + * @title Divider Progress snipper + */ + @Component({ + selector: 'app-progress-snipper', + imports: [MatProgressSpinnerModule], + templateUrl: './progress-snipper.component.html' + }) + export class AppProgressSnipperComponent { + constructor() {} + } +`; + +export const PROGRESS_SPINNER_CONFIGURABLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; + + /** + * @title Divider Progress snipper + */ + @Component({ + selector: 'app-progress-snipper', + imports: [MatCardModule, MatRadioModule, FormsModule, MatSliderModule, MatProgressSpinnerModule], + templateUrl: './progress-snipper.component.html' + }) + export class AppProgressSnipperComponent { + constructor() {} + + mode: ProgressSpinnerMode = 'determinate'; + value = 50; + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/progress-snipper/progress-snipper.component.html b/theme/packages/main/src/app/pages/ui-components/progress-snipper/progress-snipper.component.html new file mode 100644 index 0000000..149e919 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/progress-snipper/progress-snipper.component.html @@ -0,0 +1,89 @@ + +
+ Progress Spinner +
+ + + + +

+ Basic +

+
+ +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Configurable +

+
+

Progress spinner configuration

+ +
+ + + + Determinate + + + Indeterminate + + +
+ + @if (mode === 'determinate') { +
+ + + + +
+ } + +
+

Result

+ + + +
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/progress-snipper/progress-snipper.component.ts b/theme/packages/main/src/app/pages/ui-components/progress-snipper/progress-snipper.component.ts new file mode 100644 index 0000000..6d7a33a --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/progress-snipper/progress-snipper.component.ts @@ -0,0 +1,44 @@ +import { Component, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatCardModule } from '@angular/material/card'; +import { ThemePalette } from '@angular/material/core'; +import { MatProgressSpinnerModule, ProgressSpinnerMode } from '@angular/material/progress-spinner'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatSliderModule } from '@angular/material/slider'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { PROGRESS_SPINNER_BASIC_HTML_SNIPPET, PROGRESS_SPINNER_CONFIGURABLE_HTML_SNIPPET } from './code/progress-snipper-html-snippet'; +import { PROGRESS_SPINNER_BASIC_TS_SNIPPET, PROGRESS_SPINNER_CONFIGURABLE_TS_SNIPPET } from './code/progress-snipper-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +@Component({ + selector: 'app-progress-snipper', + imports: [MatCardModule, MatRadioModule, FormsModule, MatSliderModule, MatProgressSpinnerModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './progress-snipper.component.html' +}) +export class AppProgressSnipperComponent implements OnInit { + + // 1 [Basic with Progress spinner] + codeForProgressSpinnerBasic = PROGRESS_SPINNER_BASIC_HTML_SNIPPET; + codeForProgressSpinnerBasicTs = PROGRESS_SPINNER_BASIC_TS_SNIPPET; + + // 2 [Basic with Progress spinner] + codeForProgressSpinnerConfigurable = PROGRESS_SPINNER_CONFIGURABLE_HTML_SNIPPET; + codeForProgressSpinnerConfigurableTs = PROGRESS_SPINNER_CONFIGURABLE_TS_SNIPPET; + + constructor() {} + + ngOnInit(): void {} + + mode: ProgressSpinnerMode = 'determinate'; + value = 50; +} diff --git a/theme/packages/main/src/app/pages/ui-components/progress/code/progress-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/progress/code/progress-html-snippet.ts new file mode 100644 index 0000000..d2455e0 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/progress/code/progress-html-snippet.ts @@ -0,0 +1,59 @@ +export const PROGRESS_DETERMINATE_HTML_SNIPPET = ` +`; + +export const PROGRESS_INDETERMINATE_HTML_SNIPPET = ` +`; + +export const PROGRESS_QUERY_HTML_SNIPPET = ` +`; + +export const PROGRESS_BUFFER_HTML_SNIPPET = ` +`; + +export const PROGRESS_CONFIGURABLE_HTML_SNIPPET = `
+ + + + Determinate + + + Indeterminate + + + Buffer + + + Query + + +
+ + @if (mode === 'determinate' || mode === 'buffer') { +
+ + + + +
+ } + @if (mode === 'buffer') { +
+ + + + +
+ } + +
+

Result

+
+ + +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/progress/code/progress-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/progress/code/progress-ts-snippet.ts new file mode 100644 index 0000000..0905eeb --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/progress/code/progress-ts-snippet.ts @@ -0,0 +1,40 @@ +export const PROGRESS_DETERMINATE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatProgressBarModule} from '@angular/material/progress-bar'; + + /** + * @title Divider Progress + */ + @Component({ + selector: 'app-progress', + imports: [MatProgressBarModule], + templateUrl: './progress.component.html' + }) + export class AppProgressComponent { + constructor() {} + } +`; + +export const PROGRESS_CONFIGURABLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {ProgressBarMode, MatProgressBarModule} from '@angular/material/progress-bar'; + import {MatSliderModule} from '@angular/material/slider'; + import {FormsModule} from '@angular/forms'; + import {MatRadioModule} from '@angular/material/radio'; + import {MatCardModule} from '@angular/material/card'; + + /** + * @title Divider Progress + */ + @Component({ + selector: 'app-progress', + imports: [MatCardModule, MatRadioModule, FormsModule, MatSliderModule, MatProgressBarModule], + templateUrl: './progress.component.html' + }) + export class AppProgressComponent { + constructor() {} + + mode: ProgressBarMode = 'determinate'; + value = 50; + bufferValue = 75; + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/progress/progress.component.html b/theme/packages/main/src/app/pages/ui-components/progress/progress.component.html new file mode 100644 index 0000000..54a1684 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/progress/progress.component.html @@ -0,0 +1,178 @@ + +
+ Progress bar +
+ + + + +

+ Determinate +

+
+ +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Indeterminate +

+
+ +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Query +

+
+ +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Buffer +

+
+ +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Configurable +

+
+
+ + + + Determinate + + + Indeterminate + + + Buffer + + + Query + + +
+ + @if (mode === 'determinate' || mode === 'buffer') { +
+ + + + +
+ } + @if (mode === 'buffer') { +
+ + + + +
+ } + +
+

Result

+
+ + +
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/progress/progress.component.ts b/theme/packages/main/src/app/pages/ui-components/progress/progress.component.ts new file mode 100644 index 0000000..4ade4c4 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/progress/progress.component.ts @@ -0,0 +1,60 @@ +import { Component, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatCardModule } from '@angular/material/card'; +import { ThemePalette } from '@angular/material/core'; +import { ProgressBarMode } from '@angular/material/progress-bar'; +import {MatProgressBarModule} from '@angular/material/progress-bar'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatSliderModule } from '@angular/material/slider'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + + +// snippets +import { PROGRESS_BUFFER_HTML_SNIPPET, PROGRESS_CONFIGURABLE_HTML_SNIPPET, PROGRESS_DETERMINATE_HTML_SNIPPET, PROGRESS_INDETERMINATE_HTML_SNIPPET, PROGRESS_QUERY_HTML_SNIPPET } from './code/progress-html-snippet'; +import { PROGRESS_CONFIGURABLE_TS_SNIPPET, PROGRESS_DETERMINATE_TS_SNIPPET } from './code/progress-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-progress', + imports: [MatProgressBarModule, MatCardModule, FormsModule, MatSliderModule, MatRadioModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './progress.component.html' +}) + +export class AppProgressComponent implements OnInit { + + // 1 [determinate with Progress] + codeForProgressDeterminate = PROGRESS_DETERMINATE_HTML_SNIPPET; + codeForProgressDeterminateTs = PROGRESS_DETERMINATE_TS_SNIPPET; + + // 2 [Indeterminate with Progress] + codeForProgressIndeterminate = PROGRESS_INDETERMINATE_HTML_SNIPPET; + codeForProgressIndeterminateTs = PROGRESS_DETERMINATE_TS_SNIPPET; + + // 3 [Query with Progress] + codeForProgressQuery = PROGRESS_QUERY_HTML_SNIPPET; + codeForProgressQueryTs = PROGRESS_DETERMINATE_TS_SNIPPET; + + // 4 [Buffer with Progress] + codeForProgressBuffer = PROGRESS_BUFFER_HTML_SNIPPET; + codeForProgressBufferTs = PROGRESS_DETERMINATE_TS_SNIPPET; + + // 5 [Configurable with Progress] + codeForProgressConfigurable = PROGRESS_CONFIGURABLE_HTML_SNIPPET; + codeForProgressConfigurableTs = PROGRESS_CONFIGURABLE_TS_SNIPPET; + + + mode: ProgressBarMode = 'determinate'; + value = 50; + bufferValue = 75; + + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/ui-components/ripples/code/ripples-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/ripples/code/ripples-html-snippet.ts new file mode 100644 index 0000000..3ba8541 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/ripples/code/ripples-html-snippet.ts @@ -0,0 +1,19 @@ +export const RIPPLES_HTML_SNIPPET = ` Centered + Disabled + Unbounded +
+ + Radius + + + + Color + + +
+
+ Click me +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/ripples/code/ripples-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/ripples/code/ripples-ts-snippet.ts new file mode 100644 index 0000000..53a4e4b --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/ripples/code/ripples-ts-snippet.ts @@ -0,0 +1,29 @@ +export const RIPPLES_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatRippleModule} from '@angular/material/core'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + import {FormsModule} from '@angular/forms'; + import { MatCardModule } from '@angular/material/card'; + import {MatCheckboxModule} from '@angular/material/checkbox'; + + /** + * @title Divider Progress snipper + */ + @Component({ + selector: 'app-ripples', + imports: [MatCheckboxModule, FormsModule, MatFormFieldModule, MatInputModule, MatRippleModule, MatCardModule], + templateUrl: './ripples.component.html', + styleUrls: ['./ripples.component.scss'] + }) + export class AppRipplesComponent { + constructor() {} + + centered = false; + disabled = false; + unbounded = false; + + radius: number; + color: string; + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/ripples/ripples.component.html b/theme/packages/main/src/app/pages/ui-components/ripples/ripples.component.html new file mode 100644 index 0000000..009878d --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/ripples/ripples.component.html @@ -0,0 +1,41 @@ + + +

+ Ripples +

+
+ Centered + Disabled + Unbounded +
+ + Radius + + + + Color + + +
+
+ Click me +
+
+ +
+
+      
+    
+
+ +
+
+      
+    
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/ripples/ripples.component.scss b/theme/packages/main/src/app/pages/ui-components/ripples/ripples.component.scss new file mode 100644 index 0000000..aeca6f8 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/ripples/ripples.component.scss @@ -0,0 +1,24 @@ +.example-ripple-container { + cursor: pointer; + text-align: center; + + width: 300px; + height: 300px; + line-height: 300px; + + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + + -webkit-user-drag: none; + -webkit-tap-highlight-color: transparent; +} + +/** Styles to make the demo look better. */ +.example-ripple-checkbox { + margin: 6px 12px 6px 0; +} + +.example-ripple-form-field { + margin: 0 12px 0 0; +} \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/ripples/ripples.component.ts b/theme/packages/main/src/app/pages/ui-components/ripples/ripples.component.ts new file mode 100644 index 0000000..2ac44ea --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/ripples/ripples.component.ts @@ -0,0 +1,44 @@ +import { Component, OnInit } from '@angular/core'; +import {MatRippleModule} from '@angular/material/core'; +import {MatInputModule} from '@angular/material/input'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {FormsModule} from '@angular/forms'; +import {MatCheckboxModule} from '@angular/material/checkbox'; +import { MatCardModule } from '@angular/material/card'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { RIPPLES_HTML_SNIPPET } from './code/ripples-html-snippet'; +import { RIPPLES_TS_SNIPPET } from './code/ripples-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-ripples', + imports: [MatCheckboxModule, FormsModule, MatFormFieldModule, MatInputModule, MatRippleModule, MatCardModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './ripples.component.html', + styleUrls: ['./ripples.component.scss'] +}) +export class AppRipplesComponent implements OnInit { + + // 1 [Ripple] + codeForRipple = RIPPLES_HTML_SNIPPET; + codeForRippleTs = RIPPLES_TS_SNIPPET; + + centered = false; + disabled = false; + unbounded = false; + + radius: number; + color: string; + + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/ui-components/slide-toggle/code/slide-toggle-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/slide-toggle/code/slide-toggle-html-snippet.ts new file mode 100644 index 0000000..8b074e9 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/slide-toggle/code/slide-toggle-html-snippet.ts @@ -0,0 +1,61 @@ +export const BASIC_SLIDE_TOGGLE_HTML_SNIPPET = ` Slide me! +`; + +export const FORM_SLIDE_TOGGLE_HTML_SNIPPET = `

Slide Toggle using a simple NgModel.

+ + Slide Toggle Checked: {{isChecked}} + +
+
+

Slide Toggle inside of a Template-driven form

+ +
+
+ Enable Wifi + Accept Terms of Service +
+ +
+
+
+
+
+

Slide Toggle inside of a Reactive form

+ +
+
+ Enable Wifi + Accept Terms of Service + +

Form Group Status: {{formGroup.status}}

+
+ +
+
+
+
+
+`; + +export const CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET = `

Slide toggle configuration

+ +
+ Checked +
+ +
+ Disabled +
+ +
+

Result

+ +
+ + Slide me! + +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts new file mode 100644 index 0000000..de7ba0c --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts @@ -0,0 +1,69 @@ +export const BASIC_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + + /** + * @title slide-toggle + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatSlideToggleModule], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + } +`; + +export const FORM_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component, inject} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {FormBuilder, FormGroup, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {MatButtonModule} from '@angular/material/button'; + import { MatSlideToggleModule} from '@angular/material/slide-toggle'; + + /** + * @title Slide-toggle with forms + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatSlideToggleModule, FormsModule, MatButtonModule, ReactiveFormsModule,], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + + private _formBuilder = inject(FormBuilder); + + isChecked = true; + formGroup = this._formBuilder.group({ + enableWifi: '', + acceptTerms: ['', Validators.requiredTrue], + }); + + alertFormValues(formGroup: FormGroup) { + alert(JSON.stringify(formGroup.value, null, 2)); + } + } +`; + +export const CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {MatCheckboxModule} from '@angular/material/checkbox'; + import {FormsModule} from '@angular/forms'; + import {MatRadioModule} from '@angular/material/radio'; + import {MatCardModule} from '@angular/material/card'; + + /** + * @title Configurable slide-toggle + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatCardModule, MatRadioModule, FormsModule, MatCheckboxModule, MatSlideToggleModule], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + + checked = false; + disabled = false; + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/slide-toggle/slide-toggle.component.html b/theme/packages/main/src/app/pages/ui-components/slide-toggle/slide-toggle.component.html new file mode 100644 index 0000000..a4c89d6 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/slide-toggle/slide-toggle.component.html @@ -0,0 +1,133 @@ + +
+ Slide Toggle +
+ + + + +

+ Basic +

+
+ Slide me! +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Forms +

+
+

Slide Toggle using a simple NgModel.

+ + Slide Toggle Checked: {{isChecked}} + +
+
+

Slide Toggle inside of a Template-driven form

+ +
+
+ Enable Wifi + Accept Terms of Service +
+ +
+
+
+
+
+

Slide Toggle inside of a Reactive form

+ +
+
+ Enable Wifi + Accept Terms of Service + +

Form Group Status: {{formGroup.status}}

+
+ +
+
+
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Configuration +

+
+

Slide toggle configuration

+ +
+ Checked +
+ +
+ Disabled +
+ +
+

Result

+ +
+ + Slide me! + +
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts b/theme/packages/main/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts new file mode 100644 index 0000000..804e79f --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts @@ -0,0 +1,63 @@ +import { Component, OnInit, inject } from '@angular/core'; +import {FormBuilder, FormGroup, Validators, ReactiveFormsModule} from '@angular/forms'; +import { + MatSlideToggleModule, + // _MatSlideToggleRequiredValidatorModule, +} from '@angular/material/slide-toggle'; +import {MatCheckboxModule} from '@angular/material/checkbox'; +import {FormsModule} from '@angular/forms'; +import {MatRadioModule} from '@angular/material/radio'; +import {MatCardModule} from '@angular/material/card'; +import {MatButtonModule} from '@angular/material/button'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_SLIDE_TOGGLE_HTML_SNIPPET, CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET, FORM_SLIDE_TOGGLE_HTML_SNIPPET } from './code/slide-toggle-html-snippet'; +import { BASIC_SLIDE_TOGGLE_TS_SNIPPET, CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET, FORM_SLIDE_TOGGLE_TS_SNIPPET } from './code/slide-toggle-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-slide-toggle', + imports: [MatCardModule, MatRadioModule, FormsModule, MatCheckboxModule, MatSlideToggleModule, ReactiveFormsModule, MatButtonModule, + // _MatSlideToggleRequiredValidatorModule + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './slide-toggle.component.html' +}) +export class AppSlideToggleComponent implements OnInit { + + // 1 [Basic with Slide Toggle] + codeForSlideToggleBasic = BASIC_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleBasicTs = BASIC_SLIDE_TOGGLE_TS_SNIPPET; + + // 2 [Form with Slide Toggle] + codeForSlideToggleForm = FORM_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleFormTs = FORM_SLIDE_TOGGLE_TS_SNIPPET; + + // 3 [Configuration with Slide Toggle] + codeForSlideToggleConfiguration = CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleConfigurationTs = CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET; + + // configuration + checked = false; + disabled = false; + + private _formBuilder = inject(FormBuilder); + + isChecked = true; + formGroup = this._formBuilder.group({ + enableWifi: '', + acceptTerms: ['', Validators.requiredTrue], + }); + + alertFormValues(formGroup: FormGroup) { + alert(JSON.stringify(formGroup.value, null, 2)); + } + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/ui-components/slider/code/slider-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/slider/code/slider-html-snippet.ts new file mode 100644 index 0000000..6f9d5f2 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/slider/code/slider-html-snippet.ts @@ -0,0 +1,69 @@ +export const CONFIGURATION_SLIDER_HTML_SNIPPET = `
+
+ + Value + + +
+
+ + Min value + + +
+
+ + Max value + + +
+
+ + Step size + + +
+
+ +
+ Show ticks +
+ +
+ Show thumb label +
+ +
+ Disabled +
+ +
+

Result

+ +
+ + +
+ + + +
+`; + +export const CUSTOM_THUMB_LABEL_SLIDER_HTML_SNIPPET = ` + + +`; + +export const BASIC_SLIDER_HTML_SNIPPET = ` + + +`; + +export const RANGE_SLIDER_HTML_SNIPPET = ` + + + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/slider/code/slider-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/slider/code/slider-ts-snippet.ts new file mode 100644 index 0000000..0603822 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/slider/code/slider-ts-snippet.ts @@ -0,0 +1,75 @@ +export const CONFIGURATION_SLIDER_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSliderModule} from '@angular/material/slider'; + import {MatCheckboxModule} from '@angular/material/checkbox'; + import {FormsModule} from '@angular/forms'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + import {MatCardModule} from '@angular/material/card'; + + /** + * @title Configurable slider + */ + @Component({ + selector: 'app-slider', + imports: [ + MatCardModule, + MatFormFieldModule, + MatInputModule, + FormsModule, + MatCheckboxModule, + MatSliderModule, + ], + templateUrl: './slider.component.html' + }) + export class AppSliderComponent { + constructor() {} + + disabled = false; + max = 100; + min = 0; + showTicks = false; + step = 1; + thumbLabel = false; + value = 0; + } +`; + +export const CUSTOM_THUMB_LABEL_SLIDER_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSliderModule} from '@angular/material/slider'; + + /** + * @title Slider with custom thumb label formatting. + */ + @Component({ + selector: 'app-slider', + imports: [MatSliderModule], + templateUrl: './slider.component.html' + }) + export class AppSliderComponent { + constructor() {} + + formatLabel(value: number): string { + if (value >= 1000) { + return Math.round(value / 1000) + 'k'; + } + + return '{value}'; + } + } +`; + +export const BASIC_SLIDER_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSliderModule} from '@angular/material/slider'; + + /** + * @title Basic slider + */ + @Component({ + selector: 'app-slider', + imports: [MatSliderModule], + templateUrl: './slider.component.html' + }) + export class AppSliderComponent { + constructor() {} + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/slider/slider.component.html b/theme/packages/main/src/app/pages/ui-components/slider/slider.component.html new file mode 100644 index 0000000..f828036 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/slider/slider.component.html @@ -0,0 +1,174 @@ + +
+ Slider +
+ + + +

+ Configuration +

+
+
+
+ + Value + + +
+
+ + Min value + + +
+
+ + Max value + + +
+
+ + Step size + + +
+
+ +
+ Show ticks +
+ +
+ Show thumb label +
+ +
+ Disabled +
+ +
+

Result

+ +
+ + +
+ + + +
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
+ + + +

+ Custom thumb label +

+
+ + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + + +

+ Basic +

+
+ + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+
+ + + +

+ Range slider +

+
+ + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/slider/slider.component.ts b/theme/packages/main/src/app/pages/ui-components/slider/slider.component.ts new file mode 100644 index 0000000..e124466 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/slider/slider.component.ts @@ -0,0 +1,71 @@ +import { Component, OnInit } from '@angular/core'; +import {MatSliderModule} from '@angular/material/slider'; +import {MatCheckboxModule} from '@angular/material/checkbox'; +import {FormsModule} from '@angular/forms'; +import {MatInputModule} from '@angular/material/input'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {MatCardModule} from '@angular/material/card'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_SLIDER_HTML_SNIPPET, CONFIGURATION_SLIDER_HTML_SNIPPET, CUSTOM_THUMB_LABEL_SLIDER_HTML_SNIPPET, RANGE_SLIDER_HTML_SNIPPET } from './code/slider-html-snippet'; +import { BASIC_SLIDER_TS_SNIPPET, CONFIGURATION_SLIDER_TS_SNIPPET, CUSTOM_THUMB_LABEL_SLIDER_TS_SNIPPET } from './code/slider-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-slider', + imports: [ + MatCardModule, + MatFormFieldModule, + MatInputModule, + FormsModule, + MatCheckboxModule, + MatSliderModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './slider.component.html' +}) +export class AppSliderComponent implements OnInit { + + // 1 [Configuration with Slider] + codeForSliderConfiguration = CONFIGURATION_SLIDER_HTML_SNIPPET; + codeForSliderConfigurationTs = CONFIGURATION_SLIDER_TS_SNIPPET; + + // 2 [custom thumb label with Slider] + codeForSliderCustomThumbLabel = CUSTOM_THUMB_LABEL_SLIDER_HTML_SNIPPET; + codeForSliderCustomThumbLabelTs = CUSTOM_THUMB_LABEL_SLIDER_TS_SNIPPET; + + // 3 [basic with Slider] + codeForSliderBasic = BASIC_SLIDER_HTML_SNIPPET; + codeForSliderBasicTs = BASIC_SLIDER_TS_SNIPPET; + + // 4 [Range slider with Slider] + codeForSliderRange = RANGE_SLIDER_HTML_SNIPPET; + codeForSliderRangeTs = BASIC_SLIDER_TS_SNIPPET; + + disabled = false; + max = 100; + min = 0; + showTicks = false; + step = 1; + thumbLabel = false; + value = 0; + + // 2 + formatLabel(value: number): string { + if (value >= 1000) { + return Math.round(value / 1000) + 'k'; + } + + return `${value}`; + } + + constructor() {} + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/ui-components/snackbar/code/snackbar-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/snackbar/code/snackbar-html-snippet.ts new file mode 100644 index 0000000..a5b4217 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/snackbar/code/snackbar-html-snippet.ts @@ -0,0 +1,67 @@ +export const BASIC_SNACKBAR_HTML_SNIPPET = `
+
+ + Message + + +
+
+ + Action + + +
+
+ +
+
+`; + +export const CUSTOM_COMPONENT_SNACKBAR_HTML_SNIPPET = `
+
+ + Snack bar duration (seconds) + + +
+
+ +
+
+`; + +export const CONFIGURABLE_SNACKBAR_HTML_SNIPPET = `
+
+ + Horizontal position + + Start + Center + End + Left + Right + + +
+
+ + Vertical position + + Top + Bottom + + +
+
+ +
+
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/snackbar/code/snackbar-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/snackbar/code/snackbar-ts-snippet.ts new file mode 100644 index 0000000..7df5b8a --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/snackbar/code/snackbar-ts-snippet.ts @@ -0,0 +1,106 @@ +export const BASIC_SNACKBAR_TS_SNIPPET = ` import {Component, inject} from '@angular/core'; + import {MatSnackBar} from '@angular/material/snack-bar'; + import {MatButtonModule} from '@angular/material/button'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + /** + * @title Basic snack-bar + */ + @Component({ + selector: 'app-snackbar', + imports: [MatFormFieldModule, MatInputModule, MatButtonModule], + templateUrl: './snackbar.component.html' + }) + + export class AppSnackbarComponent { + constructor() {} + + private _snackBar = inject(MatSnackBar); + + openSnackBar(message: string, action: string) { + this._snackBar.open(message, action); + } + } +`; + +export const CUSTOM_COMPONENT_SNACKBAR_TS_SNIPPET = ` import {Component, inject} from '@angular/core'; + import {MatSnackBar} from '@angular/material/snack-bar'; + import {MatButtonModule} from '@angular/material/button'; + import {MatInputModule} from '@angular/material/input'; + import {FormsModule} from '@angular/forms'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + /** + * @title Snack-bar with a custom component + */ + @Component({ + selector: 'app-snackbar', + imports: [MatFormFieldModule, FormsModule, MatInputModule, MatButtonModule], + templateUrl: './snackbar.component.html' + }) + + export class AppSnackbarComponent { + constructor() {} + + private _snackBar = inject(MatSnackBar); + + durationInSeconds = 5; + + openSnackBar() { + this._snackBar.openFromComponent(PizzaPartyComponent, { + duration: this.durationInSeconds * 1000, + }); + } + } + + @Component({ + selector: 'app-custom-snackbar', + templateUrl: 'snackbar-custom.component.html', + styles: [ + + .example-pizza-party { + color: hotpink; + } + , + ], + standalone: false + }) + export class PizzaPartyComponent {} +`; + +export const CONFIGURABLE_SNACKBAR_TS_SNIPPET = ` import {Component, inject} from '@angular/core'; + import { + MatSnackBar, + MatSnackBarHorizontalPosition, + MatSnackBarVerticalPosition, + } from '@angular/material/snack-bar'; + import {MatButtonModule} from '@angular/material/button'; + import {MatSelectModule} from '@angular/material/select'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + /** + * @title Snack-bar with configurable position + */ + @Component({ + selector: 'app-snackbar', + imports: [MatFormFieldModule, MatSelectModule, MatButtonModule], + templateUrl: './snackbar.component.html' + }) + + export class AppSnackbarComponent { + constructor() {} + + private _snackBar = inject(MatSnackBar); + + horizontalPosition: MatSnackBarHorizontalPosition = 'start'; + verticalPosition: MatSnackBarVerticalPosition = 'bottom'; + + openSnackBar() { + this._snackBar.open('Cannonball!!', 'Splash', { + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + }); + } + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/snackbar/snackbar-custom.component.html b/theme/packages/main/src/app/pages/ui-components/snackbar/snackbar-custom.component.html new file mode 100644 index 0000000..9d78e75 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/snackbar/snackbar-custom.component.html @@ -0,0 +1 @@ + Pizza party!!! 🍕 diff --git a/theme/packages/main/src/app/pages/ui-components/snackbar/snackbar.component.html b/theme/packages/main/src/app/pages/ui-components/snackbar/snackbar.component.html new file mode 100644 index 0000000..f8e5a3a --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/snackbar/snackbar.component.html @@ -0,0 +1,141 @@ + +
+ Snackbar +
+ + + +

+ Basic +

+
+
+
+ + Message + + +
+
+ + Action + + +
+
+ +
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Custom Component +

+
+
+
+ + Snack bar duration (seconds) + + +
+
+ +
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Configurable +

+
+
+
+ + Horizontal position + + Start + Center + End + Left + Right + + +
+
+ + Vertical position + + Top + Bottom + + +
+
+ +
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/snackbar/snackbar.component.ts b/theme/packages/main/src/app/pages/ui-components/snackbar/snackbar.component.ts new file mode 100644 index 0000000..e046302 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/snackbar/snackbar.component.ts @@ -0,0 +1,83 @@ +import { Component } from '@angular/core'; +import { + MatSnackBar, + MatSnackBarHorizontalPosition, + MatSnackBarVerticalPosition, +} from '@angular/material/snack-bar'; +import {MatButtonModule} from '@angular/material/button'; +import {MatInputModule} from '@angular/material/input'; +import {FormsModule} from '@angular/forms'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; +import { MatCardModule } from '@angular/material/card'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_SNACKBAR_HTML_SNIPPET, CONFIGURABLE_SNACKBAR_HTML_SNIPPET, CUSTOM_COMPONENT_SNACKBAR_HTML_SNIPPET } from './code/snackbar-html-snippet'; +import { BASIC_SNACKBAR_TS_SNIPPET, CONFIGURABLE_SNACKBAR_TS_SNIPPET, CUSTOM_COMPONENT_SNACKBAR_TS_SNIPPET } from './code/snackbar-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-custom-snackbar', + templateUrl: 'snackbar-custom.component.html', + styles: [ + ` + .example-pizza-party { + color: hotpink; + } + `, + ], + standalone: false +}) +export class PizzaPartyComponent {} + +@Component({ + selector: 'app-snackbar', + imports: [MatFormFieldModule, FormsModule, MatInputModule, MatButtonModule, MatSelectModule, MatCardModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './snackbar.component.html' +}) +export class AppSnackbarComponent { + + // 1 [basic with snackbar] + codeForSnackbarBasic = BASIC_SNACKBAR_HTML_SNIPPET; + codeForSnackbarBasicTs = BASIC_SNACKBAR_TS_SNIPPET; + + // 2 [Custom Component with snackbar] + codeForSnackbarCustomComponent = CUSTOM_COMPONENT_SNACKBAR_HTML_SNIPPET; + codeForSnackbarCustomComponentTs = CUSTOM_COMPONENT_SNACKBAR_TS_SNIPPET; + + // 3 [Configurable with snackbar] + codeForSnackbarConfigurable = CONFIGURABLE_SNACKBAR_HTML_SNIPPET; + codeForSnackbarConfigurableTs = CONFIGURABLE_SNACKBAR_TS_SNIPPET; + + durationInSeconds = 5; + + horizontalPosition: MatSnackBarHorizontalPosition = 'start'; + verticalPosition: MatSnackBarVerticalPosition = 'bottom'; + + constructor(private _snackBar: MatSnackBar) {} + + openSnackBar(message: string, action: string) { + this._snackBar.open(message, action); + } + + openCustomSnackBar() { + this._snackBar.openFromComponent(PizzaPartyComponent, { + duration: this.durationInSeconds * 1000, + }); + } + + openConfigSnackBar() { + this._snackBar.open('Cannonball!!', 'Splash', { + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + }); + } +} diff --git a/theme/packages/main/src/app/pages/ui-components/tabs/code/tabs-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/tabs/code/tabs-html-snippet.ts new file mode 100644 index 0000000..1b08535 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/tabs/code/tabs-html-snippet.ts @@ -0,0 +1,597 @@ +export const BASIC_TABS_HTML_SNIPPET = ` + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+`; + +export const CENTER_ALIGN_TABS_HTML_SNIPPET = ` + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+`; + +export const RIGHT_ALIGN_TABS_HTML_SNIPPET = ` + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+`; + +export const NO_ANIMATION_TABS_HTML_SNIPPET = ` + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+`; + +export const SLOW_ANIMATION_TABS_HTML_SNIPPET = ` + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+`; + +export const GROUP_TABS_HTML_SNIPPET = ` + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+`; + +export const CUSTOM_LABEL_TABS_HTML_SNIPPET = ` + + +
+ + + +
+ Item One +
+
+ Content 1 +
+
+ + +
+ + + +
+ Item Two +
+
+ Content 2 +
+
+ + +
+ + + +
+ Item Three +
+
+ Content 3 +
+
+
+`; + +export const ICON_TABS_HTML_SNIPPET = ` + + +
+ + + +
+
+
+ Content 1 +
+
+ + +
+ + + +
+
+
+ Content 2 +
+
+ + +
+ + + +
+
+
+ Content 3 +
+
+
+`; + +export const POSITION_TABS_HTML_SNIPPET = ` + + +
+ + + +
+ Item One +
+
+ Content 1 +
+
+ + +
+ + + +
+ Item Two +
+
+ Content 2 +
+
+ + +
+ + + +
+ Item Three +
+
+ Content 3 +
+
+
+`; + +export const POSITION_WITH_ICON_TABS_HTML_SNIPPET = ` + + +
+ + + +
+
+
+ Content 1 +
+
+ + +
+ + + +
+
+
+ Content 2 +
+
+ + +
+ + + +
+
+
+ Content 3 +
+
+ + +
+ + + +
+
+
+ Content 4 +
+
+ + +
+ + + +
+
+
+ Content 5 +
+
+
+`; + +export const BACKGROUND_TABS_HTML_SNIPPET = ` + + +
+ + + +
+
+
+ Content 1 +
+
+ + +
+ + + +
+
+
+ Content 2 +
+
+ + +
+ + + +
+
+
+ Content 3 +
+
+ + +
+ + + +
+
+
+ Content 4 +
+
+ + +
+ + + +
+
+
+ Content 5 +
+
+
+`; + +export const FIT_TO_BAR_CONTENT_TABS_HTML_SNIPPET = ` + + +
+ + + +
+
+
+ Content 1 +
+
+ + +
+ + + +
+
+
+ Content 2 +
+
+ + +
+ + + +
+
+
+ Content 3 +
+
+ + +
+ + + +
+
+
+ Content 4 +
+
+ + +
+ + + +
+
+
+ Content 5 +
+
+
+`; + +export const CONTENT_LOADED_LAZILY_TABS_HTML_SNIPPET = ` + + +
+ Content 1 - Loaded: {{ getTimeLoaded(1) | date : "medium" }} +
+
+
+ + +
+ Content 2 - Loaded: {{ getTimeLoaded(2) | date : "medium" }} +
+
+
+ + +
+ Content 3 - Loaded: {{ getTimeLoaded(3) | date : "medium" }} +
+
+
+
+`; + +export const PAGINATED_TABS_HTML_SNIPPET = ` + + +
+ + + +
+ Item One +
+
+ Content 1 +
+
+ + +
+ + + +
+ Item Two +
+
+ Content 2 +
+
+ + +
+ + + +
+ Item Three +
+
+ Content 3 +
+
+ + +
+ + + +
+ Item Four +
+
+ Content 4 +
+
+ + +
+ + + +
+ Item Five +
+
+ Content 5 +
+
+ + +
+ + + +
+ Item Six +
+
+ Content 6 +
+
+ + +
+ + + +
+ Item Seven +
+
+ Content 7 +
+
+ + +
+ + + +
+ Item Eight +
+
+ Content 8 +
+
+ + +
+ + + +
+ Item Nine +
+
+ Content 9 +
+
+
+`; + +export const NAVBAR_BACKGROUND_TABS_HTML_SNIPPET = ` + +
+ + +
+`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/tabs/code/tabs-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/tabs/code/tabs-ts-snippet.ts new file mode 100644 index 0000000..c3cfb24 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/tabs/code/tabs-ts-snippet.ts @@ -0,0 +1,124 @@ +export const BASIC_TABS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatTabsModule} from '@angular/material/tabs'; + + /** + * @title Basic tabs + */ + @Component({ + selector: 'app-tabs', + imports: [MatTabsModule], + templateUrl: './tabs.component.html' + }) + + export class AppTabsComponent { + constructor() {} + } +`; + +export const BACKGROUND_TABS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatTabsModule} from '@angular/material/tabs'; + + /** + * @title background tabs + */ + @Component({ + selector: 'app-tabs', + imports: [MatTabsModule], + templateUrl: './tabs.component.html' + }) + + export class AppTabsComponent { + constructor() {} + + links = ['Item One', 'Item Second', 'Item Third']; + activeLink = this.links[0]; + background: ThemePalette = undefined; + + toggleBackground() { + this.background = this.background ? undefined : 'primary'; + } + + addLink() { + this.links.push('Link {this.links.length + 1}'); + } + } +`; + +export const CONTENT_LOADED_LAZILY_TABS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {DatePipe} from '@angular/common'; + import {MatTabsModule} from '@angular/material/tabs'; + + /** + * @title background tabs + */ + @Component({ + selector: 'app-tabs', + imports: [MatTabsModule, DatePipe], + templateUrl: './tabs.component.html' + }) + + export class AppTabsComponent { + constructor() {} + + tabLoadTimes: Date[] = []; + + getTimeLoaded(index: number) { + if (!this.tabLoadTimes[index]) { + this.tabLoadTimes[index] = new Date(); + } + + return this.tabLoadTimes[index]; + } + } +`; + +export const PAGINATED_TABS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatTabsModule} from '@angular/material/tabs'; + + /** + * @title Paginated tabs + */ + @Component({ + selector: 'app-tabs', + imports: [MatTabsModule], + templateUrl: './tabs.component.html' + }) + + export class AppTabsComponent { + constructor() {} + + lotsOfTabs = new Array(30).fill(0).map((_, index) => 'Tab {index}'); + + } +`; + +export const NAVBAR_BACKGROUND_TABS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatTabsModule} from '@angular/material/tabs'; + + /** + * @title Navbar Background tabs + */ + @Component({ + selector: 'app-tabs', + imports: [MatTabsModule], + templateUrl: './tabs.component.html' + }) + + export class AppTabsComponent { + constructor() {} + + // background + links = ['Item One', 'Item Second', 'Item Third']; + activeLink = this.links[0]; + background: ThemePalette = undefined; + + toggleBackground() { + this.background = this.background ? undefined : 'primary'; + } + + addLink() { + this.links.push('Link {this.links.length + 1}'); + } + + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/tabs/tabs.component.html b/theme/packages/main/src/app/pages/ui-components/tabs/tabs.component.html new file mode 100644 index 0000000..1545395 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/tabs/tabs.component.html @@ -0,0 +1,953 @@ + +
+ Tabs +
+ +
+
+ + +

+ Basic +

+
+ + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Center Align +

+
+ + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Right Align +

+
+ + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ No Animation +

+
+ + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Slow Animation +

+
+ + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Tab Group +

+
+ + +
+ Content 1 +
+
+ +
+ Content 2 +
+
+ +
+ Content 3 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Cusom Label +

+
+ + + +
+ + + +
+ Item One +
+
+ Content 1 +
+
+ + +
+ + + +
+ Item Two +
+
+ Content 2 +
+
+ + +
+ + + +
+ Item Three +
+
+ Content 3 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Icon +

+
+ + + +
+ + + +
+
+
+ Content 1 +
+
+ + +
+ + + +
+
+
+ Content 2 +
+
+ + +
+ + + +
+
+
+ Content 3 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Position +

+
+ + + +
+ + + +
+ Item One +
+
+ Content 1 +
+
+ + +
+ + + +
+ Item Two +
+
+ Content 2 +
+
+ + +
+ + + +
+ Item Three +
+
+ Content 3 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Position with Icons +

+
+ + + +
+ + + +
+
+
+ Content 1 +
+
+ + +
+ + + +
+
+
+ Content 2 +
+
+ + +
+ + + +
+
+
+ Content 3 +
+
+ + +
+ + + +
+
+
+ Content 4 +
+
+ + +
+ + + +
+
+
+ Content 5 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Background +

+
+ + + +
+ + + +
+ Item One +
+
+ Content 1 +
+
+ + +
+ + + +
+ Item Two +
+
+ Content 2 +
+
+ + +
+ + + +
+ Item Three +
+
+ Content 3 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Fit to Bar Content +

+
+ + + +
+ + + +
+
+
+ Content 1 +
+
+ + +
+ + + +
+
+
+ Content 2 +
+
+ + +
+ + + +
+
+
+ Content 3 +
+
+ + +
+ + + +
+
+
+ Content 4 +
+
+ + +
+ + + +
+
+
+ Content 5 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Tab Content loaded lazily +

+
+ + + +
+ Content 1 - Loaded: {{ getTimeLoaded(1) | date : "medium" }} +
+
+
+ + +
+ Content 2 - Loaded: {{ getTimeLoaded(2) | date : "medium" }} +
+
+
+ + +
+ Content 3 - Loaded: {{ getTimeLoaded(3) | date : "medium" }} +
+
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Paginated tabs +

+
+ + + +
+ + + +
+ Item One +
+
+ Content 1 +
+
+ + +
+ + + +
+ Item Two +
+
+ Content 2 +
+
+ + +
+ + + +
+ Item Three +
+
+ Content 3 +
+
+ + +
+ + + +
+ Item Four +
+
+ Content 4 +
+
+ + +
+ + + +
+ Item Five +
+
+ Content 5 +
+
+ + +
+ + + +
+ Item Six +
+
+ Content 6 +
+
+ + +
+ + + +
+ Item Seven +
+
+ Content 7 +
+
+ + +
+ + + +
+ Item Eight +
+
+ Content 8 +
+
+ + +
+ + + +
+ Item Nine +
+
+ Content 9 +
+
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Tab Navbar Background +

+
+ + +
+ + +
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/tabs/tabs.component.ts b/theme/packages/main/src/app/pages/ui-components/tabs/tabs.component.ts new file mode 100644 index 0000000..734f50a --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/tabs/tabs.component.ts @@ -0,0 +1,115 @@ +import { Component } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; +import { ThemePalette } from '@angular/material/core'; +import { MatIconModule } from '@angular/material/icon'; +import {MatTabsModule} from '@angular/material/tabs'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import {DatePipe} from '@angular/common'; +import { MatButtonModule } from '@angular/material/button'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BACKGROUND_TABS_HTML_SNIPPET, BASIC_TABS_HTML_SNIPPET, CENTER_ALIGN_TABS_HTML_SNIPPET, CONTENT_LOADED_LAZILY_TABS_HTML_SNIPPET, CUSTOM_LABEL_TABS_HTML_SNIPPET, FIT_TO_BAR_CONTENT_TABS_HTML_SNIPPET, GROUP_TABS_HTML_SNIPPET, ICON_TABS_HTML_SNIPPET, NAVBAR_BACKGROUND_TABS_HTML_SNIPPET, NO_ANIMATION_TABS_HTML_SNIPPET, PAGINATED_TABS_HTML_SNIPPET, POSITION_TABS_HTML_SNIPPET, POSITION_WITH_ICON_TABS_HTML_SNIPPET, RIGHT_ALIGN_TABS_HTML_SNIPPET, SLOW_ANIMATION_TABS_HTML_SNIPPET } from './code/tabs-html-snippet'; +import { BACKGROUND_TABS_TS_SNIPPET, BASIC_TABS_TS_SNIPPET, CONTENT_LOADED_LAZILY_TABS_TS_SNIPPET, NAVBAR_BACKGROUND_TABS_TS_SNIPPET, PAGINATED_TABS_TS_SNIPPET } from './code/tabs-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-tabs', + imports: [MatTabsModule, MatCardModule, MatIconModule, TablerIconsModule, DatePipe, MatButtonModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './tabs.component.html' +}) +export class AppTabsComponent { + + // 1 [Basic with tabs] + codeForTabsBasic = BASIC_TABS_HTML_SNIPPET; + codeForTabsBasicTs = BASIC_TABS_TS_SNIPPET; + + // 2 [Center Align with tabs] + codeForTabsCenterAlign = CENTER_ALIGN_TABS_HTML_SNIPPET; + codeForTabsCenterAlignTs = BASIC_TABS_TS_SNIPPET; + + // 3 [right Align with tabs] + codeForTabsRightAlign = RIGHT_ALIGN_TABS_HTML_SNIPPET; + codeForTabsRightAlignTs = BASIC_TABS_TS_SNIPPET; + + // 4 [No Animation with tabs] + codeForTabsNoAnimation = NO_ANIMATION_TABS_HTML_SNIPPET; + codeForTabsNoAnimationTs = BASIC_TABS_TS_SNIPPET; + + // 5 [Slow Animation with tabs] + codeForTabsSlowAnimation = SLOW_ANIMATION_TABS_HTML_SNIPPET; + codeForTabsSlowAnimationTs = BASIC_TABS_TS_SNIPPET; + + // 6 [Group with tabs] + codeForTabsGroup = GROUP_TABS_HTML_SNIPPET; + codeForTabsGroupTs = BASIC_TABS_TS_SNIPPET; + + // 7 [Cusom Label with tabs] + codeForTabsCusomLabel = CUSTOM_LABEL_TABS_HTML_SNIPPET; + codeForTabsCusomLabelTs = BASIC_TABS_TS_SNIPPET; + + // 8 [icon with tabs] + codeForTabsIcon = ICON_TABS_HTML_SNIPPET; + codeForTabsIconTs = BASIC_TABS_TS_SNIPPET; + + // 9 [position with tabs] + codeForTabsPosition = POSITION_TABS_HTML_SNIPPET; + codeForTabsPositionTs = BASIC_TABS_TS_SNIPPET; + + // 10 [position with tabs] + codeForTabsPositionWithIcon = POSITION_WITH_ICON_TABS_HTML_SNIPPET; + codeForTabsPositionWithIconTs = BASIC_TABS_TS_SNIPPET; + + // 11 [Background with tabs] + codeForTabsBackground = BACKGROUND_TABS_HTML_SNIPPET; + codeForTabsBackgroundTs = BACKGROUND_TABS_TS_SNIPPET; + + // 12 [Fit to Bar Content with tabs] + codeForTabsFitToBarContent = FIT_TO_BAR_CONTENT_TABS_HTML_SNIPPET; + codeForTabsFitToBarContentTs = BASIC_TABS_TS_SNIPPET; + + // 13 [Content loaded lazily with tabs] + codeForTabsContentLoadedLazily = CONTENT_LOADED_LAZILY_TABS_HTML_SNIPPET; + codeForTabsContentLoadedLazilyTs = CONTENT_LOADED_LAZILY_TABS_TS_SNIPPET; + + // 14 [Paginated with tabs] + codeForTabsPaginated = PAGINATED_TABS_HTML_SNIPPET; + codeForTabsPaginatedTs = PAGINATED_TABS_TS_SNIPPET; + + // 15 [Navbar Background with tabs] + codeForTabsNavbarBackground = NAVBAR_BACKGROUND_TABS_HTML_SNIPPET; + codeForTabsNavbarBackgroundTs = NAVBAR_BACKGROUND_TABS_TS_SNIPPET; + + constructor() {} + + // loaded lazily + tabLoadTimes: Date[] = []; + + getTimeLoaded(index: number) { + if (!this.tabLoadTimes[index]) { + this.tabLoadTimes[index] = new Date(); + } + + return this.tabLoadTimes[index]; + } + + // background + links = ['Item One', 'Item Second', 'Item Third']; + activeLink = this.links[0]; + background: ThemePalette = undefined; + + toggleBackground() { + this.background = this.background ? undefined : 'primary'; + } + + addLink() { + this.links.push(`Link ${this.links.length + 1}`); + } +} diff --git a/theme/packages/main/src/app/pages/ui-components/toolbar/code/toolbar-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/toolbar/code/toolbar-html-snippet.ts new file mode 100644 index 0000000..c73334c --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/toolbar/code/toolbar-html-snippet.ts @@ -0,0 +1,48 @@ +export const BASIC_TOOLBAR_HTML_SNIPPET = `
+
+ + Message + + +
+
+ + Action + + +
+
+ +
+
+`; + +export const MULTI_ROW_TOOLBAR_HTML_SNIPPET = ` + + Custom Toolbar + + + + Second Line + + verified_user + + + + Third Line + +
+ favorite + delete +
+
+
+`; + +export const ONLY_BRAND_TOOLBAR_HTML_SNIPPET = ` + Modernize + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/toolbar/code/toolbar-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/toolbar/code/toolbar-ts-snippet.ts new file mode 100644 index 0000000..a1d7f4f --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/toolbar/code/toolbar-ts-snippet.ts @@ -0,0 +1,18 @@ +export const BASIC_TOOLBAR_TS_SNIPPET = ` import {Component, inject} from '@angular/core'; + import {MatIconModule} from '@angular/material/icon'; + import {MatButtonModule} from '@angular/material/button'; + import {MatToolbarModule} from '@angular/material/toolbar'; + + /** + * @title Basic toolbar + */ + @Component({ + selector: 'app-toolbar', + imports: [MatToolbarModule, MatButtonModule, MatIconModule], + templateUrl: './toolbar.component.html' + }) + + export class AppToolbarComponent { + constructor() {} + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/toolbar/toolbar.component.html b/theme/packages/main/src/app/pages/ui-components/toolbar/toolbar.component.html new file mode 100644 index 0000000..5f6614f --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/toolbar/toolbar.component.html @@ -0,0 +1,123 @@ + +
+ Toolbar +
+ + + +

+ Basic +

+
+ + + My App + + + + +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + + +

+ Multi Row +

+
+ + + Custom Toolbar + + + + Second Line + + verified_user + + + + Third Line + +
+ favorite + delete +
+
+
+
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ + + +

+ Only Brand +

+
+ + Modernize + +
+ +
+
+          
+        
+
+ +
+
+          
+        
+
+
+ +
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/toolbar/toolbar.component.ts b/theme/packages/main/src/app/pages/ui-components/toolbar/toolbar.component.ts new file mode 100644 index 0000000..a0e7a17 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/toolbar/toolbar.component.ts @@ -0,0 +1,42 @@ +import { Component, OnInit } from '@angular/core'; +import {MatIconModule} from '@angular/material/icon'; +import {MatButtonModule} from '@angular/material/button'; +import {MatToolbarModule} from '@angular/material/toolbar'; +import { MatCardModule } from '@angular/material/card'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_TOOLBAR_HTML_SNIPPET, MULTI_ROW_TOOLBAR_HTML_SNIPPET, ONLY_BRAND_TOOLBAR_HTML_SNIPPET } from './code/toolbar-html-snippet'; +import { BASIC_TOOLBAR_TS_SNIPPET } from './code/toolbar-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-toolbar', + imports: [MatToolbarModule, MatButtonModule, MatIconModule, MatCardModule, TablerIconsModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './toolbar.component.html' +}) +export class AppToolbarComponent implements OnInit { + constructor() {} + + // 1 [basic with toolbar] + codeForToolbarBasic = BASIC_TOOLBAR_HTML_SNIPPET; + codeForToolbarBasicTs = BASIC_TOOLBAR_TS_SNIPPET; + + // 2 [Multi Row with toolbar] + codeForToolbarMultiRow = MULTI_ROW_TOOLBAR_HTML_SNIPPET; + codeForToolbarMultiRowTs = BASIC_TOOLBAR_TS_SNIPPET; + + // 3 [Only Brand with toolbar] + codeForToolbarOnlyBrand = ONLY_BRAND_TOOLBAR_HTML_SNIPPET; + codeForToolbarOnlyBrandTs = BASIC_TOOLBAR_TS_SNIPPET; + + ngOnInit(): void {} +} diff --git a/theme/packages/main/src/app/pages/ui-components/tooltips/code/tooltips-html-snippet.ts b/theme/packages/main/src/app/pages/ui-components/tooltips/code/tooltips-html-snippet.ts new file mode 100644 index 0000000..cd66563 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/tooltips/code/tooltips-html-snippet.ts @@ -0,0 +1,72 @@ +export const BASIC_TOOLTIPS_HTML_SNIPPET = ` +`; + +export const UPPERCASE_TOOLTIPS_HTML_SNIPPET = ` +`; + +export const DISABLED_CLICK_TOOLTIPS_HTML_SNIPPET = ` + + + Tooltip disabled + +`; + +export const POSITION_TOOLTIPS_HTML_SNIPPET = ` + + + +`; + +export const SHOW_AND_HIDE_TOOLTIPS_HTML_SNIPPET = `
+
+ + Show delay + + milliseconds + +
+
+ + Hide delay + + milliseconds + +
+
+ +
+
+`; + +export const CHANGE_MESSAGE_TOOLTIPS_HTML_SNIPPET = ` + Tooltip message + + + + +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/tooltips/code/tooltips-ts-snippet.ts b/theme/packages/main/src/app/pages/ui-components/tooltips/code/tooltips-ts-snippet.ts new file mode 100644 index 0000000..a937281 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/tooltips/code/tooltips-ts-snippet.ts @@ -0,0 +1,100 @@ +export const BASIC_TOOLTIPS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatTooltipModule} from '@angular/material/tooltip'; + import {MatButtonModule} from '@angular/material/button'; + + /** + * @title Basic tooltip + */ + @Component({ + selector: 'app-tooltips', + imports: [MatButtonModule, MatTooltipModule], + templateUrl: './tooltips.component.html' + }) + + export class AppTooltipsComponent { + constructor() {} + } +`; + +export const DISABLED_CLICK_TOOLTIPS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {MatCheckboxModule} from '@angular/material/checkbox'; + import {MatTooltipModule} from '@angular/material/tooltip'; + import {MatButtonModule} from '@angular/material/button'; + + /** + * @title Tooltip that can be disabled + */ + @Component({ + selector: 'app-tooltips', + imports: [MatButtonModule, MatTooltipModule, MatCheckboxModule, FormsModule, ReactiveFormsModule], + templateUrl: './tooltips.component.html' + }) + + export class AppTooltipsComponent { + constructor() {} + + disabled = new FormControl(false); + } +`; + +export const SHOW_AND_HIDE_TOOLTIPS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {MatTooltipModule} from '@angular/material/tooltip'; + import {MatButtonModule} from '@angular/material/button'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + /** + * @title Tooltip with a show and hide delay + */ + @Component({ + selector: 'app-tooltips', + imports: [ + MatFormFieldModule, + MatInputModule, + FormsModule, + ReactiveFormsModule, + MatButtonModule, + MatTooltipModule, + ], + templateUrl: './tooltips.component.html' + }) + + export class AppTooltipsComponent { + constructor() {} + + showDelay = new FormControl(1000); + hideDelay = new FormControl(2000); + } +`; + +export const CHANGE_MESSAGE_TOOLTIPS_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {MatTooltipModule} from '@angular/material/tooltip'; + import {MatButtonModule} from '@angular/material/button'; + import {MatInputModule} from '@angular/material/input'; + import {MatFormFieldModule} from '@angular/material/form-field'; + + /** + * @title Tooltip with a changing message + */ + @Component({ + selector: 'app-tooltips', + imports: [ + MatFormFieldModule, + MatInputModule, + FormsModule, + ReactiveFormsModule, + MatButtonModule, + MatTooltipModule, + ], + templateUrl: './tooltips.component.html' + }) + + export class AppTooltipsComponent { + constructor() {} + + message = new FormControl('Info about the action'); + } +`; \ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/tooltips/tooltips.component.html b/theme/packages/main/src/app/pages/ui-components/tooltips/tooltips.component.html new file mode 100644 index 0000000..1cdcb06 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/tooltips/tooltips.component.html @@ -0,0 +1,229 @@ + +
+ Tooltips +
+ +
+
+ + +

+ Basic +

+
+ +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Uppercase +

+
+ +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+ + +

+ Disabled on click +

+
+ + + + Tooltip disabled + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Position +

+
+ + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Show and Hide +

+
+
+
+ + Show delay + + milliseconds + +
+
+ + Hide delay + + milliseconds + +
+
+ +
+
+
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+ +
+ + +

+ Change Message +

+
+ + Tooltip message + + + + +
+ +
+
+              
+            
+
+ +
+
+              
+            
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/ui-components/tooltips/tooltips.component.ts b/theme/packages/main/src/app/pages/ui-components/tooltips/tooltips.component.ts new file mode 100644 index 0000000..a5dd10e --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/tooltips/tooltips.component.ts @@ -0,0 +1,72 @@ +import { Component } from '@angular/core'; +import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {TooltipPosition, MatTooltipModule} from '@angular/material/tooltip'; +import {MatButtonModule} from '@angular/material/button'; +import {CdkScrollable} from '@angular/cdk/scrolling'; +import {MatSelectModule} from '@angular/material/select'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import { MatCardModule } from '@angular/material/card'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_TOOLTIPS_TS_SNIPPET, CHANGE_MESSAGE_TOOLTIPS_TS_SNIPPET, DISABLED_CLICK_TOOLTIPS_TS_SNIPPET, SHOW_AND_HIDE_TOOLTIPS_TS_SNIPPET } from './code/tooltips-ts-snippet'; +import { BASIC_TOOLTIPS_HTML_SNIPPET, CHANGE_MESSAGE_TOOLTIPS_HTML_SNIPPET, DISABLED_CLICK_TOOLTIPS_HTML_SNIPPET, POSITION_TOOLTIPS_HTML_SNIPPET, SHOW_AND_HIDE_TOOLTIPS_HTML_SNIPPET, UPPERCASE_TOOLTIPS_HTML_SNIPPET } from './code/tooltips-html-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + + +@Component({ + selector: 'app-tooltips', + imports: [ + MatFormFieldModule, + MatSelectModule, + FormsModule, + ReactiveFormsModule, + MatButtonModule, + MatTooltipModule, MatCardModule, MatInputModule, MatCheckboxModule, + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './tooltips.component.html' +}) +export class AppTooltipsComponent { + + // 1 [tooltips with toolbar] + codeForTooltipsBasic = BASIC_TOOLTIPS_HTML_SNIPPET; + codeForTooltipsBasicTs = BASIC_TOOLTIPS_TS_SNIPPET; + + // 2 [Uppercase with toolbar] + codeForTooltipsUppercase = UPPERCASE_TOOLTIPS_HTML_SNIPPET; + codeForTooltipsUppercaseTs = BASIC_TOOLTIPS_TS_SNIPPET; + + // 3 [Disabled on click with toolbar] + codeForTooltipsDisabledClick = DISABLED_CLICK_TOOLTIPS_HTML_SNIPPET; + codeForTooltipsDisabledClickTs = DISABLED_CLICK_TOOLTIPS_TS_SNIPPET; + + // 4 [Position with toolbar] + codeForTooltipsPosition = POSITION_TOOLTIPS_HTML_SNIPPET; + codeForTooltipsPositionTs = BASIC_TOOLTIPS_TS_SNIPPET; + + // 5 [Show and Hide with toolbar] + codeForTooltipsShowAndHide = SHOW_AND_HIDE_TOOLTIPS_HTML_SNIPPET; + codeForTooltipsShowAndHideTs = SHOW_AND_HIDE_TOOLTIPS_TS_SNIPPET; + + // 6 [Change Message with toolbar] + codeForTooltipsChangeMessage = CHANGE_MESSAGE_TOOLTIPS_HTML_SNIPPET; + codeForTooltipsChangeMessageTs = CHANGE_MESSAGE_TOOLTIPS_TS_SNIPPET; + + // disabled + disabled = new FormControl(false); + + // show and hide + showDelay = new FormControl(1000); + hideDelay2 = new FormControl(2000); + + // change message + message = new FormControl('Info about the action'); +} diff --git a/theme/packages/main/src/app/pages/ui-components/ui-components.routes.ts b/theme/packages/main/src/app/pages/ui-components/ui-components.routes.ts new file mode 100644 index 0000000..ce02737 --- /dev/null +++ b/theme/packages/main/src/app/pages/ui-components/ui-components.routes.ts @@ -0,0 +1,215 @@ +import { Routes } from '@angular/router'; + +// ui +import { AppBadgeComponent } from './badge/badge.component'; +import { AppChipsComponent } from './chips/chips.component'; +import { AppDialogComponent } from './dialog/dialog.component'; +import { AppDividerComponent } from './divider/divider.component'; +import { AppExpansionComponent } from './expansion/expansion.component'; +import { AppListsComponent } from './lists/lists.component'; +import { AppMenuComponent } from './menu/menu.component'; +import { AppPaginatorComponent } from './paginator/paginator.component'; +import { AppProgressSnipperComponent } from './progress-snipper/progress-snipper.component'; +import { AppProgressComponent } from './progress/progress.component'; +import { AppRipplesComponent } from './ripples/ripples.component'; +import { AppSlideToggleComponent } from './slide-toggle/slide-toggle.component'; +import { AppSliderComponent } from './slider/slider.component'; +import { AppSnackbarComponent } from './snackbar/snackbar.component'; +import { AppTabsComponent } from './tabs/tabs.component'; +import { AppToolbarComponent } from './toolbar/toolbar.component'; +import { AppTooltipsComponent } from './tooltips/tooltips.component'; + +export const UiComponentsRoutes: Routes = [ + { + path: '', + children: [ + { + path: 'badge', + component: AppBadgeComponent, + data: { + title: 'Badge', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Badge' }, + ], + }, + }, + { + path: 'expansion', + component: AppExpansionComponent, + data: { + title: 'Expansion Panel', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Expansion Panel' }, + ], + }, + }, + { + path: 'chips', + component: AppChipsComponent, + data: { + title: 'Chip', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Chip' }, + ], + }, + }, + { + path: 'dialog', + component: AppDialogComponent, + data: { + title: 'Dialog', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Dialog' }, + ], + }, + }, + { + path: 'lists', + component: AppListsComponent, + data: { + title: 'Lists', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Lists' }, + ], + }, + }, + { + path: 'divider', + component: AppDividerComponent, + data: { + title: 'Divider', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Divider' }, + ], + }, + }, + { + path: 'menu', + component: AppMenuComponent, + data: { + title: 'Menu', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Menu' }, + ], + }, + }, + { + path: 'paginator', + component: AppPaginatorComponent, + data: { + title: 'Paginator', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Paginator' }, + ], + }, + }, + { + path: 'progress', + component: AppProgressComponent, + data: { + title: 'Progress', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Progress' }, + ], + }, + }, + { + path: 'progress-spinner', + component: AppProgressSnipperComponent, + data: { + title: 'Progress Spinner', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Progress Spinner' }, + ], + }, + }, + { + path: 'ripples', + component: AppRipplesComponent, + data: { + title: 'Ripples', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Ripples' }, + ], + }, + }, + { + path: 'slide-toggle', + component: AppSlideToggleComponent, + data: { + title: 'Slide Toggle', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Slide Toggle' }, + ], + }, + }, + { + path: 'slider', + component: AppSliderComponent, + data: { + title: 'Slider', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Slider' }, + ], + }, + }, + { + path: 'snackbar', + component: AppSnackbarComponent, + data: { + title: 'Snackbar', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Snackbar' }, + ], + }, + }, + { + path: 'tabs', + component: AppTabsComponent, + data: { + title: 'Tabs', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Tabs' }, + ], + }, + }, + { + path: 'toolbar', + component: AppToolbarComponent, + data: { + title: 'Toolbar', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Toolbar' }, + ], + }, + }, + { + path: 'tooltips', + component: AppTooltipsComponent, + data: { + title: 'Tooltips', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Tooltips' }, + ], + }, + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/pages/widgets/banners/banners.component.html b/theme/packages/main/src/app/pages/widgets/banners/banners.component.html new file mode 100644 index 0000000..47a52a3 --- /dev/null +++ b/theme/packages/main/src/app/pages/widgets/banners/banners.component.html @@ -0,0 +1,136 @@ +
+ +
+ + + +
+
+ Welcome back Mathew! + You have earned 54% more than last month which is great + thing. + +
+
+ welcome +
+
+
+
+ + + + +
+
+ Track your every Transaction Easily + Track and record your every income and expence easily to control + your balance + +
+
+ welcome +
+
+
+
+ + +
+
+ + + img + + Oops something went wrong! + Trying again to bypasses these
+ temporary error.
+ +
+
+
+
+ + + img + + Oop, Your cart is empty! + Get back to shopping and get
+ rewards from it.
+ +
+
+
+
+
+ +
+ + + Level Up + img + + You reach all Notifications + Congratulations,
Tap to continue next task.
+ +
+
+ + + +
Mutual Friend Revealed
+ img + + Tommoie Henderson + Accept the request and
type a message
+ + +
+
+
+
diff --git a/theme/packages/main/src/app/pages/widgets/banners/banners.component.ts b/theme/packages/main/src/app/pages/widgets/banners/banners.component.ts new file mode 100644 index 0000000..b334cc7 --- /dev/null +++ b/theme/packages/main/src/app/pages/widgets/banners/banners.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; + +@Component({ + selector: 'app-banners', + imports: [MatCardModule, MatButtonModule], + templateUrl: './banners.component.html' +}) +export class AppBannersComponent { + constructor() {} +} diff --git a/theme/packages/main/src/app/pages/widgets/cards/cards.component.html b/theme/packages/main/src/app/pages/widgets/cards/cards.component.html new file mode 100644 index 0000000..051c1c9 --- /dev/null +++ b/theme/packages/main/src/app/pages/widgets/cards/cards.component.html @@ -0,0 +1,348 @@ + + + + +
+ @for(topcard of topcards; track topcard) { +
+ + + users +

+ {{ topcard.title }} +

+
+ {{ topcard.subtitle }} +
+
+
+
+ } +
+ + + + +
+ @for(cardimg of cardimgs; track cardimg.imgSrc) { +
+ + Photo of a Shiba Inu +
+ {{ + cardimg.time + }} +
+ + +
+
+ +
+ {{ + cardimg.category + }} +
+ {{ cardimg.title }} +
+
+ {{ cardimg.views }} + {{ cardimg.comments }} +
+ + + {{ cardimg.date }} + +
+
+
+
+ } +
+ + + + +
+ @for(productcard of productcards; track productcard.title) { +
+ + + imgSrc + + + + {{ + productcard.title + }} +
+
+
${{ productcard.price }}
+ ${{ productcard.rprice }} +
+
+ + + + + +
+
+
+
+
+ } +
+ + + + +
+ @for(musiccard of musiccards; track musiccard.title) { +
+ +
+
+
{{ musiccard.title }}
+ {{ musiccard.subtext }} + +
+ + + +
+
+
+ blog +
+
+
+
+ } +
+ + + + +
+ @for(followercard of followercards; track followercard.title) { +
+ + +
+
+ user +
+
{{ followercard.title }}
+ {{ followercard.subtext }} +
+
+ +
+
+
+
+ } +
+ + + + +
+ @for(friendcard of friendcards; track friendcard.title) { +
+ + + user + {{ friendcard.title }} +
+
+ user + user + user +
+ 3 mutual friends +
+ + +
+
+
+ } +
+ + + + +
+ @for(socialcard of socialcards; track socialcard.username) { +
+ + + + {{ + socialcard.username + }} + {{ + socialcard.post + }} + +
+ + + + +
+
+
+ } +
+ + + + +
+ @for(giftcard of giftcards; track giftcard.username) { +
+ + +
+ {{ + giftcard.username + }} + +
+ + user + + +
+
+
+ } +
+ +
+ +
+ + + Payment Gateways + Platform For Income + + @for(stat of stats; track stat.title) { +
+
+ + icon + + +
+
{{ stat.title }}
+ {{ stat.subtitle }} +
+ +${{ stat.percent }} +
+
+ } + + +
+
+
+ + +
+ + + Upcoming Activity + In New year + + @for(activity of activities; track activity.title) { +
+
+ + + + +
+
{{ activity.title }}
+ {{ activity.subtitle }} +
+ {{ activity.time }} +
+
+ } +
+
+
+ + +
+ + + Recent Transactions + +
+ @for(stat of stats2; track stat.subtext) { +
+
{{ stat.time }}
+
+ + +
+
+ @if(stat.subtext) { + {{ stat.subtext }} + } + + @if(stat.title) { + {{ + stat.title + }} + } + + @if(stat.link) { + #ML-3467 + } +
+
+ } +
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/main/src/app/pages/widgets/cards/cards.component.ts b/theme/packages/main/src/app/pages/widgets/cards/cards.component.ts new file mode 100644 index 0000000..e282030 --- /dev/null +++ b/theme/packages/main/src/app/pages/widgets/cards/cards.component.ts @@ -0,0 +1,460 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatChipsModule } from '@angular/material/chips'; +import { TablerIconsModule } from 'angular-tabler-icons'; +// card 1 +interface topcards { + id: number; + img: string; + color: string; + title: string; + subtitle: string; +} + +// card 2 +interface cardimgs { + id: number; + time: string; + imgSrc: string; + user: string; + title: string; + views: string; + category: string; + comments: number; + date: string; +} + +// card 3 +interface productcards { + id: number; + imgSrc: string; + title: string; + price: string; + rprice: string; +} + +// card 4 +interface musiccards { + id: number; + imgSrc: string; + title: string; + subtext: string; +} + +// card 5 +interface followercards { + id: number; + imgSrc: string; + title: string; + subtext: string; +} + +// card 6 +interface friendcards { + id: number; + imgSrc: string; + title: string; +} + +// card 7 +interface socialcards { + id: number; + imgSrc: string; + username: string; + post: string; +} + +// card 8 +interface giftcards { + id: number; + imgSrc: string; + username: string; +} + +// card 9 +interface stats { + id: number; + color: string; + title: string; + subtitle: string; + img: string; + percent: string; +} + +// card 10 +interface stats2 { + id: number; + time: string; + color: string; + title?: string; + subtext?: string; + link?: string; +} + +// card 11 +interface activities { + id: number; + color: string; + title: string; + subtitle: string; + icon: string; + time: string; +} + +@Component({ + selector: 'app-cards', + imports: [MatCardModule, MatChipsModule, TablerIconsModule, MatButtonModule], + templateUrl: './cards.component.html', +}) +export class AppCardsComponent { + constructor() {} + // card 1 + topcards: topcards[] = [ + { + id: 1, + color: 'primary', + img: '/assets/images/svgs/icon-user-male.svg', + title: 'Profile', + subtitle: '3,685', + }, + { + id: 2, + color: 'warning', + img: '/assets/images/svgs/icon-briefcase.svg', + title: 'Blog', + subtitle: '256', + }, + { + id: 3, + color: 'secondary', + img: '/assets/images/svgs/icon-mailbox.svg', + title: 'Calendar', + subtitle: '932', + }, + { + id: 4, + color: 'error', + img: '/assets/images/svgs/icon-favorites.svg', + title: 'Email', + subtitle: '$348K', + }, + { + id: 5, + color: 'success', + img: '/assets/images/svgs/icon-speech-bubble.svg', + title: 'Chats', + subtitle: '96', + }, + { + id: 6, + color: 'secondary', + img: '/assets/images/svgs/icon-connect.svg', + title: 'Contacts', + subtitle: '48', + }, + ]; + + // card 2 + cardimgs: cardimgs[] = [ + { + id: 1, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img1.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 2, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img2.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 3, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img3.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + ]; + + // card 3 + productcards: productcards[] = [ + { + id: 1, + imgSrc: '/assets/images/products/s4.jpg', + title: 'Boat Headphone', + price: '285', + rprice: '375', + }, + { + id: 2, + imgSrc: '/assets/images/products/s5.jpg', + title: 'MacBook Air Pro', + price: '285', + rprice: '375', + }, + { + id: 3, + imgSrc: '/assets/images/products/s7.jpg', + title: 'Red Valvet Dress', + price: '285', + rprice: '375', + }, + { + id: 4, + imgSrc: '/assets/images/products/s11.jpg', + title: 'Cute Soft Teddybear', + price: '285', + rprice: '375', + }, + ]; + + // card 4 + musiccards: musiccards[] = [ + { + id: 1, + imgSrc: '/assets/images/blog/blog-img5.jpg', + title: 'Uptown Funk', + subtext: 'Jon Bon Jovi', + }, + { + id: 2, + imgSrc: '/assets/images/blog/blog-img4.jpg', + title: 'Blank Space', + subtext: 'Madonna', + }, + { + id: 3, + imgSrc: '/assets/images/blog/blog-img3.jpg', + title: 'Lean On', + subtext: 'Jennifer Lopez', + }, + ]; + + // card 5 + followercards: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/profile/user-1.jpg', + title: 'Andrew Grant', + subtext: 'El Salvador', + }, + { + id: 2, + imgSrc: '/assets/images/profile/user-2.jpg', + title: 'Leo Pratt', + subtext: 'Bulgaria', + }, + { + id: 3, + imgSrc: '/assets/images/profile/user-3.jpg', + title: 'Charles Nunez', + subtext: 'Nepal', + }, + ]; + + // card 6 + friendcards: friendcards[] = [ + { + id: 1, + imgSrc: '/assets/images/profile/user-1.jpg', + title: 'Andrew Grant', + }, + { + id: 2, + imgSrc: '/assets/images/profile/user-2.jpg', + title: 'Leo Pratt', + }, + { + id: 3, + imgSrc: '/assets/images/profile/user-3.jpg', + title: 'Charles Nunez', + }, + { + id: 4, + imgSrc: '/assets/images/profile/user-4.jpg', + title: 'Lora Powers', + }, + ]; + + // card 7 + socialcards: socialcards[] = [ + { + id: 1, + imgSrc: '/assets/images/profile/user-1.jpg', + username: 'Andrew Grant', + post: 'Technology Director', + }, + { + id: 2, + imgSrc: '/assets/images/profile/user-2.jpg', + username: 'Andrew Grant', + post: 'Technology Director', + }, + { + id: 3, + imgSrc: '/assets/images/profile/user-3.jpg', + username: 'Andrew Grant', + post: 'Technology Director', + }, + ]; + + // card 8 + giftcards: giftcards[] = [ + { + id: 1, + imgSrc: '/assets/images/products/s1.jpg', + username: 'Andrew Grant', + }, + { + id: 2, + imgSrc: '/assets/images/products/s2.jpg', + username: 'Leo Pratt', + }, + { + id: 3, + imgSrc: '/assets/images/products/s3.jpg', + username: 'Charles Nunez', + }, + ]; + + // card 9 + stats: stats[] = [ + { + id: 1, + color: 'primary', + title: 'Paypal', + subtitle: 'Big Brands', + img: 'assets/images/svgs/icon-paypal.svg', + percent: '6235', + }, + { + id: 2, + color: 'success', + title: 'Wallet', + subtitle: 'Bill payment', + img: 'assets/images/svgs/icon-office-bag.svg', + percent: '345', + }, + { + id: 3, + color: 'warning', + title: 'Credit Card', + subtitle: 'Money reversed', + img: 'assets/images/svgs/icon-master-card.svg', + percent: '2235', + }, + { + id: 4, + color: 'error', + title: 'Refund', + subtitle: 'Bill Payment', + img: 'assets/images/svgs/icon-pie.svg', + percent: '32', + }, + ]; + + // card 10 + stats2: stats2[] = [ + { + id: 1, + time: '09.30 am', + color: 'primary', + subtext: 'Payment received from John Doe of $385.90', + }, + { + id: 2, + time: '10.30 am', + color: 'accent', + title: 'New sale recorded', + link: '#ML-3467', + }, + { + id: 3, + time: '12.30 pm', + color: 'success', + subtext: 'Payment was made of $64.95 to Michael', + }, + { + id: 4, + time: '12.30 pm', + color: 'warning', + title: 'New sale recorded', + link: '#ML-3467', + }, + { + id: 5, + time: '12.30 pm', + color: 'error', + title: 'New arrival recorded', + link: '#ML-3467', + }, + ]; + + // card 11 + id: number; + color: string; + title: string; + subtitle: string; + icon: string; + time: string; + + activities: activities[] = [ + { + id: 1, + color: 'primary', + title: 'Trip to singapore', + subtitle: 'working on', + icon: 'map-pin', + time: '5 mins', + }, + { + id: 2, + color: 'secondary', + title: 'Archived Data', + subtitle: 'working on', + icon: 'database', + time: '10 mins', + }, + { + id: 3, + color: 'warning', + title: 'Meeting with client', + subtitle: 'pending', + icon: 'phone', + time: '15 mins', + }, + { + id: 4, + color: 'error', + title: 'Screening Task Team', + subtitle: 'pending', + icon: 'screen-share', + time: '20 mins', + }, + { + id: 5, + color: 'success', + title: 'Send envelope to John', + subtitle: 'done', + icon: 'mail', + time: '20 mins', + }, + ]; +} diff --git a/theme/packages/main/src/app/pages/widgets/charts/charts.component.html b/theme/packages/main/src/app/pages/widgets/charts/charts.component.html new file mode 100644 index 0000000..ca67948 --- /dev/null +++ b/theme/packages/main/src/app/pages/widgets/charts/charts.component.html @@ -0,0 +1,631 @@ + + + +
+ +
+ + + 2,545 +
+ Followers + +1.20% +
+
+ + +
+
+ +
+ + + 15,480 +
+ Views + -4.150% +
+ + +
+
+
+ +
+ + + 2,545 +
+ Earned + +1.20% +
+
+ + +
+
+ +
+ + + Total Earning + $78,298 + + + + + +
+ +
+ + +
+ Current Value +
+ + +
+
+ +
+
+ + + + + + Income + +
+ $25,260 + +1.25% +
+
+
+
+
+ + + + + + Expance + +
+ $12,260 + +4.25% +
+
+
+
+
+ + + + + + Current Year + +
+ $98,260 + + +2.5% +
+
+
+
+
+
+
+
+ + +
+
+
+ + + Yearly Breakup + + +
+
+

$36,358

+
+ +
+9%
+
last year
+
+ +
+
+ +
2025
+
+
+ +
2022
+
+
+
+
+ +
+
+
+
+
+
+ + + Monthly Earnings +
+ +
+
+ +
+

$6,820

+
+ +
+9%
+
+
+ + +
+
+
+
+ + +
+ Most Visited + + + @for(month of months; track month.value) { + + {{ month.viewValue }} + + } + + +
+
+ +
+
+
+ +
+ San Francisco +
+
+
+ +
+ Diego +
+
+
+
+
+
+
+
+ + +
+ + + + Yearly Sales + Every month + + + + +
+
+ +
+ Salary +
$36,358
+
+
+
+ +
+ Expance +
$5,296
+
+
+
+
+
+ + + + Page Impressions +
+
+
$456,120
+ (Change Yesterday) +
+ +
+9%
+
+
+
+ +
+
+
+
+ +
+
+ + + Customers +
36,358
+ +
+ +
+9%
+
+
+ +
+
+
+ + + Projects +
78,298
+ +
+ +
+9%
+
+ +
+
+
+
+
+ +
+ + + Revenue Updates + Overview of Profit + + +
+
+ +
+ Footware +
+
+
+ +
+ Fashionware +
+
+
+ +
+
+ + + Sales Overview + Every month + + + + +
+
+ +
+
$23,450
+ Profit +
+
+
+ +
+
$23,450
+ Expance +
+
+
+
+
+
+
diff --git a/theme/packages/main/src/app/pages/widgets/charts/charts.component.ts b/theme/packages/main/src/app/pages/widgets/charts/charts.component.ts new file mode 100644 index 0000000..94ea09d --- /dev/null +++ b/theme/packages/main/src/app/pages/widgets/charts/charts.component.ts @@ -0,0 +1,1065 @@ +import { Component, ViewChild } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatSelectModule } from '@angular/material/select'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { + ApexAxisChartSeries, + ApexChart, + ChartComponent, + ApexDataLabels, + ApexYAxis, + ApexLegend, + ApexXAxis, + ApexTooltip, + ApexTheme, + ApexGrid, + ApexPlotOptions, + ApexFill, + NgApexchartsModule, +} from 'ng-apexcharts'; + +export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: any; + theme: ApexTheme; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + colors: string[]; + markers: any; + grid: ApexGrid; + plotOptions: ApexPlotOptions; + fill: ApexFill; + labels: string[]; +}; + +interface month { + value: string; + viewValue: string; +} + +@Component({ + selector: 'app-charts', + imports: [ + MatCardModule, + NgApexchartsModule, + TablerIconsModule, + FormsModule, + MatInputModule, + MatSelectModule, + MatFormFieldModule, + ReactiveFormsModule, + MatButtonModule, + ], + templateUrl: './charts.component.html' +}) +export class AppChartsComponent { + @ViewChild('chart') chart: ChartComponent = Object.create(null); + + public followersChart: Partial | any; + public viewsChart: Partial | any; + public earnChart: Partial | any; + public totalearnChart: Partial | any; + public incomeChart: Partial | any; + public expancechart: Partial | any; + public currentyearChart: Partial | any; + public yearlyBreakupChart: Partial | any; + public monthlytwoChart: Partial | any; + public yearlysaleChart: Partial | any; + public projectsChart: Partial | any; + public customerChart: Partial | any; + public revenuetwoChart: Partial | any; + public salesoverviewChart: Partial | any; + public mostvisitChart: Partial | any; + public pageimpChart: Partial | any; + + months: month[] = [ + { value: 'mar', viewValue: 'March 2025' }, + { value: 'apr', viewValue: 'April 2025' }, + { value: 'june', viewValue: 'June 2025' }, + ]; + + constructor() { + // followers chart + this.followersChart = { + series: [ + { + name: '', + data: [0, 150, 110, 240, 200, 200, 300, 200], + }, + ], + chart: { + type: 'area', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 90, + sparkline: { + enabled: true, + }, + }, + colors: ['#5D87FF'], + stroke: { + curve: 'straight', + width: 2, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + show: false, + }, + xaxis: { + axisBorder: { + show: true, + }, + axisTicks: { + show: false, + }, + }, + tooltip: { + theme: 'dark', + }, + }; + + // views chart + this.viewsChart = { + series: [ + { + name: '', + data: [20, 15, 30, 25, 10, 18, 20], + }, + ], + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 70, + sparkline: { + enabled: true, + }, + }, + colors: [ + '#E8F7FF', + '#E8F7FF', + '#49BEFF', + '#E8F7FF', + '#E8F7FF', + '#E8F7FF', + '#E8F7FF', + '#E8F7FF', + ], + plotOptions: { + bar: { + borderRadius: 4, + columnWidth: '50%', + distributed: true, + endingShape: 'rounded', + }, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + show: false, + padding: { + top: 0, + right: 0, + bottom: 0, + left: 0, + }, + }, + xaxis: { + categories: ['M', 'T', 'W', 'T', 'F', 'S', 'S'], + labels: { + show: false, + }, + axisBorder: { + show: false, + }, + axisTicks: { + show: false, + }, + }, + yaxis: { + labels: { + show: false, + }, + }, + tooltip: { + theme: 'dark', + }, + }; + + // earn chart + this.earnChart = { + series: [ + { + name: '', + data: [0, 3, 1, 2, 8, 1, 5, 1], + }, + ], + chart: { + type: 'area', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 90, + sparkline: { + enabled: true, + }, + }, + colors: ['#5D87FF'], + stroke: { + curve: 'straight', + width: 2, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + show: false, + }, + xaxis: { + axisBorder: { + show: true, + }, + axisTicks: { + show: false, + }, + }, + tooltip: { + theme: 'dark', + }, + }; + + // total earnings chart + this.totalearnChart = { + series: [ + { + name: '', + data: [4, 10, 9, 7, 9, 10, 11, 8, 10], + }, + ], + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 65, + resize: true, + barColor: '#fff', + sparkline: { + enabled: true, + }, + }, + colors: ['#49BEFF'], + grid: { + show: false, + }, + plotOptions: { + bar: { + horizontal: false, + startingShape: 'flat', + endingShape: 'flat', + columnWidth: '60%', + barHeight: '20%', + borderRadius: 3, + }, + }, + dataLabels: { + enabled: false, + }, + stroke: { + show: true, + width: 2.5, + colors: ['rgba(0,0,0,0.01)'], + }, + xaxis: { + axisBorder: { + show: false, + }, + axisTicks: { + show: false, + }, + labels: { + show: false, + }, + }, + yaxis: { + labels: { + show: false, + }, + }, + axisBorder: { + show: false, + }, + fill: { + opacity: 1, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + + // income chart + this.incomeChart = { + series: [ + { + name: '', + data: [2.5, 3.7, 3.2, 2.6, 1.9, 2.5], + }, + { + name: '', + data: [-2.8, -1.1, -3.0, -1.5, -1.9, -2.8], + }, + ], + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 200, + stacked: true, + sparkline: { + enabled: true, + }, + }, + colors: ['#5D87FF', '#5D87FF'], + plotOptions: { + bar: { + horizontal: false, + barHeight: '60%', + columnWidth: '20%', + borderRadius: [6], + borderRadiusApplication: 'end', + borderRadiusWhenStacked: 'all', + }, + }, + stroke: { + show: false, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + show: false, + padding: { + top: 0, + right: 0, + bottom: 0, + left: 0, + }, + }, + yaxis: { + min: -5, + max: 5, + tickAmount: 4, + }, + xaxis: { + categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May'], + axisTicks: { + show: false, + }, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + + // expance chart + this.expancechart = { + series: [ + { + name: '', + data: [2.5, 3.7, 3.2, 2.6, 1.9, 2.5], + }, + { + name: '', + data: [-2.8, -1.1, -3.0, -1.5, -1.9, -2.8], + }, + ], + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 200, + stacked: true, + sparkline: { + enabled: true, + }, + }, + colors: ['#49BEFF', '#49BEFF'], + plotOptions: { + bar: { + horizontal: false, + barHeight: '60%', + columnWidth: '20%', + borderRadius: [6], + borderRadiusApplication: 'end', + borderRadiusWhenStacked: 'all', + }, + }, + stroke: { + show: false, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + show: false, + padding: { + top: 0, + right: 0, + bottom: 0, + left: 0, + }, + }, + yaxis: { + min: -5, + max: 5, + tickAmount: 4, + }, + xaxis: { + categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May'], + axisTicks: { + show: false, + }, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + + // current year chart + this.currentyearChart = { + series: [55, 55, 55], + chart: { + type: 'donut', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + + toolbar: { + show: false, + }, + height: 220, + }, + labels: ['Income', 'Current', 'Expance'], + colors: ['#5D87FF', '#ECF2FF', '#49BEFF'], + plotOptions: { + pie: { + startAngle: 0, + endAngle: 360, + donut: { + size: '89%', + background: 'transparent', + + labels: { + show: true, + name: { + show: true, + offsetY: 7, + }, + value: { + show: false, + }, + total: { + show: true, + color: '#2A3547', + fontSize: '20px', + fontWeight: '600', + label: '$98,260', + }, + }, + }, + }, + }, + dataLabels: { + enabled: false, + }, + stroke: { + show: false, + }, + legend: { + show: false, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + + // yearly breakup + this.yearlyBreakupChart = { + series: [38, 40, 25], + + chart: { + type: 'donut', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 130, + }, + colors: ['#5D87FF', '#ECF2FF', '#F9F9FD'], + plotOptions: { + pie: { + startAngle: 0, + endAngle: 360, + donut: { + size: '75%', + background: 'transparent', + }, + }, + }, + stroke: { + show: false, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + responsive: [ + { + breakpoint: 991, + options: { + chart: { + width: 120, + }, + }, + }, + ], + tooltip: { + enabled: false, + }, + }; + + // monthly chart + this.monthlytwoChart = { + series: [ + { + name: '', + color: '#5D87FF', + data: [25, 66, 20, 40, 12, 58, 20], + }, + ], + + chart: { + type: 'area', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 60, + sparkline: { + enabled: true, + }, + group: 'sparklines', + }, + stroke: { + curve: 'smooth', + width: 2, + }, + fill: { + colors: ['#E8F7FF'], + type: 'solid', + }, + markers: { + size: 0, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + + // yearlysale chart + this.yearlysaleChart = { + series: [ + { + name: '', + data: [20, 15, 30, 25, 10, 15], + }, + ], + + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 290, + }, + colors: [ + '#ECF2FF', + '#ECF2FF', + '#5D87FF', + '#ECF2FF', + '#ECF2FF', + '#ECF2FF', + ], + plotOptions: { + bar: { + borderRadius: 4, + columnWidth: '45%', + distributed: true, + endingShape: 'rounded', + }, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + yaxis: { + lines: { + show: false, + }, + }, + }, + xaxis: { + categories: [['Apr'], ['May'], ['June'], ['July'], ['Aug'], ['Sept']], + axisBorder: { + show: false, + }, + }, + yaxis: { + labels: { + show: false, + }, + }, + tooltip: { + theme: 'dark', + }, + }; + + // projcts chart + this.projectsChart = { + series: [ + { + name: '', + data: [4, 10, 9, 7, 9, 10, 11, 8, 10], + }, + ], + + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 80, + resize: true, + barColor: '#fff', + sparkline: { + enabled: true, + }, + }, + colors: ['#5D87FF'], + grid: { + show: false, + }, + plotOptions: { + bar: { + horizontal: false, + startingShape: 'flat', + endingShape: 'flat', + columnWidth: '60%', + barHeight: '20%', + borderRadius: 3, + }, + }, + stroke: { + show: true, + width: 2.5, + colors: ['rgba(0,0,0,0.01)'], + }, + xaxis: { + axisBorder: { + show: false, + }, + axisTicks: { + show: false, + }, + labels: { + show: false, + }, + }, + yaxis: { + labels: { + show: false, + }, + }, + axisBorder: { + show: false, + }, + fill: { + opacity: 1, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + + // customers chart + this.customerChart = { + series: [ + { + name: '', + color: '#49BEFF', + data: [30, 25, 35, 20, 30, 40], + }, + ], + + chart: { + type: 'area', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 80, + sparkline: { + enabled: true, + }, + group: 'sparklines', + }, + stroke: { + curve: 'smooth', + width: 2, + }, + fill: { + colors: ['#E8F7FF'], + type: 'solid', + opacity: 0.05, + }, + markers: { + size: 0, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + + // revenue charts + this.revenuetwoChart = { + series: [ + { + name: 'Footware', + data: [2.5, 3.7, 3.2, 2.6, 1.9], + color: '#5D87FF', + }, + { + name: 'Fashionware', + data: [-2.8, -1.1, -3.0, -1.5, -1.9], + color: '#49BEFF', + }, + ], + + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 320, + offsetX: -20, + stacked: true, + }, + + plotOptions: { + bar: { + horizontal: false, + columnWidth: '20%', + borderRadius: [6], + borderRadiusApplication: 'end', + borderRadiusWhenStacked: 'all', + }, + }, + + stroke: { + show: false, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + show: false, + }, + yaxis: { + min: -5, + max: 5, + tickAmount: 4, + }, + xaxis: { + categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May'], + }, + tooltip: { + theme: 'dark', + fillSeriesColor: false, + }, + }; + + // sales overview chart + this.salesoverviewChart = { + series: [55, 55, 55], + + chart: { + type: 'donut', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + + toolbar: { + show: false, + }, + height: 275, + }, + labels: ['Profit', 'Revenue', 'Expance'], + colors: ['#5D87FF', '#ECF2FF', '#49BEFF'], + plotOptions: { + pie: { + donut: { + size: '89%', + background: 'transparent', + + labels: { + show: true, + name: { + show: true, + offsetY: 7, + }, + value: { + show: false, + }, + total: { + show: true, + color: '#2A3547', + fontSize: '20px', + fontWeight: '600', + label: '$500,458', + }, + }, + }, + }, + }, + dataLabels: { + enabled: false, + }, + stroke: { + show: false, + }, + legend: { + show: false, + }, + tooltip: { + theme: 'dark', + fillSeriesColor: false, + }, + }; + + // most visit chart + this.mostvisitChart = { + series: [ + { + name: 'San Francisco', + data: [44, 55, 41, 67, 22, 43], + }, + { + name: 'Diego', + data: [13, 23, 20, 8, 13, 27], + }, + ], + + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 280, + stacked: true, + }, + colors: ['#5D87FF', '#49BEFF'], + plotOptions: { + bar: { + borderRadius: [6], + horizontal: false, + barHeight: '60%', + columnWidth: '30%', + borderRadiusApplication: 'end', + borderRadiusWhenStacked: 'all', + }, + }, + stroke: { + show: false, + }, + dataLabels: { + enabled: false, + }, + legend: { + show: false, + }, + grid: { + show: false, + }, + yaxis: { + tickAmount: 4, + }, + xaxis: { + categories: ['01', '02', '03', '04', '05', '06'], + axisTicks: { + show: false, + }, + }, + tooltip: { + theme: 'dark', + fillSeriesColor: false, + }, + }; + + // page impressions + this.pageimpChart = { + series: [ + { + name: '', + data: [20, 15, 30, 25, 10], + }, + ], + chart: { + type: 'bar', + fontFamily: "'Plus Jakarta Sans', sans-serif;", + foreColor: '#adb0bb', + toolbar: { + show: false, + }, + height: 100, + resize: true, + barColor: '#fff', + sparkline: { + enabled: true, + }, + }, + colors: [ + '#E8F7FF', + '#E8F7FF', + '#49BEFF', + '#E8F7FF', + '#E8F7FF', + '#E8F7FF', + ], + grid: { + show: false, + }, + plotOptions: { + bar: { + borderRadius: 4, + columnWidth: '50%', + distributed: true, + endingShape: 'rounded', + }, + }, + dataLabels: { + enabled: false, + }, + stroke: { + show: true, + width: 2.5, + colors: ['rgba(0,0,0,0.01)'], + }, + xaxis: { + axisBorder: { + show: false, + }, + axisTicks: { + show: false, + }, + labels: { + show: false, + }, + }, + yaxis: { + labels: { + show: false, + }, + }, + axisBorder: { + show: false, + }, + fill: { + opacity: 1, + }, + tooltip: { + theme: 'dark', + x: { + show: false, + }, + }, + }; + } +} diff --git a/theme/packages/main/src/app/pages/widgets/widgets.routes.ts b/theme/packages/main/src/app/pages/widgets/widgets.routes.ts new file mode 100644 index 0000000..bf32778 --- /dev/null +++ b/theme/packages/main/src/app/pages/widgets/widgets.routes.ts @@ -0,0 +1,47 @@ +import { Routes } from '@angular/router'; + +// widgets +import { AppBannersComponent } from './banners/banners.component'; +import { AppCardsComponent } from './cards/cards.component'; +import { AppChartsComponent } from './charts/charts.component'; + +export const WidgetsRoutes: Routes = [ + { + path: '', + children: [ + { + path: 'banners', + component: AppBannersComponent, + data: { + title: 'Banners', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Banners' }, + ], + }, + }, + { + path: 'cards', + component: AppCardsComponent, + data: { + title: 'Cards', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Cards' }, + ], + }, + }, + { + path: 'charts', + component: AppChartsComponent, + data: { + title: 'Charts', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Charts' }, + ], + }, + }, + ], + }, +]; diff --git a/theme/packages/main/src/app/pipe/filter.pipe.ts b/theme/packages/main/src/app/pipe/filter.pipe.ts new file mode 100644 index 0000000..be41f6e --- /dev/null +++ b/theme/packages/main/src/app/pipe/filter.pipe.ts @@ -0,0 +1,21 @@ + + +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ name: 'appFilter' }) +export class FilterPipe implements PipeTransform { + + transform(items: any[], searchText: string): any[] { + if (!items) { + return []; + } + if (!searchText) { + return items; + } + searchText = searchText.toLocaleLowerCase(); + + return items.filter((it) => { + return it.displayName.toLocaleLowerCase().includes(searchText); + }); + } +} diff --git a/theme/packages/main/src/app/services/apps/blog/blog.service.ts b/theme/packages/main/src/app/services/apps/blog/blog.service.ts new file mode 100644 index 0000000..63221f7 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/blog/blog.service.ts @@ -0,0 +1,25 @@ +import { Injectable, signal } from '@angular/core'; +import { blogPosts } from 'src/app/pages/apps/blogs/blogData'; + +@Injectable({ + providedIn: 'root', +}) +export class blogService { + private blogPosts = signal(blogPosts); + private selectedPost = signal(null); + + constructor() {} + + public getBlog() { + return this.blogPosts(); + } + + public selectBlogPost(title: string) { + const post = this.blogPosts().find((post) => post.title === title); + this.selectedPost.set(post || null); + } + + public getSelectedPost() { + return this.selectedPost(); + } +} diff --git a/theme/packages/main/src/app/services/apps/chat/chat.service.ts b/theme/packages/main/src/app/services/apps/chat/chat.service.ts new file mode 100644 index 0000000..2924d0e --- /dev/null +++ b/theme/packages/main/src/app/services/apps/chat/chat.service.ts @@ -0,0 +1,40 @@ +import { Injectable, signal } from '@angular/core'; +import { messages } from 'src/app/pages/apps/chat/chatData'; +import { Message } from 'src/app/pages/apps/chat/chat'; + +@Injectable({ + providedIn: 'root', +}) +export class ChatService { + private messagesSignal = signal(messages); + private selectedMessageSignal = signal(messages[0]); + + constructor() {} + + get messages() { + return this.messagesSignal; + } + + get selectedMessage() { + return this.selectedMessageSignal; + } + + sendMessage(selectedMessage: Message, msg: string) { + if (msg.trim()) { + const newMessage = { type: 'even', msg, date: new Date() }; + selectedMessage.chat.push(newMessage); + this.messagesSignal.update((currentMessages) => + currentMessages.map((message) => + message === selectedMessage + ? { ...message, chat: [...selectedMessage.chat] } + : message + ) + ); + this.selectedMessageSignal.set({ ...selectedMessage }); + } + } + + selectMessage(message: Message): void { + this.selectedMessageSignal.set(message); + } +} diff --git a/theme/packages/main/src/app/services/apps/contact-list/contact-list.service.ts b/theme/packages/main/src/app/services/apps/contact-list/contact-list.service.ts new file mode 100644 index 0000000..eac9a10 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/contact-list/contact-list.service.ts @@ -0,0 +1,86 @@ +import { Injectable, signal } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { ContactList } from 'src/app/pages/apps/contact-list/contactlistData'; +import { + Category, + filter, + label, +} from 'src/app/pages/apps/contact-list/listing/categories'; +import { ContactBox } from 'src/app/pages/apps/contact-list/contact-list'; + +@Injectable({ + providedIn: 'root', +}) +export class ContactService { + contactList = signal(ContactList); + labels = signal(label); + filters = signal(filter); + + selectedFilter = signal(null); + selectedCategory = signal(null); + + private selectedContactSubject = new BehaviorSubject(ContactList[0]); + selectedContact$ = this.selectedContactSubject.asObservable(); + + constructor() {} + + setSelectedContact(contact: any) { + this.selectedContactSubject.next(contact); + } + + getSelectedContact() { + return this.selectedContactSubject.getValue(); + } + + setContacts(contacts: any[]) { + this.contactList.set(contacts); + } + updateContact(updatedContact: any) { + const updatedList = this.contactList().map((contact) => + contact.id === updatedContact.id ? updatedContact : contact + ); + this.contactList.set(updatedList); + if (this.selectedContactSubject.getValue()?.id === updatedContact.id) { + this.setSelectedContact(updatedContact); + } + } + + applyFilter(filter: Category): void { + this.selectedFilter.set(filter); + this.filters.set( + this.filters().map((f) => ({ ...f, active: f === filter })) + ); + this.selectedCategory.set(null); + } + + applyCategory(category: Category): void { + this.selectedCategory.set(category); + this.labels().forEach((lab) => (lab.active = lab === category)); + this.selectedFilter.set(null); + } + + toggleStarred(contact: ContactBox, $event: any): void { + contact.starred = !contact.starred; + $event.stopPropagation(); + this.contactList.set([...this.contactList()]); + } + + deleteContact(contactToDelete: ContactBox) { + const updatedList = this.contactList().filter( + (contact) => contact.id !== contactToDelete.id + ); + this.contactList.set(updatedList); + + // Check if the deleted contact was the selected one + const currentlySelectedContact = this.selectedContactSubject.getValue(); + if (currentlySelectedContact?.id === contactToDelete.id) { + // Set the next contact as selected, or null if there are no more contacts + const nextContact = updatedList.length > 0 ? updatedList[0] : null; + this.setSelectedContact(nextContact); + } + } + + getContactList() { + return this.contactList(); + } +} diff --git a/theme/packages/main/src/app/services/apps/contact/contact.service.ts b/theme/packages/main/src/app/services/apps/contact/contact.service.ts new file mode 100644 index 0000000..75871fd --- /dev/null +++ b/theme/packages/main/src/app/services/apps/contact/contact.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { signal } from '@angular/core'; +import { Contact } from 'src/app/pages/apps/contact/contact'; +import { contactList } from 'src/app/pages/apps/contact/contactData'; + +@Injectable({ + providedIn: 'root', +}) +export class ContactService { + private contacts = signal(contactList); + + public getContacts() { + return this.contacts(); + } + + public addContact(contact: Contact) { + this.contacts.set([contact, ...this.contacts()]); + } + + public filterContacts(searchText: string): Contact[] { + return this.contacts().filter((contact) => + contact.contactname.toLowerCase().includes(searchText.toLowerCase()) + ); + } +} diff --git a/theme/packages/main/src/app/services/apps/course/course.service.ts b/theme/packages/main/src/app/services/apps/course/course.service.ts new file mode 100644 index 0000000..a963522 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/course/course.service.ts @@ -0,0 +1,14 @@ +import { Injectable, signal } from '@angular/core'; +import { course } from 'src/app/pages/apps/courses/course'; +import { courseList } from 'src/app/pages/apps/courses/courseData'; + +@Injectable({ + providedIn: 'root', +}) +export class CourseService { + public course = signal(courseList); + + public getCourse(): course[] { + return this.course(); + } +} diff --git a/theme/packages/main/src/app/services/apps/email/email.service.ts b/theme/packages/main/src/app/services/apps/email/email.service.ts new file mode 100644 index 0000000..fe70053 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/email/email.service.ts @@ -0,0 +1,76 @@ +import { Injectable, signal, computed } from '@angular/core'; +import { Mailbox } from 'src/app/pages/apps/email/email'; +import { mailboxList } from 'src/app/pages/apps/email/email-data'; +import { User } from 'src/app/pages/apps/email/user-data'; + +@Injectable({ + providedIn: 'root', +}) +export class mailGlobalVariable { + public page = signal(1); + public pageSize = signal(5); + public collectionSize = signal(0); + + public topLabel = signal(''); + public mailList = signal([]); + public selectedMail = signal(null); + public selectedUser = signal(null); + + public users = signal([]); + public inboxList = signal([]); + public sentList = signal([]); + public draftList = signal([]); + public spamList = signal([]); + public trashList = signal([]); + + public isShow = signal(false); + public addClass = signal(true); + public type = signal(''); + router: any; + + public inboxCount = computed( + () => + this.inboxList().filter( + (inbox: { mailbox: string; seen: any }) => + inbox.mailbox === 'Inbox' && !inbox.seen + ).length + ); + public spamCount = computed(() => this.spamList().length); + public draftCount = computed(() => this.draftList().length); + public replyShow = signal(false); + + public toggleStar(name: string): void { + const mail = this.selectedMail(); + + if (mail) { + if (!mail.filter.includes(name)) { + mail.filter.push(name); + } else { + mail.filter = mail.filter.filter((fil) => fil !== name); + } + } + } +} + +@Injectable({ + providedIn: 'root', +}) +export class mailService { + public getInbox(): Mailbox[] { + return mailboxList.filter((mail) => + ['Inbox', 'Sent', 'Draft', 'Spam'].includes(mail.mailbox) + ); + } + public getSent(): Mailbox[] { + return mailboxList.filter((mail) => mail.mailbox === 'Sent'); + } + public getDraft(): Mailbox[] { + return mailboxList.filter((mail) => mail.mailbox === 'Draft'); + } + public getSpam(): Mailbox[] { + return mailboxList.filter((mail) => mail.mailbox === 'Spam'); + } + public getTrash(): Mailbox[] { + return mailboxList.filter((mail) => mail.mailbox === 'Trash'); + } +} diff --git a/theme/packages/main/src/app/services/apps/employee/employee.service.ts b/theme/packages/main/src/app/services/apps/employee/employee.service.ts new file mode 100644 index 0000000..a952c85 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/employee/employee.service.ts @@ -0,0 +1,35 @@ +import { Injectable, signal } from '@angular/core'; +import { Employee } from 'src/app/pages/apps/employee/employee'; +import { employees } from 'src/app/pages/apps/employee/employeeData'; + +@Injectable({ + providedIn: 'root', +}) +export class EmployeeService { + private employees = signal(employees); + + getEmployees() { + return this.employees(); + } + + addEmployee(employee: Employee): void { + employee.id = this.employees().length + 1; + this.employees.update((employees) => [...employees, employee]); + } + + updateEmployee(updatedEmployee: Employee): void { + this.employees.update((employees) => { + const index = employees.findIndex((e) => e.id === updatedEmployee.id); + if (index !== -1) { + employees[index] = updatedEmployee; + } + return [...employees]; + }); + } + + deleteEmployee(employeeId: number): void { + this.employees.update((employees) => + employees.filter((e) => e.id !== employeeId) + ); + } +} diff --git a/theme/packages/main/src/app/services/apps/front-pages/front-end.service.spec.ts b/theme/packages/main/src/app/services/apps/front-pages/front-end.service.spec.ts new file mode 100644 index 0000000..950ecc8 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/front-pages/front-end.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { FrontEndService } from './front-end.service'; + +describe('FrontEndService', () => { + let service: FrontEndService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(FrontEndService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/services/apps/front-pages/front-end.service.ts b/theme/packages/main/src/app/services/apps/front-pages/front-end.service.ts new file mode 100644 index 0000000..a736e66 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/front-pages/front-end.service.ts @@ -0,0 +1,21 @@ +import { Injectable, signal } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class FrontEndService { + + private blog = signal(null); + + constructor() { } + + + + setBlog(blogData: any) { + this.blog.set(blogData); + } + + getBlog() { + return this.blog; + } +} diff --git a/theme/packages/main/src/app/services/apps/invoice/invoice.service.ts b/theme/packages/main/src/app/services/apps/invoice/invoice.service.ts new file mode 100644 index 0000000..a293c61 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/invoice/invoice.service.ts @@ -0,0 +1,37 @@ +import { Injectable, signal } from '@angular/core'; +import { InvoiceList } from 'src/app/pages/apps/invoice/invoice'; +import { invoceLists } from 'src/app/pages/apps/invoice/invoiceData'; + +@Injectable({ + providedIn: 'root', +}) +export class InvoiceService { + private invoiceList = signal(invoceLists); + constructor() {} + + public getInvoiceList(): InvoiceList[] { + return this.invoiceList(); + } + + deleteInvoice(id: number): void { + this.invoiceList.update((invoices) => + invoices.filter((invoice) => invoice.id !== id) + ); + } + + public addInvoice(invoice: InvoiceList): void { + this.invoiceList.update((invoices) => [...invoices, invoice]); + } + + public updateInvoice(id: number, invoice: InvoiceList): void { + this.invoiceList.update((invoices) => { + const index = invoices.findIndex((x) => x.id === id); + if (index !== -1) { + const updatedInvoices = [...invoices]; + updatedInvoices[index] = invoice; // Update the invoice at the found index + return updatedInvoices; + } + return invoices; // Return the original list if not found + }); + } +} diff --git a/theme/packages/main/src/app/services/apps/kanban/kanban.service.ts b/theme/packages/main/src/app/services/apps/kanban/kanban.service.ts new file mode 100644 index 0000000..706967d --- /dev/null +++ b/theme/packages/main/src/app/services/apps/kanban/kanban.service.ts @@ -0,0 +1,84 @@ +import { Injectable, signal } from '@angular/core'; +import { Todos } from 'src/app/pages/apps/kanban/kanban'; +import { + todos, + inprogress, + completed, + onhold, +} from 'src/app/pages/apps/kanban/kanbanData'; + +@Injectable({ + providedIn: 'root', +}) +export class KanbanService { + todos = signal(todos); + inProgress = signal(inprogress); + completed = signal(completed); + onHold = signal(onhold); + + constructor() {} + + getAllTasks(): { + todos: Todos[]; + inProgress: Todos[]; + completed: Todos[]; + onHold: Todos[]; + } { + return { + todos: this.todos(), + inProgress: this.inProgress(), + completed: this.completed(), + onHold: this.onHold(), + }; + } + + addTask(task: Todos): void { + const currentTodos = this.todos(); + const newTask = { + ...task, + id: currentTodos.length + ? currentTodos[currentTodos.length - 1].id + 1 + : 1, // Generate a new ID + }; + this.todos.set([...currentTodos, newTask]); + } + + editTask(updatedTask: Todos): void { + const currentTodos = this.todos(); + const updatedTodos = currentTodos.map((task: { id: number }) => + task.id === updatedTask.id ? updatedTask : task + ); + this.todos.set(updatedTodos); + + this.updateTaskInList(this.inProgress(), updatedTask); + this.updateTaskInList(this.completed(), updatedTask); + this.updateTaskInList(this.onHold(), updatedTask); + } + + private updateTaskInList(taskList: Todos[], updatedTask: Todos): void { + const updatedList = taskList.map((task) => + task.id === updatedTask.id ? updatedTask : task + ); + if (taskList === this.inProgress()) { + this.inProgress.set(updatedList); + } else if (taskList === this.completed()) { + this.completed.set(updatedList); + } else if (taskList === this.onHold()) { + this.onHold.set(updatedList); + } + } + deleteTask(taskId: number): void { + this.todos.set( + this.todos().filter((task: { id: number }) => task.id !== taskId) + ); + this.inProgress.set( + this.inProgress().filter((task: { id: number }) => task.id !== taskId) + ); + this.completed.set( + this.completed().filter((task: { id: number }) => task.id !== taskId) + ); + this.onHold.set( + this.onHold().filter((task: { id: number }) => task.id !== taskId) + ); + } +} diff --git a/theme/packages/main/src/app/services/apps/notes/note.service.ts b/theme/packages/main/src/app/services/apps/notes/note.service.ts new file mode 100644 index 0000000..fc130d0 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/notes/note.service.ts @@ -0,0 +1,31 @@ +import { Injectable, signal } from '@angular/core'; +import { Note } from 'src/app/pages/apps/notes/note'; +import { notes } from 'src/app/pages/apps/notes/notesData'; + +@Injectable({ + providedIn: 'root', +}) +export class NoteService { + private notes = signal(notes); + + public getNotes(): Note[] { + return this.notes(); + } + + public addNote(note: Note) { + this.notes.update((currentNotes) => [note, ...currentNotes]); + } + + public removeNote(note: Note) { + this.notes.update((currentNotes) => currentNotes.filter((n) => n !== note)); + } + + public updateNote(updatedNote: Note): void { + this.notes.update( + (currentNotes) => + currentNotes.map((n) => + n.title === updatedNote.title ? updatedNote : n + ) + ); + } +} diff --git a/theme/packages/main/src/app/services/apps/product/product.service.spec.ts b/theme/packages/main/src/app/services/apps/product/product.service.spec.ts new file mode 100644 index 0000000..d5c493e --- /dev/null +++ b/theme/packages/main/src/app/services/apps/product/product.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { ProductService } from './product.service'; + +describe('ProductService', () => { + let service: ProductService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ProductService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/theme/packages/main/src/app/services/apps/product/product.service.ts b/theme/packages/main/src/app/services/apps/product/product.service.ts new file mode 100644 index 0000000..a705ef9 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/product/product.service.ts @@ -0,0 +1,48 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Subject } from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +export class ProductService { + + constructor() { } + private product: any = null; + + private readonly productKey = 'selectedProduct'; // Key for localStorage + + + + private productAdded = new BehaviorSubject(null); +productAdded$ = this.productAdded.asObservable(); + +editProduct = new BehaviorSubject(null); + editMode = new BehaviorSubject(false); + productUpdated = new Subject(); + + setProduct(product: any) { + this.product = product; + localStorage.setItem(this.productKey, JSON.stringify(product)); // Save to localStorage + } + + getProduct() { + const productFromLocalStorage = localStorage.getItem(this.productKey); + return productFromLocalStorage ? JSON.parse(productFromLocalStorage) : null; // Return from localStorage or null + } + + clearProduct() { + this.product = null; + localStorage.removeItem(this.productKey); // Remove from localStorage + } + emitProduct(data: any) { + this.productAdded.next(data); + } + + clearEmittedProduct() { + this.productAdded.next(null); + } + updateProduct(data: any) { + console.log('Updated product data in service', data); + this.productUpdated.next(data); + } +} diff --git a/theme/packages/main/src/app/services/apps/ticket/ticket.service.ts b/theme/packages/main/src/app/services/apps/ticket/ticket.service.ts new file mode 100644 index 0000000..0f2b3a0 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/ticket/ticket.service.ts @@ -0,0 +1,69 @@ +import { Injectable, signal } from '@angular/core'; +import { TicketElement } from 'src/app/pages/apps/tickets/ticket'; +import { tickets } from 'src/app/pages/apps/tickets/ticketsData'; + +@Injectable({ + providedIn: 'root', +}) +export class TicketService { + // track ticket data + private ticketsData = signal(tickets); + + get tickets$() { + return this.ticketsData(); + } + + public users = [ + { id: 1, name: 'Alice', photo: '/assets/images/profile/user-1.jpg' }, + { id: 2, name: 'Jonathan', photo: '/assets/images/profile/user-2.jpg' }, + { id: 3, name: 'Smith', photo: '/assets/images/profile/user-3.jpg' }, + { id: 4, name: 'Vincent', photo: '/assets/images/profile/user-4.jpg' }, + { id: 5, name: 'Chris', photo: '/assets/images/profile/user-5.jpg' }, + ]; + + getUsers(): any[] { + return this.users; + } + + constructor() {} + + addTicket(ticket: TicketElement): void { + const today = new Date(); + + // Get the current list of tickets + const currentTickets = this.ticketsData(); + + // Find the highest ID currently in use + const maxId = + currentTickets.length > 0 + ? Math.max(...currentTickets.map((t) => t.id)) + : 0; // Default to 0 if no tickets exist + + const newTicket: TicketElement = { + id: maxId + 1, // Set new ID + title: ticket.title, + subtext: ticket.subtext, + assignee: ticket.assignee, + imgSrc: '/assets/images/profile/user-1.jpg', + status: 'open', + date: today.toISOString().split('T')[0], + }; + + // Update the tickets data with the new ticket + this.ticketsData.update((currentTickets) => [...currentTickets, newTicket]); + } + + updateTicket(updatedTicket: TicketElement): void { + this.ticketsData.update((currentTickets) => + currentTickets.map((ticket) => + ticket.id === updatedTicket.id ? updatedTicket : ticket + ) + ); + } + + deleteTicket(id: number): void { + this.ticketsData.update((currentTickets) => + currentTickets.filter((ticket) => ticket.id !== id) + ); + } +} diff --git a/theme/packages/main/src/app/services/apps/todo/todo.service.ts b/theme/packages/main/src/app/services/apps/todo/todo.service.ts new file mode 100644 index 0000000..f6484e7 --- /dev/null +++ b/theme/packages/main/src/app/services/apps/todo/todo.service.ts @@ -0,0 +1,51 @@ +import { Injectable, signal } from '@angular/core'; +import { ToDo } from 'src/app/pages/apps/todo/todo'; +import { todos } from 'src/app/pages/apps/todo/todoData'; + +@Injectable({ + providedIn: 'root', +}) +export class TodoService { + private todos = signal(todos); + + public getTodos(): ToDo[] { + return this.todos(); + } + + public addTodo(message: string): void { + if (message.trim().length === 0) { + return; + } + + // Get the current list of todos to find the maximum ID + const currentTodos = this.todos(); // Get current todos from the signal + const maxId = + currentTodos.length > 0 + ? Math.max(...currentTodos.map((todo) => todo.id)) + : 0; + + const newTodo: ToDo = { + id: maxId + 1, // Set new ID as max ID + 1 + message, + completionStatus: false, + edit: false, + date: new Date(), + }; + + this.todos.update((todos) => [newTodo, ...todos]); + } + + public deleteTodo(id: number): void { + this.todos.update((todos) => todos.filter((todo) => todo.id !== id)); + } + + public editTodo(id: number, message: string): void { + this.todos.update((todos) => + todos.map((todo) => + todo.id === id ? { ...todo, message, edit: false } : todo + ) + ); + } + + +} diff --git a/theme/packages/main/src/app/services/core.service.ts b/theme/packages/main/src/app/services/core.service.ts new file mode 100644 index 0000000..a0566fb --- /dev/null +++ b/theme/packages/main/src/app/services/core.service.ts @@ -0,0 +1,28 @@ +import { Injectable, signal } from '@angular/core'; +import { AppSettings, defaults } from '../config'; + +@Injectable({ + providedIn: 'root', +}) +export class CoreService { + private optionsSignal = signal(defaults); + + getOptions() { + return this.optionsSignal(); + } + + setOptions(options: Partial) { + this.optionsSignal.update((current) => ({ + ...current, + ...options, + })); + } + + setLanguage(lang: string) { + this.setOptions({ language: lang }); + } + + getLanguage() { + return this.getOptions().language; + } +} diff --git a/theme/packages/main/src/app/services/nav.service.ts b/theme/packages/main/src/app/services/nav.service.ts new file mode 100644 index 0000000..e6b4f01 --- /dev/null +++ b/theme/packages/main/src/app/services/nav.service.ts @@ -0,0 +1,17 @@ +import { Injectable, signal } from '@angular/core'; +import { Event, NavigationEnd, Router } from '@angular/router'; + +@Injectable({ providedIn: 'root' }) +export class NavService { + showClass: any = false; + + public currentUrl = signal(undefined); + + constructor(private router: Router) { + this.router.events.subscribe((event: Event) => { + if (event instanceof NavigationEnd) { + this.currentUrl.set(event.urlAfterRedirects); + } + }); + } +} \ No newline at end of file diff --git a/theme/packages/main/src/app/utils/normalize-replies.util.ts b/theme/packages/main/src/app/utils/normalize-replies.util.ts new file mode 100644 index 0000000..89c895a --- /dev/null +++ b/theme/packages/main/src/app/utils/normalize-replies.util.ts @@ -0,0 +1,24 @@ +import { Post } from "../pages/apps/profile-content/profileData"; + + +export function normalizeReplies(posts: Post[]): Post[] { + return posts.map((post) => ({ + ...post, + data: { + ...post.data, + comments: post.data.comments.map((comment) => ({ + ...comment, + data: { + ...comment.data, + replies: (comment.data.replies ?? []).map((reply) => ({ + ...reply, + data: { + ...reply.data, + replies: reply.data.replies ?? [], + }, + })), + }, + })), + }, + })); + } \ No newline at end of file diff --git a/theme/packages/main/src/assets/.gitkeep b/theme/packages/main/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/main/src/assets/i18n/de.json b/theme/packages/main/src/assets/i18n/de.json new file mode 100644 index 0000000..ca1f960 --- /dev/null +++ b/theme/packages/main/src/assets/i18n/de.json @@ -0,0 +1,101 @@ +{ + "Analytical": "Analytisch", + "eCommerce": "E-Commerce", + "Chat": "Plaudern", + "Calendar": "Kalender", + "Email": "Email", + "Contacts": "Kontakte", + "Courses": "Kurse", + "Employee": "Mitarbeiterin", + "Notes": "Anmerkungen", + "Tickets": "Eintrittskarten", + "Invoice": "Rechnung", + "Blog": "Bloggen", + "Posts": "Beiträge", + "Detail": "Detail", + "ToDo": "Machen", + "Taskboard": "Taskboard", + "Roll Base Access": "Zugriff auf die Rollbasis", + "Treeview": "Baumsicht", + "Pricing": "Preisgestaltung", + "Account Setting": "Konto-Einstellung", + "FAQ": "FAQ", + "Landingpage": "Zielseite", + "Widgets": "Widgets", + "Cards": "Karten", + "Banners": "Banner", + "Charts": "Diagramme", + "Form elements": "Formularelemente", + "Autocomplete": "Automatische Vervollständigung", + "Button": "Taste", + "Checkbox": "Kontrollkästchen", + "Radio": "Radio", + "Datepicker": "Datumsauswahl", + "Form Layouts": "Formularlayouts", + "Form Horizontal": "Horizontal bilden", + "Form Vertical": "Form vertikal", + "Form Wizard": "Formzauberer", + "Tables": "Tische", + "Basic Table": "Grundlegende Tabelle", + "Dynamic Table": "Dynamische Tabelle", + "Expand Table": "Tabelle erweitern", + "Filterable Table": "Filterbare Tabelle", + "Footer Row Table": "Fußzeilentabelle", + "HTTP Table": "HTTP-Tabelle", + "Mix Table": "Mischtabelle", + "Multi Header Footer": "Fußzeile mit mehreren Kopfzeilen", + "Pagination Table": "Paginierungstabelle", + "Row Context Table": "Zeilenkontexttabelle", + "Selection Table": "Auswahltabelle", + "Sortable Table": "Sortierbare Tabelle", + "Sticky Column": "Klebrige Spalte", + "Sticky Header Footer": "Klebrige Kopfzeile Fußzeile", + "Datatables": "Datentabellen", + "Basic DataTable": "Grundlegende Datentabelle", + "Material Table": "Materialtabelle", + "Table Editing": "Tabellenbearbeitung", + "Filter Table": "Filtertabelle", + "Line": "Linie", + "Gredient": "Zutat", + "Area": "Bereich", + "Candlestick": "Leuchter", + "Column": "Spalte", + "Doughnut & Pie": "Donut und Kuchen", + "Radialbar & Radar": "Radialbar & Radar", + "Ui Components": "Ui-Komponenten", + "Badge": "Abzeichen", + "Expansion Panel": "Erweiterungspanel", + "Chips": "Chips", + "Dialog": "Dialog", + "Lists": "Listen", + "Divider": "Teiler", + "Menu": "Speisekarte", + "Paginator": "Paginator", + "Progress Bar": "Fortschrittsanzeige", + "Progress Spinner": "Fortschrittsspinner", + "Ripples": "Wellen", + "Slide Toggle": "Schieben Sie um", + "Slider": "Schieberegler", + "Snackbar": "Imbissbude", + "Tabs": "Registerkarten", + "Toolbar": "Symbolleiste", + "Tooltips": "Kurzinfos", + "Login": "Anmeldung", + "Side Login": "Seitlicher Login", + "Boxed Login": "Box-Login", + "Register": "Registrieren", + "Side Register": "Seitenregister", + "Boxed Register": "Verpacktes Register", + "Forgot Password": "Passwort vergessen", + "Side Forgot Password": "Seite Passwort vergessen", + "Boxed Forgot Password": "Box Passwort vergessen", + "Two Steps": "Zwei schritte", + "Side Two Steps": "Seite zwei Schritte", + "Boxed Two Steps": "Verpackt zwei Schritte", + "Error": "Fehler", + "Maintenance": "Wartung", + "Menu Level": "Menüebene", + "Menu 1": "Menü 1", + "Menu 2": "Menü 2", + "Disabled": "Behinderte" +} diff --git a/theme/packages/main/src/assets/i18n/en.json b/theme/packages/main/src/assets/i18n/en.json new file mode 100644 index 0000000..ba45934 --- /dev/null +++ b/theme/packages/main/src/assets/i18n/en.json @@ -0,0 +1,101 @@ +{ + "Analytical": "Analytical", + "eCommerce": "eCommerce", + "Chat": "Chat", + "Calendar": "Calendar", + "Email": "Email", + "Contacts": "Contacts", + "Courses": "Courses", + "Employee": "Employee", + "Notes": "Notes", + "Tickets": "Tickets", + "Invoice": "Invoice", + "Blog": "Blog", + "Posts": "Posts", + "Detail": "Detail", + "ToDo": "ToDo", + "Taskboard": "Taskboard", + "Roll Base Access": "Roll Base Access", + "Treeview": "Treeview", + "Pricing": "Pricing", + "Account Setting": "Account Setting", + "FAQ": "FAQ", + "Landingpage": "Landingpage", + "Widgets": "Widgets", + "Cards": "Cards", + "Banners": "Banners", + "Charts": "Charts", + "Form elements": "Form elements", + "Autocomplete": "Autocomplete", + "Button": "Button", + "Checkbox": "Checkbox", + "Radio": "Radio", + "Datepicker": "Datepicker", + "Form Layouts": "Form Layouts", + "Form Horizontal": "Form Horizontal", + "Form Vertical": "Form Vertical", + "Form Wizard": "Form Wizard", + "Tables": "Tables", + "Basic Table": "Basic Table", + "Dynamic Table": "Dynamic Table", + "Expand Table": "Expand Table", + "Filterable Table": "Filterable Table", + "Footer Row Table": "Footer Row Table", + "HTTP Table": "HTTP Table", + "Mix Table": "Mix Table", + "Multi Header Footer": "Multi Header Footer", + "Pagination Table": "Pagination Table", + "Row Context Table": "Row Context Table", + "Selection Table": "Selection Table", + "Sortable Table": "Sortable Table", + "Sticky Column": "Sticky Column", + "Sticky Header Footer": "Sticky Header Footer", + "Datatables": "Datatables", + "Basic DataTable": "Basic DataTable", + "Material Table": "Material Table", + "Table Editing": "Table Editing", + "Filter Table": "Filter Table", + "Line": "Line", + "Gredient": "Gredient", + "Area": "Area", + "Candlestick": "Candlestick", + "Column": "Column", + "Doughnut & Pie": "Doughnut & Pie", + "Radialbar & Radar": "Radialbar & Radar", + "Ui Components": "Ui Components", + "Badge": "Badge", + "Expansion Panel": "Expansion Panel", + "Chips": "Chips", + "Dialog": "Dialog", + "Lists": "Lists", + "Divider": "Divider", + "Menu": "Menu", + "Paginator": "Paginator", + "Progress Bar": "Progress Bar", + "Progress Spinner": "Progress Spinner", + "Ripples": "Ripples", + "Slide Toggle": "Slide Toggle", + "Slider": "Slider", + "Snackbar": "Snackbar", + "Tabs": "Tabs", + "Toolbar": "Toolbar", + "Tooltips": "Tooltips", + "Login": "Login", + "Side Login": "Side Login", + "Boxed Login": "Boxed Login", + "Register": "Register", + "Side Register": "Side Register", + "Boxed Register": "Boxed Register", + "Forgot Password": "Forgot Password", + "Side Forgot Password": "Side Forgot Password", + "Boxed Forgot Password": "Boxed Forgot Password", + "Two Steps": "Two Steps", + "Side Two Steps": "Side Two Steps", + "Boxed Two Steps": "Boxed Two Steps", + "Error": "Error", + "Maintenance": "Maintenance", + "Menu Level": "Menu Level", + "Menu 1": "Menu 1", + "Menu 2": "Menu 2", + "Disabled": "Disabled" +} diff --git a/theme/packages/main/src/assets/i18n/es.json b/theme/packages/main/src/assets/i18n/es.json new file mode 100644 index 0000000..5542dbb --- /dev/null +++ b/theme/packages/main/src/assets/i18n/es.json @@ -0,0 +1,101 @@ +{ + "Analytical": "Analítica", + "eCommerce": "comércio eletrônico", + "Chat": "Bater papo", + "Calendar": "Calendário", + "Email": "E-mail", + "Contacts": "Contatos", + "Courses": "Cursos", + "Employee": "Funcionária", + "Notes": "Notas", + "Tickets": "Ingressos", + "Invoice": "Fatura", + "Blog": "blog", + "Posts": "Postagens", + "Detail": "Detalhe", + "ToDo": "Pendência", + "Taskboard": "Painel de tarefas", + "Roll Base Access": "Acesso à base de rolo", + "Treeview": "Treeview", + "Pricing": "Preços", + "Account Setting": "Configurações de conta", + "FAQ": "Perguntas frequentes", + "Landingpage": "página de destino", + "Widgets": "Widgets", + "Cards": "cartões", + "Banners": "Banners", + "Charts": "Gráficas", + "Form elements": "Elementos de formulário", + "Autocomplete": "autocompletar", + "Button": "Botão", + "Checkbox": "Caixa de seleção", + "Radio": "Rádio", + "Datepicker": "Selecionador de data", + "Form Layouts": "Layouts de formulário", + "Form Horizontal": "Forma Horizontal", + "Form Vertical": "Formulário Vertical", + "Form Wizard": "Assistente de formulário", + "Tables": "Tabelas", + "Basic Table": "Tabela Básica", + "Dynamic Table": "Tabela Dinâmica", + "Expand Table": "Expandir tabela", + "Filterable Table": "Tabela filtrável", + "Footer Row Table": "Tabela de linha de rodapé", + "HTTP Table": "Tabela HTTP", + "Mix Table": "Tabela de mistura", + "Multi Header Footer": "Multi Cabeçalho Rodapé", + "Pagination Table": "Tabela de Paginação", + "Row Context Table": "Tabela de Contexto de Linha", + "Selection Table": "Tabela de seleção", + "Sortable Table": "Tabela Ordenável", + "Sticky Column": "coluna fixa", + "Sticky Header Footer": "Cabeçalho Fixo Rodapé", + "Datatables": "Tabelas de dados", + "Basic DataTable": "Tabela de Dados Básica", + "Material Table": "Tabela de Materiais", + "Table Editing": "Edição de tabela", + "Filter Table": "Tabela de filtro", + "Line": "Linha", + "Gredient": "Grediente", + "Area": "Área", + "Candlestick": "Castiçal", + "Column": "Coluna", + "Doughnut & Pie": "rosquinha e torta", + "Radialbar & Radar": "Barra radial e radar", + "Ui Components": "Componentes da interface do usuário", + "Badge": "Distintivo", + "Expansion Panel": "Painel de Expansão", + "Chips": "Salgadinhos", + "Dialog": "Diálogo", + "Lists": "Listas", + "Divider": "Divisor", + "Menu": "Cardápio", + "Paginator": "paginador", + "Progress Bar": "Barra de progresso", + "Progress Spinner": "Girador de Progresso", + "Ripples": "ondulações", + "Slide Toggle": "Alternar slide", + "Slider": "Controle deslizante", + "Snackbar": "Lanchonete", + "Tabs": "Guias", + "Toolbar": "barra de ferramentas", + "Tooltips": "dicas", + "Login": "Conecte-se", + "Side Login": "Login lateral", + "Boxed Login": "Login em caixa", + "Register": "Registro", + "Side Register": "Registro Lateral", + "Boxed Register": "caixa registradora", + "Forgot Password": "Esqueceu sua senha", + "Side Forgot Password": "Lado Esqueceu a Senha", + "Boxed Forgot Password": "Senha esquecida em caixa", + "Two Steps": "Dois passos", + "Side Two Steps": "Lado Dois Passos", + "Boxed Two Steps": "Dois Passos Encaixotados", + "Error": "Erro", + "Maintenance": "Manutenção", + "Menu Level": "Nível do menu", + "Menu 1": "Menu 1", + "Menu 2": "Menu 2", + "Disabled": "Desabilitada" +} diff --git a/theme/packages/main/src/assets/i18n/fr.json b/theme/packages/main/src/assets/i18n/fr.json new file mode 100644 index 0000000..5c3122a --- /dev/null +++ b/theme/packages/main/src/assets/i18n/fr.json @@ -0,0 +1,101 @@ +{ + "Analytical": "Analytique", + "eCommerce": "commerce électronique", + "Chat": "Discuter", + "Calendar": "Calendar", + "Email": "E-mail", + "Contacts": "Contacts", + "Courses": "Cours", + "Employee": "Employée", + "Notes": "Remarques", + "Tickets": "Des billets", + "Invoice": "Facture", + "Blog": "Blog", + "Posts": "Des postes", + "Detail": "Détail", + "ToDo": "Faire", + "Taskboard": "Tableau des tâches", + "Roll Base Access": "Accès à la base roulante", + "Treeview": "Arborescence", + "Pricing": "Tarification", + "Account Setting": "Paramètre du compte", + "FAQ": "FAQ", + "Landingpage": "Page de destination", + "Widgets": "Widget", + "Cards": "Cartes", + "Banners": "Bannières", + "Charts": "Graphiques", + "Form elements": "Éléments de formulaire", + "Autocomplete": "Saisie automatique", + "Button": "Bouton", + "Checkbox": "Case à cocher", + "Radio": "Radio", + "Datepicker": "Sélecteur de date", + "Form Layouts": "Dispositions de formulaire", + "Form Horizontal": "Forme horizontale", + "Form Vertical": "Forme verticale", + "Form Wizard": "Assistant Formulaire", + "Tables": "les tables", + "Basic Table": "Tableau de base", + "Dynamic Table": "Tableau dynamique", + "Expand Table": "Développer le tableau", + "Filterable Table": "Tableau filtrable", + "Footer Row Table": "Tableau des lignes de pied de page", + "HTTP Table": "Tableau HTTP", + "Mix Table": "Tableau de mélange", + "Multi Header Footer": "Pied de page multi-en-tête", + "Pagination Table": "Tableau de pagination", + "Row Context Table": "Tableau de contexte de ligne", + "Selection Table": "Tableau de sélection", + "Sortable Table": "Tableau triable", + "Sticky Column": "Colonne collante", + "Sticky Header Footer": "En-tête collant", + "Datatables": "Tableaux de données", + "Basic DataTable": "Tableau de données de base", + "Material Table": "Tableau des matériaux", + "Table Editing": "Édition de tableau", + "Filter Table": "Tableau de filtrage", + "Line": "Doubler", + "Gredient": "Grédient", + "Area": "Zone", + "Candlestick": "Chandelier", + "Column": "Colonne", + "Doughnut & Pie": "Donut et tarte", + "Radialbar & Radar": "Barre radiale et radar", + "Ui Components": "Composants de l'interface utilisateur", + "Badge": "Badge", + "Expansion Panel": "Panneau d'extension", + "Chips": "Puces", + "Dialog": "Dialogue", + "Lists": "Listes", + "Divider": "Diviseur", + "Menu": "Menu", + "Paginator": "Paginateur", + "Progress Bar": "Barre de progression", + "Progress Spinner": "Spinner de progression", + "Ripples": "Ondulations", + "Slide Toggle": "Bascule de diapositive", + "Slider": "Glissière", + "Snackbar": "Snack-bar", + "Tabs": "Onglets", + "Toolbar": "Barre d'outils", + "Tooltips": "Info-bulles", + "Login": "Connexion", + "Side Login": "Connexion latérale", + "Boxed Login": "Connexion en boîte", + "Register": "Enregistrer", + "Side Register": "Registre latéral", + "Boxed Register": "Registre en boîte", + "Forgot Password": "Mot de passe oublié", + "Side Forgot Password": "Mot de passe oublié", + "Boxed Forgot Password": "Mot de passe oublié", + "Two Steps": "Deux étapes", + "Side Two Steps": "Côté deux étapes", + "Boxed Two Steps": "Deux étapes en boîte", + "Error": "Erreur", + "Maintenance": "Entretien", + "Menu Level": "Niveau menu", + "Menu 1": "Menu 1", + "Menu 2": "Menu 2", + "Disabled": "Désactivé" +} diff --git a/theme/packages/main/src/assets/images/backgrounds/404-error-idea.gif b/theme/packages/main/src/assets/images/backgrounds/404-error-idea.gif new file mode 100644 index 0000000..6f5bf86 Binary files /dev/null and b/theme/packages/main/src/assets/images/backgrounds/404-error-idea.gif differ diff --git a/theme/packages/main/src/assets/images/backgrounds/bronze.png b/theme/packages/main/src/assets/images/backgrounds/bronze.png new file mode 100644 index 0000000..d0e5bfa Binary files /dev/null and b/theme/packages/main/src/assets/images/backgrounds/bronze.png differ diff --git a/theme/packages/main/src/assets/images/backgrounds/errorimg.svg b/theme/packages/main/src/assets/images/backgrounds/errorimg.svg new file mode 100644 index 0000000..1f523c4 --- /dev/null +++ b/theme/packages/main/src/assets/images/backgrounds/errorimg.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/backgrounds/gold.png b/theme/packages/main/src/assets/images/backgrounds/gold.png new file mode 100644 index 0000000..bdc7ede Binary files /dev/null and b/theme/packages/main/src/assets/images/backgrounds/gold.png differ diff --git a/theme/packages/main/src/assets/images/backgrounds/login-bg.svg b/theme/packages/main/src/assets/images/backgrounds/login-bg.svg new file mode 100644 index 0000000..b5b43a4 --- /dev/null +++ b/theme/packages/main/src/assets/images/backgrounds/login-bg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/backgrounds/maintenance.svg b/theme/packages/main/src/assets/images/backgrounds/maintenance.svg new file mode 100644 index 0000000..71eccf6 --- /dev/null +++ b/theme/packages/main/src/assets/images/backgrounds/maintenance.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/backgrounds/maintenance2.svg b/theme/packages/main/src/assets/images/backgrounds/maintenance2.svg new file mode 100644 index 0000000..260f07f --- /dev/null +++ b/theme/packages/main/src/assets/images/backgrounds/maintenance2.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/backgrounds/piggy.png b/theme/packages/main/src/assets/images/backgrounds/piggy.png new file mode 100644 index 0000000..c8dcbfd Binary files /dev/null and b/theme/packages/main/src/assets/images/backgrounds/piggy.png differ diff --git a/theme/packages/main/src/assets/images/backgrounds/profilebg.jpg b/theme/packages/main/src/assets/images/backgrounds/profilebg.jpg new file mode 100644 index 0000000..1b318aa Binary files /dev/null and b/theme/packages/main/src/assets/images/backgrounds/profilebg.jpg differ diff --git a/theme/packages/main/src/assets/images/backgrounds/silver.png b/theme/packages/main/src/assets/images/backgrounds/silver.png new file mode 100644 index 0000000..818e736 Binary files /dev/null and b/theme/packages/main/src/assets/images/backgrounds/silver.png differ diff --git a/theme/packages/main/src/assets/images/backgrounds/track-bg.png b/theme/packages/main/src/assets/images/backgrounds/track-bg.png new file mode 100644 index 0000000..429ffee Binary files /dev/null and b/theme/packages/main/src/assets/images/backgrounds/track-bg.png differ diff --git a/theme/packages/main/src/assets/images/backgrounds/unlimited-bg.png b/theme/packages/main/src/assets/images/backgrounds/unlimited-bg.png new file mode 100644 index 0000000..501f5bb Binary files /dev/null and b/theme/packages/main/src/assets/images/backgrounds/unlimited-bg.png differ diff --git a/theme/packages/main/src/assets/images/backgrounds/website-under-construction.gif b/theme/packages/main/src/assets/images/backgrounds/website-under-construction.gif new file mode 100644 index 0000000..5ff9a25 Binary files /dev/null and b/theme/packages/main/src/assets/images/backgrounds/website-under-construction.gif differ diff --git a/theme/packages/main/src/assets/images/backgrounds/welcome-bg2.png b/theme/packages/main/src/assets/images/backgrounds/welcome-bg2.png new file mode 100644 index 0000000..9b9ea3c Binary files /dev/null and b/theme/packages/main/src/assets/images/backgrounds/welcome-bg2.png differ diff --git a/theme/packages/main/src/assets/images/blog/blog-img1.jpg b/theme/packages/main/src/assets/images/blog/blog-img1.jpg new file mode 100644 index 0000000..393391d Binary files /dev/null and b/theme/packages/main/src/assets/images/blog/blog-img1.jpg differ diff --git a/theme/packages/main/src/assets/images/blog/blog-img10.jpg b/theme/packages/main/src/assets/images/blog/blog-img10.jpg new file mode 100644 index 0000000..f7df3d1 Binary files /dev/null and b/theme/packages/main/src/assets/images/blog/blog-img10.jpg differ diff --git a/theme/packages/main/src/assets/images/blog/blog-img11.jpg b/theme/packages/main/src/assets/images/blog/blog-img11.jpg new file mode 100644 index 0000000..4cc927e Binary files /dev/null and b/theme/packages/main/src/assets/images/blog/blog-img11.jpg differ diff --git a/theme/packages/main/src/assets/images/blog/blog-img2.jpg b/theme/packages/main/src/assets/images/blog/blog-img2.jpg new file mode 100644 index 0000000..61ba89b Binary files /dev/null and b/theme/packages/main/src/assets/images/blog/blog-img2.jpg differ diff --git a/theme/packages/main/src/assets/images/blog/blog-img3.jpg b/theme/packages/main/src/assets/images/blog/blog-img3.jpg new file mode 100644 index 0000000..3713c89 Binary files /dev/null and b/theme/packages/main/src/assets/images/blog/blog-img3.jpg differ diff --git a/theme/packages/main/src/assets/images/blog/blog-img4.jpg b/theme/packages/main/src/assets/images/blog/blog-img4.jpg new file mode 100644 index 0000000..ac2c76f Binary files /dev/null and b/theme/packages/main/src/assets/images/blog/blog-img4.jpg differ diff --git a/theme/packages/main/src/assets/images/blog/blog-img5.jpg b/theme/packages/main/src/assets/images/blog/blog-img5.jpg new file mode 100644 index 0000000..f4b421d Binary files /dev/null and b/theme/packages/main/src/assets/images/blog/blog-img5.jpg differ diff --git a/theme/packages/main/src/assets/images/blog/blog-img6.jpg b/theme/packages/main/src/assets/images/blog/blog-img6.jpg new file mode 100644 index 0000000..c34a46e Binary files /dev/null and b/theme/packages/main/src/assets/images/blog/blog-img6.jpg differ diff --git a/theme/packages/main/src/assets/images/blog/blog-img8.jpg b/theme/packages/main/src/assets/images/blog/blog-img8.jpg new file mode 100644 index 0000000..b37c64d Binary files /dev/null and b/theme/packages/main/src/assets/images/blog/blog-img8.jpg differ diff --git a/theme/packages/main/src/assets/images/blog/blog-img9.jpg b/theme/packages/main/src/assets/images/blog/blog-img9.jpg new file mode 100644 index 0000000..e59a50d Binary files /dev/null and b/theme/packages/main/src/assets/images/blog/blog-img9.jpg differ diff --git a/theme/packages/main/src/assets/images/breadcrumb/ChatBc.png b/theme/packages/main/src/assets/images/breadcrumb/ChatBc.png new file mode 100644 index 0000000..ef22544 Binary files /dev/null and b/theme/packages/main/src/assets/images/breadcrumb/ChatBc.png differ diff --git a/theme/packages/main/src/assets/images/breadcrumb/emailSv.png b/theme/packages/main/src/assets/images/breadcrumb/emailSv.png new file mode 100644 index 0000000..3c01e85 Binary files /dev/null and b/theme/packages/main/src/assets/images/breadcrumb/emailSv.png differ diff --git a/theme/packages/main/src/assets/images/chat/icon-adobe.svg b/theme/packages/main/src/assets/images/chat/icon-adobe.svg new file mode 100644 index 0000000..138a8e4 --- /dev/null +++ b/theme/packages/main/src/assets/images/chat/icon-adobe.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/chat/icon-chrome.svg b/theme/packages/main/src/assets/images/chat/icon-chrome.svg new file mode 100644 index 0000000..2d430e2 --- /dev/null +++ b/theme/packages/main/src/assets/images/chat/icon-chrome.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/chat/icon-figma.svg b/theme/packages/main/src/assets/images/chat/icon-figma.svg new file mode 100644 index 0000000..acfb5bc --- /dev/null +++ b/theme/packages/main/src/assets/images/chat/icon-figma.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/theme/packages/main/src/assets/images/chat/icon-javascript.svg b/theme/packages/main/src/assets/images/chat/icon-javascript.svg new file mode 100644 index 0000000..d8d1812 --- /dev/null +++ b/theme/packages/main/src/assets/images/chat/icon-javascript.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/chat/icon-zip-folder.svg b/theme/packages/main/src/assets/images/chat/icon-zip-folder.svg new file mode 100644 index 0000000..32ea4af --- /dev/null +++ b/theme/packages/main/src/assets/images/chat/icon-zip-folder.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/flag/icon-flag-de.svg b/theme/packages/main/src/assets/images/flag/icon-flag-de.svg new file mode 100644 index 0000000..efec2cb --- /dev/null +++ b/theme/packages/main/src/assets/images/flag/icon-flag-de.svg @@ -0,0 +1,10 @@ + + + ic_flag_cn + + + + + + + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/flag/icon-flag-en.svg b/theme/packages/main/src/assets/images/flag/icon-flag-en.svg new file mode 100644 index 0000000..485ad5c --- /dev/null +++ b/theme/packages/main/src/assets/images/flag/icon-flag-en.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/flag/icon-flag-es.svg b/theme/packages/main/src/assets/images/flag/icon-flag-es.svg new file mode 100644 index 0000000..8b517ff --- /dev/null +++ b/theme/packages/main/src/assets/images/flag/icon-flag-es.svg @@ -0,0 +1,10 @@ + + + ic_flag_sa + + + + + + + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/flag/icon-flag-fr.svg b/theme/packages/main/src/assets/images/flag/icon-flag-fr.svg new file mode 100644 index 0000000..2ae63a1 --- /dev/null +++ b/theme/packages/main/src/assets/images/flag/icon-flag-fr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/front-pages/app-chat.jpg b/theme/packages/main/src/assets/images/front-pages/app-chat.jpg new file mode 100644 index 0000000..cffde47 Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/app-chat.jpg differ diff --git a/theme/packages/main/src/assets/images/front-pages/app-email.jpg b/theme/packages/main/src/assets/images/front-pages/app-email.jpg new file mode 100644 index 0000000..5da2d90 Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/app-email.jpg differ diff --git a/theme/packages/main/src/assets/images/front-pages/banner-top-left.svg b/theme/packages/main/src/assets/images/front-pages/banner-top-left.svg new file mode 100644 index 0000000..0b5d123 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/banner-top-left.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/banner-top-right.svg b/theme/packages/main/src/assets/images/front-pages/banner-top-right.svg new file mode 100644 index 0000000..ce2deff --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/banner-top-right.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/bottom-part.svg b/theme/packages/main/src/assets/images/front-pages/bottom-part.svg new file mode 100644 index 0000000..0a9f8f9 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/bottom-part.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/demo-dark.jpg b/theme/packages/main/src/assets/images/front-pages/demo-dark.jpg new file mode 100644 index 0000000..1181c96 Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/demo-dark.jpg differ diff --git a/theme/packages/main/src/assets/images/front-pages/demo-horizontal.jpg b/theme/packages/main/src/assets/images/front-pages/demo-horizontal.jpg new file mode 100644 index 0000000..a384d56 Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/demo-horizontal.jpg differ diff --git a/theme/packages/main/src/assets/images/front-pages/demo-main.jpg b/theme/packages/main/src/assets/images/front-pages/demo-main.jpg new file mode 100644 index 0000000..895551e Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/demo-main.jpg differ diff --git a/theme/packages/main/src/assets/images/front-pages/demo-rtl.jpg b/theme/packages/main/src/assets/images/front-pages/demo-rtl.jpg new file mode 100644 index 0000000..a8011a3 Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/demo-rtl.jpg differ diff --git a/theme/packages/main/src/assets/images/front-pages/design-collection.png b/theme/packages/main/src/assets/images/front-pages/design-collection.png new file mode 100644 index 0000000..08a4a50 Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/design-collection.png differ diff --git a/theme/packages/main/src/assets/images/front-pages/icon-american-express.svg b/theme/packages/main/src/assets/images/front-pages/icon-american-express.svg new file mode 100644 index 0000000..0cc1e3c --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-american-express.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-chart.svg b/theme/packages/main/src/assets/images/front-pages/icon-chart.svg new file mode 100644 index 0000000..fa45961 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-chart.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-circle-check.svg b/theme/packages/main/src/assets/images/front-pages/icon-circle-check.svg new file mode 100644 index 0000000..458ffdb --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-circle-check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-circle-x.svg b/theme/packages/main/src/assets/images/front-pages/icon-circle-x.svg new file mode 100644 index 0000000..41b5593 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-circle-x.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-color.svg b/theme/packages/main/src/assets/images/front-pages/icon-color.svg new file mode 100644 index 0000000..14d5f1a --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-color.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-components.svg b/theme/packages/main/src/assets/images/front-pages/icon-components.svg new file mode 100644 index 0000000..a14b4e4 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-components.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-customize.svg b/theme/packages/main/src/assets/images/front-pages/icon-customize.svg new file mode 100644 index 0000000..300ee35 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-customize.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-diners.svg b/theme/packages/main/src/assets/images/front-pages/icon-diners.svg new file mode 100644 index 0000000..4ea5609 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-diners.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-discover.svg b/theme/packages/main/src/assets/images/front-pages/icon-discover.svg new file mode 100644 index 0000000..12eebd5 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-discover.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-facebook.svg b/theme/packages/main/src/assets/images/front-pages/icon-facebook.svg new file mode 100644 index 0000000..d0cfd8a --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-facebook.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-favorites.svg b/theme/packages/main/src/assets/images/front-pages/icon-favorites.svg new file mode 100644 index 0000000..84fedaa --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-favorites.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/front-pages/icon-framework.svg b/theme/packages/main/src/assets/images/front-pages/icon-framework.svg new file mode 100644 index 0000000..2718d0c --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-framework.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-icons.svg b/theme/packages/main/src/assets/images/front-pages/icon-icons.svg new file mode 100644 index 0000000..87d1ae4 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-icons.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-instagram.svg b/theme/packages/main/src/assets/images/front-pages/icon-instagram.svg new file mode 100644 index 0000000..6a73bf9 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-instagram.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-jcb.svg b/theme/packages/main/src/assets/images/front-pages/icon-jcb.svg new file mode 100644 index 0000000..b71e935 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-jcb.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-masetro.svg b/theme/packages/main/src/assets/images/front-pages/icon-masetro.svg new file mode 100644 index 0000000..5a84358 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-masetro.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-mastercard.svg b/theme/packages/main/src/assets/images/front-pages/icon-mastercard.svg new file mode 100644 index 0000000..da591ae --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-mastercard.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-pages.svg b/theme/packages/main/src/assets/images/front-pages/icon-pages.svg new file mode 100644 index 0000000..ac7ca4b --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-pages.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-paypal.svg b/theme/packages/main/src/assets/images/front-pages/icon-paypal.svg new file mode 100644 index 0000000..7f8de85 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-paypal.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-responsive.svg b/theme/packages/main/src/assets/images/front-pages/icon-responsive.svg new file mode 100644 index 0000000..fc57366 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-responsive.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-sass.svg b/theme/packages/main/src/assets/images/front-pages/icon-sass.svg new file mode 100644 index 0000000..5751e1a --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-sass.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-sidebar.svg b/theme/packages/main/src/assets/images/front-pages/icon-sidebar.svg new file mode 100644 index 0000000..1a0ca63 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-sidebar.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-speech-bubble.svg b/theme/packages/main/src/assets/images/front-pages/icon-speech-bubble.svg new file mode 100644 index 0000000..2e1f2bd --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-speech-bubble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/front-pages/icon-support.svg b/theme/packages/main/src/assets/images/front-pages/icon-support.svg new file mode 100644 index 0000000..6aa77a3 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-support.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-table.svg b/theme/packages/main/src/assets/images/front-pages/icon-table.svg new file mode 100644 index 0000000..3fd98d7 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-table.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-twitter.svg b/theme/packages/main/src/assets/images/front-pages/icon-twitter.svg new file mode 100644 index 0000000..e0b7780 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-twitter.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-update.svg b/theme/packages/main/src/assets/images/front-pages/icon-update.svg new file mode 100644 index 0000000..94b5ed9 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-update.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/icon-visa.svg b/theme/packages/main/src/assets/images/front-pages/icon-visa.svg new file mode 100644 index 0000000..7a06b63 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/icon-visa.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/front-pages/logoIcon.svg b/theme/packages/main/src/assets/images/front-pages/logoIcon.svg new file mode 100644 index 0000000..90fdce0 --- /dev/null +++ b/theme/packages/main/src/assets/images/front-pages/logoIcon.svg @@ -0,0 +1,11 @@ + + logoIcon + + + + + + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/front-pages/topbar-bg.png b/theme/packages/main/src/assets/images/front-pages/topbar-bg.png new file mode 100644 index 0000000..e11b4a5 Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/topbar-bg.png differ diff --git a/theme/packages/main/src/assets/images/front-pages/user1.jpg b/theme/packages/main/src/assets/images/front-pages/user1.jpg new file mode 100644 index 0000000..eb505b5 Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/user1.jpg differ diff --git a/theme/packages/main/src/assets/images/front-pages/user2.jpg b/theme/packages/main/src/assets/images/front-pages/user2.jpg new file mode 100644 index 0000000..f8aa6af Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/user2.jpg differ diff --git a/theme/packages/main/src/assets/images/front-pages/user3.jpg b/theme/packages/main/src/assets/images/front-pages/user3.jpg new file mode 100644 index 0000000..6478013 Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/user3.jpg differ diff --git a/theme/packages/main/src/assets/images/front-pages/user4.jpg b/theme/packages/main/src/assets/images/front-pages/user4.jpg new file mode 100644 index 0000000..e599b2a Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/user4.jpg differ diff --git a/theme/packages/main/src/assets/images/front-pages/user5.jpg b/theme/packages/main/src/assets/images/front-pages/user5.jpg new file mode 100644 index 0000000..494e402 Binary files /dev/null and b/theme/packages/main/src/assets/images/front-pages/user5.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-blog-detail.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-blog-detail.jpg new file mode 100644 index 0000000..33e0ad0 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-blog-detail.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-blog.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-blog.jpg new file mode 100644 index 0000000..39e8703 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-blog.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-calendar.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-calendar.jpg new file mode 100644 index 0000000..37ab178 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-calendar.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-chat.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-chat.jpg new file mode 100644 index 0000000..0503a71 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-chat.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-contact-list.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-contact-list.jpg new file mode 100644 index 0000000..f5dbf49 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-contact-list.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-contact.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-contact.jpg new file mode 100644 index 0000000..2b94cee Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-contact.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-email.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-email.jpg new file mode 100644 index 0000000..821e7f2 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-email.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-employee.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-employee.jpg new file mode 100644 index 0000000..8576430 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-employee.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-invoice.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-invoice.jpg new file mode 100644 index 0000000..74a908c Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-invoice.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-note.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-note.jpg new file mode 100644 index 0000000..f83acd4 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-note.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-taskboard.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-taskboard.jpg new file mode 100644 index 0000000..51135bf Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-taskboard.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-ticket.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-ticket.jpg new file mode 100644 index 0000000..7e746b7 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-ticket.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/apps/app-todo.jpg b/theme/packages/main/src/assets/images/landingpage/apps/app-todo.jpg new file mode 100644 index 0000000..e912e7f Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/apps/app-todo.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/background/accordian1.jpg b/theme/packages/main/src/assets/images/landingpage/background/accordian1.jpg new file mode 100644 index 0000000..d13def2 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/background/accordian1.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/background/c2a.png b/theme/packages/main/src/assets/images/landingpage/background/c2a.png new file mode 100644 index 0000000..6a3bb3b Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/background/c2a.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/background/design-collection.png b/theme/packages/main/src/assets/images/landingpage/background/design-collection.png new file mode 100644 index 0000000..2886a14 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/background/design-collection.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/background/feature-apps.png b/theme/packages/main/src/assets/images/landingpage/background/feature-apps.png new file mode 100644 index 0000000..fef18c5 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/background/feature-apps.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/background/screen1.png b/theme/packages/main/src/assets/images/landingpage/background/screen1.png new file mode 100644 index 0000000..afd642a Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/background/screen1.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/background/slider-group.png b/theme/packages/main/src/assets/images/landingpage/background/slider-group.png new file mode 100644 index 0000000..34c4096 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/background/slider-group.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/bannerimg1.svg b/theme/packages/main/src/assets/images/landingpage/bannerimg1.svg new file mode 100644 index 0000000..5ba13b7 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/bannerimg1.svg @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/landingpage/bannerimg2.svg b/theme/packages/main/src/assets/images/landingpage/bannerimg2.svg new file mode 100644 index 0000000..01ced56 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/bannerimg2.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/landingpage/demos/demo-dark.jpg b/theme/packages/main/src/assets/images/landingpage/demos/demo-dark.jpg new file mode 100644 index 0000000..b303b9b Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/demos/demo-dark.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/demos/demo-firebase.jpg b/theme/packages/main/src/assets/images/landingpage/demos/demo-firebase.jpg new file mode 100644 index 0000000..d983be7 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/demos/demo-firebase.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/demos/demo-horizontal.jpg b/theme/packages/main/src/assets/images/landingpage/demos/demo-horizontal.jpg new file mode 100644 index 0000000..0feb962 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/demos/demo-horizontal.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/demos/demo-main.jpg b/theme/packages/main/src/assets/images/landingpage/demos/demo-main.jpg new file mode 100644 index 0000000..eda0bcd Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/demos/demo-main.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/demos/demo-minisidebar.jpg b/theme/packages/main/src/assets/images/landingpage/demos/demo-minisidebar.jpg new file mode 100644 index 0000000..1d3ffdb Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/demos/demo-minisidebar.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/demos/demo-rtl.jpg b/theme/packages/main/src/assets/images/landingpage/demos/demo-rtl.jpg new file mode 100644 index 0000000..80672ae Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/demos/demo-rtl.jpg differ diff --git a/theme/packages/main/src/assets/images/landingpage/favicon.png b/theme/packages/main/src/assets/images/landingpage/favicon.png new file mode 100644 index 0000000..80ba642 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/favicon.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/frameworks/angular.svg b/theme/packages/main/src/assets/images/landingpage/frameworks/angular.svg new file mode 100644 index 0000000..bf081ac --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/frameworks/angular.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/landingpage/frameworks/icon-tabler.svg b/theme/packages/main/src/assets/images/landingpage/frameworks/icon-tabler.svg new file mode 100644 index 0000000..6e6810e --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/frameworks/icon-tabler.svg @@ -0,0 +1,3 @@ + + + diff --git a/theme/packages/main/src/assets/images/landingpage/frameworks/logo-apex.svg b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-apex.svg new file mode 100644 index 0000000..b3e00c4 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-apex.svg @@ -0,0 +1,9 @@ + + New Project + + + + + + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/landingpage/frameworks/logo-figma.svg b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-figma.svg new file mode 100644 index 0000000..6f1faf6 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-figma.svg @@ -0,0 +1,9 @@ + + New Project + + + + + + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/landingpage/frameworks/logo-js.svg b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-js.svg new file mode 100644 index 0000000..04065d3 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-js.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/landingpage/frameworks/logo-mui.svg b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-mui.svg new file mode 100644 index 0000000..2a99e21 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-mui.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/landingpage/frameworks/logo-react.svg b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-react.svg new file mode 100644 index 0000000..a4bff17 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-react.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/main/src/assets/images/landingpage/frameworks/logo-redux.svg b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-redux.svg new file mode 100644 index 0000000..b89147b --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-redux.svg @@ -0,0 +1,3 @@ + + + diff --git a/theme/packages/main/src/assets/images/landingpage/frameworks/logo-ts.svg b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-ts.svg new file mode 100644 index 0000000..5b7da07 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/frameworks/logo-ts.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/landingpage/frameworks/material.svg b/theme/packages/main/src/assets/images/landingpage/frameworks/material.svg new file mode 100644 index 0000000..9ac2836 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/frameworks/material.svg @@ -0,0 +1 @@ +material \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/landingpage/profile/testimonial1.png b/theme/packages/main/src/assets/images/landingpage/profile/testimonial1.png new file mode 100644 index 0000000..959e55b Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/profile/testimonial1.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/profile/testimonial2.png b/theme/packages/main/src/assets/images/landingpage/profile/testimonial2.png new file mode 100644 index 0000000..b332e26 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/profile/testimonial2.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/profile/testimonial3.png b/theme/packages/main/src/assets/images/landingpage/profile/testimonial3.png new file mode 100644 index 0000000..bd5aaa9 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/profile/testimonial3.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/profile/user1.png b/theme/packages/main/src/assets/images/landingpage/profile/user1.png new file mode 100644 index 0000000..fbed268 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/profile/user1.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/profile/user2.png b/theme/packages/main/src/assets/images/landingpage/profile/user2.png new file mode 100644 index 0000000..ade53d2 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/profile/user2.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/profile/user3.png b/theme/packages/main/src/assets/images/landingpage/profile/user3.png new file mode 100644 index 0000000..461d710 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/profile/user3.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/shape/badge.png b/theme/packages/main/src/assets/images/landingpage/shape/badge.png new file mode 100644 index 0000000..50cd545 Binary files /dev/null and b/theme/packages/main/src/assets/images/landingpage/shape/badge.png differ diff --git a/theme/packages/main/src/assets/images/landingpage/shape/badge.svg b/theme/packages/main/src/assets/images/landingpage/shape/badge.svg new file mode 100644 index 0000000..cb69f54 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/shape/badge.svg @@ -0,0 +1,3 @@ + + + diff --git a/theme/packages/main/src/assets/images/landingpage/shape/line-bg-2.svg b/theme/packages/main/src/assets/images/landingpage/shape/line-bg-2.svg new file mode 100644 index 0000000..df28d75 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/shape/line-bg-2.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/landingpage/shape/line-bg.svg b/theme/packages/main/src/assets/images/landingpage/shape/line-bg.svg new file mode 100644 index 0000000..dbb849b --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/shape/line-bg.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/landingpage/shape/shape-1.svg b/theme/packages/main/src/assets/images/landingpage/shape/shape-1.svg new file mode 100644 index 0000000..30463fb --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/shape/shape-1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/landingpage/shape/shape-2.svg b/theme/packages/main/src/assets/images/landingpage/shape/shape-2.svg new file mode 100644 index 0000000..4130b24 --- /dev/null +++ b/theme/packages/main/src/assets/images/landingpage/shape/shape-2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/logos/dark-logo.svg b/theme/packages/main/src/assets/images/logos/dark-logo.svg new file mode 100644 index 0000000..c0e674b --- /dev/null +++ b/theme/packages/main/src/assets/images/logos/dark-logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/theme/packages/main/src/assets/images/logos/dark-rtl-logo.svg b/theme/packages/main/src/assets/images/logos/dark-rtl-logo.svg new file mode 100644 index 0000000..afa324d --- /dev/null +++ b/theme/packages/main/src/assets/images/logos/dark-rtl-logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/main/src/assets/images/logos/light-logo-rtl.svg b/theme/packages/main/src/assets/images/logos/light-logo-rtl.svg new file mode 100644 index 0000000..1b3c4a6 --- /dev/null +++ b/theme/packages/main/src/assets/images/logos/light-logo-rtl.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/main/src/assets/images/logos/light-logo.svg b/theme/packages/main/src/assets/images/logos/light-logo.svg new file mode 100644 index 0000000..0eb8718 --- /dev/null +++ b/theme/packages/main/src/assets/images/logos/light-logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/main/src/assets/images/products/Screenshot_1.png b/theme/packages/main/src/assets/images/products/Screenshot_1.png new file mode 100644 index 0000000..0f02cc5 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/Screenshot_1.png differ diff --git a/theme/packages/main/src/assets/images/products/empty-shopping-bag.gif b/theme/packages/main/src/assets/images/products/empty-shopping-bag.gif new file mode 100644 index 0000000..558d4d1 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/empty-shopping-bag.gif differ diff --git a/theme/packages/main/src/assets/images/products/empty-shopping-cart.svg b/theme/packages/main/src/assets/images/products/empty-shopping-cart.svg new file mode 100644 index 0000000..dfe6f20 --- /dev/null +++ b/theme/packages/main/src/assets/images/products/empty-shopping-cart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/products/payment-complete.gif b/theme/packages/main/src/assets/images/products/payment-complete.gif new file mode 100644 index 0000000..05b78d8 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/payment-complete.gif differ diff --git a/theme/packages/main/src/assets/images/products/payment.svg b/theme/packages/main/src/assets/images/products/payment.svg new file mode 100644 index 0000000..39a39f3 --- /dev/null +++ b/theme/packages/main/src/assets/images/products/payment.svg @@ -0,0 +1,1085 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/products/product-1.jpg b/theme/packages/main/src/assets/images/products/product-1.jpg new file mode 100644 index 0000000..32e1a5c Binary files /dev/null and b/theme/packages/main/src/assets/images/products/product-1.jpg differ diff --git a/theme/packages/main/src/assets/images/products/product-2.jpg b/theme/packages/main/src/assets/images/products/product-2.jpg new file mode 100644 index 0000000..2601e45 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/product-2.jpg differ diff --git a/theme/packages/main/src/assets/images/products/product-3.jpg b/theme/packages/main/src/assets/images/products/product-3.jpg new file mode 100644 index 0000000..bb202c3 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/product-3.jpg differ diff --git a/theme/packages/main/src/assets/images/products/product-4.jpg b/theme/packages/main/src/assets/images/products/product-4.jpg new file mode 100644 index 0000000..e13e01c Binary files /dev/null and b/theme/packages/main/src/assets/images/products/product-4.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s1.jpg b/theme/packages/main/src/assets/images/products/s1.jpg new file mode 100644 index 0000000..144d0e8 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s1.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s10.jpg b/theme/packages/main/src/assets/images/products/s10.jpg new file mode 100644 index 0000000..cf64bc3 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s10.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s11.jpg b/theme/packages/main/src/assets/images/products/s11.jpg new file mode 100644 index 0000000..8980089 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s11.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s12.jpg b/theme/packages/main/src/assets/images/products/s12.jpg new file mode 100644 index 0000000..88a6dbc Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s12.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s2.jpg b/theme/packages/main/src/assets/images/products/s2.jpg new file mode 100644 index 0000000..9bc8e62 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s2.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s3.jpg b/theme/packages/main/src/assets/images/products/s3.jpg new file mode 100644 index 0000000..6413e06 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s3.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s4.jpg b/theme/packages/main/src/assets/images/products/s4.jpg new file mode 100644 index 0000000..803e397 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s4.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s5.jpg b/theme/packages/main/src/assets/images/products/s5.jpg new file mode 100644 index 0000000..c40751b Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s5.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s6.jpg b/theme/packages/main/src/assets/images/products/s6.jpg new file mode 100644 index 0000000..3ca15a9 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s6.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s7.jpg b/theme/packages/main/src/assets/images/products/s7.jpg new file mode 100644 index 0000000..d819743 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s7.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s8.jpg b/theme/packages/main/src/assets/images/products/s8.jpg new file mode 100644 index 0000000..ba04626 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s8.jpg differ diff --git a/theme/packages/main/src/assets/images/products/s9.jpg b/theme/packages/main/src/assets/images/products/s9.jpg new file mode 100644 index 0000000..18c7623 Binary files /dev/null and b/theme/packages/main/src/assets/images/products/s9.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-1.jpg b/theme/packages/main/src/assets/images/profile/user-1.jpg new file mode 100644 index 0000000..e19df67 Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-1.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-10.jpg b/theme/packages/main/src/assets/images/profile/user-10.jpg new file mode 100644 index 0000000..7d4531f Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-10.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-11.jpg b/theme/packages/main/src/assets/images/profile/user-11.jpg new file mode 100644 index 0000000..8d54dc0 Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-11.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-12.jpg b/theme/packages/main/src/assets/images/profile/user-12.jpg new file mode 100644 index 0000000..adbbde4 Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-12.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-2.jpg b/theme/packages/main/src/assets/images/profile/user-2.jpg new file mode 100644 index 0000000..52d8f1f Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-2.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-3.jpg b/theme/packages/main/src/assets/images/profile/user-3.jpg new file mode 100644 index 0000000..2a541d7 Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-3.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-4.jpg b/theme/packages/main/src/assets/images/profile/user-4.jpg new file mode 100644 index 0000000..e9312df Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-4.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-5.jpg b/theme/packages/main/src/assets/images/profile/user-5.jpg new file mode 100644 index 0000000..ff2e6f0 Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-5.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-6.jpg b/theme/packages/main/src/assets/images/profile/user-6.jpg new file mode 100644 index 0000000..867b150 Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-6.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-7.jpg b/theme/packages/main/src/assets/images/profile/user-7.jpg new file mode 100644 index 0000000..df8e3fb Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-7.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-8.jpg b/theme/packages/main/src/assets/images/profile/user-8.jpg new file mode 100644 index 0000000..facea41 Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-8.jpg differ diff --git a/theme/packages/main/src/assets/images/profile/user-9.jpg b/theme/packages/main/src/assets/images/profile/user-9.jpg new file mode 100644 index 0000000..9de110f Binary files /dev/null and b/theme/packages/main/src/assets/images/profile/user-9.jpg differ diff --git a/theme/packages/main/src/assets/images/shapes/shape-1.svg b/theme/packages/main/src/assets/images/shapes/shape-1.svg new file mode 100644 index 0000000..30463fb --- /dev/null +++ b/theme/packages/main/src/assets/images/shapes/shape-1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/shapes/shape-2.svg b/theme/packages/main/src/assets/images/shapes/shape-2.svg new file mode 100644 index 0000000..4130b24 --- /dev/null +++ b/theme/packages/main/src/assets/images/shapes/shape-2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/theme/packages/main/src/assets/images/svgs/facebook-icon.svg b/theme/packages/main/src/assets/images/svgs/facebook-icon.svg new file mode 100644 index 0000000..c24d6ba --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/facebook-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/svgs/google-icon.svg b/theme/packages/main/src/assets/images/svgs/google-icon.svg new file mode 100644 index 0000000..1307b69 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/google-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-account.svg b/theme/packages/main/src/assets/images/svgs/icon-account.svg new file mode 100644 index 0000000..da8f1a1 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-account.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-briefcase.svg b/theme/packages/main/src/assets/images/svgs/icon-briefcase.svg new file mode 100644 index 0000000..6bbd6d4 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-briefcase.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/svgs/icon-connect.svg b/theme/packages/main/src/assets/images/svgs/icon-connect.svg new file mode 100644 index 0000000..0adb3ea --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-connect.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/svgs/icon-dd-application.svg b/theme/packages/main/src/assets/images/svgs/icon-dd-application.svg new file mode 100644 index 0000000..6adaa3c --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-dd-application.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-dd-cart.svg b/theme/packages/main/src/assets/images/svgs/icon-dd-cart.svg new file mode 100644 index 0000000..00b79fe --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-dd-cart.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-dd-chat.svg b/theme/packages/main/src/assets/images/svgs/icon-dd-chat.svg new file mode 100644 index 0000000..fdb1ad0 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-dd-chat.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-dd-date.svg b/theme/packages/main/src/assets/images/svgs/icon-dd-date.svg new file mode 100644 index 0000000..f56859c --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-dd-date.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-dd-invoice.svg b/theme/packages/main/src/assets/images/svgs/icon-dd-invoice.svg new file mode 100644 index 0000000..035cebf --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-dd-invoice.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-dd-lifebuoy.svg b/theme/packages/main/src/assets/images/svgs/icon-dd-lifebuoy.svg new file mode 100644 index 0000000..9d464e1 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-dd-lifebuoy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-dd-message-box.svg b/theme/packages/main/src/assets/images/svgs/icon-dd-message-box.svg new file mode 100644 index 0000000..f2d4d07 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-dd-message-box.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-dd-mobile.svg b/theme/packages/main/src/assets/images/svgs/icon-dd-mobile.svg new file mode 100644 index 0000000..66c22f0 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-dd-mobile.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-favorites.svg b/theme/packages/main/src/assets/images/svgs/icon-favorites.svg new file mode 100644 index 0000000..84fedaa --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-favorites.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/svgs/icon-inbox.svg b/theme/packages/main/src/assets/images/svgs/icon-inbox.svg new file mode 100644 index 0000000..ebcb4ec --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-inbox.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-mailbox.svg b/theme/packages/main/src/assets/images/svgs/icon-mailbox.svg new file mode 100644 index 0000000..a4a3aa3 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-mailbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/svgs/icon-master-card-2.svg b/theme/packages/main/src/assets/images/svgs/icon-master-card-2.svg new file mode 100644 index 0000000..4adbf06 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-master-card-2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-master-card.svg b/theme/packages/main/src/assets/images/svgs/icon-master-card.svg new file mode 100644 index 0000000..2ceeaad --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-master-card.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-office-bag-2.svg b/theme/packages/main/src/assets/images/svgs/icon-office-bag-2.svg new file mode 100644 index 0000000..8b7cbe1 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-office-bag-2.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-office-bag.svg b/theme/packages/main/src/assets/images/svgs/icon-office-bag.svg new file mode 100644 index 0000000..a7dedaa --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-office-bag.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-paypal.svg b/theme/packages/main/src/assets/images/svgs/icon-paypal.svg new file mode 100644 index 0000000..c17ed7f --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-paypal.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-pie.svg b/theme/packages/main/src/assets/images/svgs/icon-pie.svg new file mode 100644 index 0000000..01d5297 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-pie.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-speech-bubble.svg b/theme/packages/main/src/assets/images/svgs/icon-speech-bubble.svg new file mode 100644 index 0000000..2e1f2bd --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-speech-bubble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/svgs/icon-tasks.svg b/theme/packages/main/src/assets/images/svgs/icon-tasks.svg new file mode 100644 index 0000000..a6c280f --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-tasks.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/main/src/assets/images/svgs/icon-user-male.svg b/theme/packages/main/src/assets/images/svgs/icon-user-male.svg new file mode 100644 index 0000000..2832c4f --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/icon-user-male.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/svgs/mastercard.svg b/theme/packages/main/src/assets/images/svgs/mastercard.svg new file mode 100644 index 0000000..3fdc683 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/mastercard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/svgs/paypal.svg b/theme/packages/main/src/assets/images/svgs/paypal.svg new file mode 100644 index 0000000..41e02d5 --- /dev/null +++ b/theme/packages/main/src/assets/images/svgs/paypal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/main/src/assets/images/taskboard/kanban-img-1.jpg b/theme/packages/main/src/assets/images/taskboard/kanban-img-1.jpg new file mode 100644 index 0000000..c08ff5c Binary files /dev/null and b/theme/packages/main/src/assets/images/taskboard/kanban-img-1.jpg differ diff --git a/theme/packages/main/src/assets/images/taskboard/kanban-img-2.jpg b/theme/packages/main/src/assets/images/taskboard/kanban-img-2.jpg new file mode 100644 index 0000000..c1b79bb Binary files /dev/null and b/theme/packages/main/src/assets/images/taskboard/kanban-img-2.jpg differ diff --git a/theme/packages/main/src/assets/images/taskboard/kanban-img-3.jpg b/theme/packages/main/src/assets/images/taskboard/kanban-img-3.jpg new file mode 100644 index 0000000..0a44600 Binary files /dev/null and b/theme/packages/main/src/assets/images/taskboard/kanban-img-3.jpg differ diff --git a/theme/packages/main/src/assets/images/taskboard/kanban-img-4.jpg b/theme/packages/main/src/assets/images/taskboard/kanban-img-4.jpg new file mode 100644 index 0000000..9d89edd Binary files /dev/null and b/theme/packages/main/src/assets/images/taskboard/kanban-img-4.jpg differ diff --git a/theme/packages/main/src/assets/scss/_container.scss b/theme/packages/main/src/assets/scss/_container.scss new file mode 100644 index 0000000..730c06f --- /dev/null +++ b/theme/packages/main/src/assets/scss/_container.scss @@ -0,0 +1,154 @@ +@use "variables" as *; + +*, +:after, +:before { + box-sizing: border-box; +} + +body { + font-family: $font-family; + line-height: 1.334rem; + overflow-x: hidden; + color: var(--mat-sys-on-background); +} + +.mainWrapper { + display: flex; + min-height: 100vh; + width: 100%; + flex: 1; + height: 100%; +} + +.container { + max-width: 1200px; + padding-left: 24px; + padding-right: 24px; + margin: 0 auto; + + &.full-width { + display: flex; + align-items: center; + width: 100%; + } +} + +.pageWrapper { + padding: 24px; + min-height: calc(100vh - 70px); + + margin: 0 auto; + + &.maxWidth { + max-width: $boxedWidth; + } +} + +.w-100 { + width: 100%; +} + +.h-100 { + height: 100%; +} + +.shadow-none { + box-shadow: none !important; +} + +.rounded { + border-radius: $border-radius !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 25px !important; +} + +.overflow-hidden { + overflow: hidden; +} + +.text-decoration-none { + text-decoration: none; +} + +.position-relative { + position: relative; +} + +.table-responsive { + overflow-x: auto; + + td, + mat-cell { + white-space: nowrap; + padding: 16px; + } +} + +.op-5 { + opacity: 0.5; +} + +.cursor-pointer { + cursor: pointer; +} + +.avatar-group { + img { + border: 2px solid $white; + margin-right: -5px; + + &:last-child { + margin-right: 0; + } + } +} + +a { + color: var(--mat-sys-on-background); + + &:hover { + color: $primary; + } +} + +.filter-sidebar { + width: 290px; + position: fixed; + right: -290px; + top: 0; + z-index: 10; + height: 100%; + transition: all 0.3s ease-in-out; + box-shadow: var(--mat-sys-level3); + background-color: var(--mat-sys-background); + + &.open { + right: 0; + } +} + +pre { + margin: 0; + white-space: nowrap; +} + +td.hljs-ln-line.hljs-ln-numbers { + padding-right: 10px; +} + +@media (min-width: 768px) { + html .flex-sm-row { + flex-direction: row !important; + } +} + +.mat-drawer[style*="visibility: hidden"] { + display: none; +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/_variables.scss b/theme/packages/main/src/assets/scss/_variables.scss new file mode 100644 index 0000000..c06babd --- /dev/null +++ b/theme/packages/main/src/assets/scss/_variables.scss @@ -0,0 +1,43 @@ +@import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap"); + +// font +$font-family: "Plus Jakarta Sans", sans-serif; + +// light color variable + +// Sidenav +$sidenav-desktop: 270px !default; +$sidenav-mini: 80px !default; +$header-height: 70px !default; + +//BorderColor +$borderColor: var(--mat-sys-outline-variant); +$borderformColor: var(--mat-sys-outline-variant); + +// custom +$primary: var(--mat-sys-primary); +$secondary: var(--mat-sys-secondary); +$accent: var(--mat-sys-secondary); +$error: var(--mat-sys-error); +$warning: #ffae1f; +$success: #13deb9; +$white: #ffffff; + +$light: var(--mat-sys-surface-bright); +$light-primary: var(--mat-sys-primary-fixed-dim); +$light-secondary: var(--mat-sys-secondary-fixed-dim); +$light-accent: var(--mat-sys-secondary-fixed-dim); +$light-error: var(--mat-sys-error-fixed-dim); +$light-warning: #ffad1f40; +$light-success: #13deb940; + +// layout +$boxedWidth: 1200px; +$border-radius: 7px; + +$card-spacer: 24px; + +$text-color: var(--mat-sys-on-background); + +$dark-text-secondary: rgba(255, 255, 255, 0.67); +$dark-body-bg: #141a21; diff --git a/theme/packages/main/src/assets/scss/apps/_blogs.scss b/theme/packages/main/src/assets/scss/apps/_blogs.scss new file mode 100644 index 0000000..efffaac --- /dev/null +++ b/theme/packages/main/src/assets/scss/apps/_blogs.scss @@ -0,0 +1,46 @@ +.card-overlay { + position: absolute; + top: 0; + width: 100%; + height: 225px; +} + +.user-category { + margin-top: -45px; + z-index: 1; + position: relative; +} + +.featured-card { + height: 400px; + &:before { + content: ""; + position: absolute; + background: rgba(33, 33, 33, 0.6); + top: 0; + width: 100%; + height: 100%; + z-index: 1; + } + .featured-overlay { + position: absolute; + z-index: 2; + top: 0; + width: 100%; + height: 100%; + } +} + +.detail-card-overlay { + position: absolute; + top: 0; + width: 100%; + height: 440px; +} + +@media (min-width: 1200px) { + .blog-title { + font-size: 36px; + line-height: 40px; + } +} diff --git a/theme/packages/main/src/assets/scss/apps/_calendar.scss b/theme/packages/main/src/assets/scss/apps/_calendar.scss new file mode 100644 index 0000000..6f48b6c --- /dev/null +++ b/theme/packages/main/src/assets/scss/apps/_calendar.scss @@ -0,0 +1,85 @@ +@use "../variables" as *; + +.cal-event-action { + text-decoration: none; + margin-left: 5px; + color: $white; +} + +.cal-month-view { + background-color: transparent !important; + + .cal-open-day-events { + background-color: $dark-body-bg !important; + } + + .cal-day-badge { + background-color: var(--mat-sys-primary) !important; + } + + .cal-day-cell.cal-weekend .cal-day-number { + color: var(--mat-sys-primary) !important; + } + + .cal-cell { + font-size: 14px; + font-weight: 500; + } +} + +.add-event-date .mat-mdc-icon-button { + width: 35px !important; + height: 35px !important; + padding: 0 !important; + display: flex; + align-items: center; + justify-content: center; +} + +html { + + .cal-week-view, + .cal-week-view .cal-hour-odd { + background-color: var(--mat-sys-surface); + } + + .cal-month-view .cal-cell-row:hover, + .cal-month-view .cal-cell-row .cal-cell:hover, + .cal-month-view .cal-cell.cal-has-events.cal-open, + .cal-week-view .cal-time-events .cal-day-columns:not(.cal-resize-active) .cal-hour-segment:hover, + .cal-week-view .cal-day-headers .cal-header:hover, + .cal-week-view .cal-day-headers .cal-drag-over { + background-color: var(--mat-option-focus-state-layer-color); + } + + .cal-month-view .cal-day-cell:not(:last-child) { + border-right-color: var(--mat-sys-outline); + } + + .cal-month-view .cal-days .cal-cell-row, + .cal-week-view .cal-hour:not(:last-child) .cal-hour-segment, + .cal-week-view .cal-hour:last-child :not(:last-child) .cal-hour-segment { + border-bottom-color: var(--mat-sys-outline); + } + + .cal-month-view .cal-days, + .cal-week-view, + .cal-week-view .cal-day-headers, + .cal-week-view .cal-time-events, + .cal-week-view .cal-day-column, + .cal-week-view .cal-day-headers .cal-header:first-child, + .cal-week-view .cal-day-headers .cal-header:not(:last-child) { + border-color: var(--mat-sys-outline); + } +} + +// +// ticket app +// +.max-text { + max-width: 250px; + line-height: 1.57; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/apps/_chat.scss b/theme/packages/main/src/assets/scss/apps/_chat.scss new file mode 100644 index 0000000..296db7d --- /dev/null +++ b/theme/packages/main/src/assets/scss/apps/_chat.scss @@ -0,0 +1,36 @@ +.chat-list { + overflow: hidden; + box-sizing: border-box; + width: 100%; + margin-bottom: 1rem; + display: flex; + + &.even { + -webkit-box-pack: end; + -ms-flex-pack: end; + -moz-justify-content: flex-end; + justify-content: flex-end; + text-align: right; + } +} + +.chat-app { + .mat-drawer { + width: 320px; + } + .ng-scroll-content { + display: block !important; + } +} + +.chat-listing { + .mdc-list-item { + height: 75px; + display: flex; + align-items: center; + + .mdc-list-item__primary-text { + margin-bottom: -23px !important; + } + } +} diff --git a/theme/packages/main/src/assets/scss/apps/_contact-list.scss b/theme/packages/main/src/assets/scss/apps/_contact-list.scss new file mode 100644 index 0000000..9cf1b85 --- /dev/null +++ b/theme/packages/main/src/assets/scss/apps/_contact-list.scss @@ -0,0 +1,59 @@ +@use "../variables" as *; + +@media (max-width: 1279px) { + .detail-part.movetodetail { + display: block; + position: absolute; + z-index: 9; + left: 0; + background: var(--mat-card-elevated-container-color); + } +} + +@media (max-width: 1279px) { + .welcome-app { + display: none; + } +} + +@media (max-width: 959px) { + .contact-detail-part { + display: none; + } + + .contact-detail-part.activeContact { + position: absolute !important; + top: 0; + left: 0; + display: block; + width: 100%; + height: 100%; + z-index: 999; + background-color: var(--mat-card-elevated-container-color); + } +} + +// contact app +.uploader { + .upload-image { + width: 100px; + height: auto; + cursor: pointer; + } + + input[type="file"] { + position: absolute; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + } +} + +.contact-listing { + .mdc-list-item__primary-text { + margin-bottom: -11px !important; + margin-top: 10px !important; + } +} diff --git a/theme/packages/main/src/assets/scss/apps/_courses.scss b/theme/packages/main/src/assets/scss/apps/_courses.scss new file mode 100644 index 0000000..9a71edb --- /dev/null +++ b/theme/packages/main/src/assets/scss/apps/_courses.scss @@ -0,0 +1,25 @@ +@use "../variables" as *; + +.course-header { + padding: 12px !important; + color: $white; +} + +.course-header, +.detail-bg { + &.Angular { + background-color: var(--mat-sys-error); + } + + &.Web { + background-color: var(--mat-sys-primary); + } + + &.Design { + background-color: var(--mat-sys-secondary); + } + + &.Android { + background-color: $warning; + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/apps/_ecommerce.scss b/theme/packages/main/src/assets/scss/apps/_ecommerce.scss new file mode 100644 index 0000000..467169d --- /dev/null +++ b/theme/packages/main/src/assets/scss/apps/_ecommerce.scss @@ -0,0 +1,94 @@ +body { + + // Add Product + + .NgxEditor__Wrapper { + border: 1px solid var(--mat-sys-outline-variant); + } + + .NgxEditor__Seperator { + border-left: 1px solid var(--mat-sys-outline-variant); + } + + .NgxEditor__MenuBar { + background-color: var(--mat-card-elevated-container-color); + border-bottom: 1px solid var(--mat-sys-outline-variant) !important; + } + + .NgxEditor { + background: var(--mat-card-elevated-container-color); + color: var(--mat-sys-on-background); + } + + .NgxEditor__MenuItem .NgxEditor__MenuItem--Icon:hover { + background-color: var(--mat-sys-primary); + color: var(--mat-sys-background); + } + + .NgxEditor__Dropdown:hover { + background-color: var(--mat-sys-primary); + + .NgxEditor__Dropdown--Text { + color: var(--mat-sys-background); + } + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--Selected, + .NgxEditor__Dropdown .NgxEditor__Dropdown--Open { + color: var(--mat-sys-background); + background-color: var(--mat-sys-primary); + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--Item:hover { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--DropdownMenu { + background-color: var(--mat-card-elevated-container-color); + } + + + .dropzone-box { + border: 1px dashed var(--mat-sys-primary); + background-color: var(--mat-sys-primary-fixed-dim); + + .dropzone-content { + .preview-image { + width: 100px; + height: 70px; + object-fit: cover; + border-radius: 6px; + margin-bottom: 0.5rem; + } + } + + .headline { + margin: 0; + } + } + + .cards-circle { + width: 15px; + height: 15px; + border-radius: var(--mat-sys-corner-full); + display: flex; + align-items: center; + justify-content: center; + background-color: var(--mat-sys-primary); + + .theme-icon { + display: none; + } + + &.selected { + .theme-icon { + display: block; + color: white; + width: 18px; + height: 25px; + } + } + } + +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/apps/_email.scss b/theme/packages/main/src/assets/scss/apps/_email.scss new file mode 100644 index 0000000..abe434c --- /dev/null +++ b/theme/packages/main/src/assets/scss/apps/_email.scss @@ -0,0 +1,52 @@ +@use "../variables" as *; + +.ngx-pagination { + margin-bottom: 15px !important; + + .current { + background: var(--mat-sys-primary) !important; + border-radius: $border-radius; + } + + a { + border-radius: $border-radius !important; + } + + button { + border-radius: $border-radius !important; + } +} + +html .mail-sidebar { + width: 240px; +} + +.email-box { + @media (max-width: 991px) { + .detail-part { + display: none; + } + } + + @media (max-width: 1279px) { + .detail-part.movetodetail { + display: block; + position: absolute; + z-index: 9; + left: 0; + background: $white; + } + + } +} + +// invoice app + +.add-invoice-list, +.edit-invoice-list { + .table { + .mat-mdc-form-field-infix { + width: auto; + } + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/apps/_kanban.scss b/theme/packages/main/src/assets/scss/apps/_kanban.scss new file mode 100644 index 0000000..88e5215 --- /dev/null +++ b/theme/packages/main/src/assets/scss/apps/_kanban.scss @@ -0,0 +1,39 @@ +@use "../variables" as *; + +.task-list-section { + display: flex; + gap: 24px; + flex-wrap: nowrap; +} + +.task-list-container { + width: 258px; + flex-shrink: 0; +} + +.connect-sorting { + padding: 20px; + border-radius: $border-radius; +} + +.img-task { + cursor: grab; +} + +.cdk-drag-preview { + box-sizing: border-box; + border-radius: $border-radius; + box-shadow: var(--mat-sys-level2); +} + +.cdk-drag-placeholder { + opacity: 0; +} + +.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.cdk-drop-list { + padding: 0px 0px 20px 0px !important +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/apps/_todo.scss b/theme/packages/main/src/assets/scss/apps/_todo.scss new file mode 100644 index 0000000..8052e1e --- /dev/null +++ b/theme/packages/main/src/assets/scss/apps/_todo.scss @@ -0,0 +1,25 @@ +@use "../variables" as *; + +.todo-item { + position: relative; + + .edit-view { + position: absolute; + left: 0; + background: $white; + width: 100%; + top: 15px; + padding: 0 13px; + height: 70px; + } +} + +.app-left-sidebar { + &.mat-sidenav { + width: 240px; + } +} + +.completed { + text-decoration: line-through; +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/dark/_dark.scss b/theme/packages/main/src/assets/scss/dark/_dark.scss new file mode 100644 index 0000000..b371092 --- /dev/null +++ b/theme/packages/main/src/assets/scss/dark/_dark.scss @@ -0,0 +1,68 @@ +@use "sass:meta"; +@use "../variables" as *; + +.dark-theme { + // typography + color: $dark-text-secondary; + + .mat-mdc-menu-panel { + color: var(--mat-sys-on-background) !important; + } + + .bg-white, + .mdc-menu-surface { + background-color: var(--mat-sys-surface) !important; + } + + .topbar { + background-color: var(--mat-sys-surface); + } + + .hljs { + background: var(--mat-sys-surface); + } + + // ------------------------------------------------------- + // border + // ------------------------------------------------------- + + .b-1 { + border: 1px solid var(--mat-sys-outline-variant) !important; + } + + .b-b-1 { + border-bottom: 1px solid var(--mat-sys-outline-variant) !important; + } + + .b-t-1 { + border-top: 1px solid var(--mat-sys-outline-variant) !important; + } + + .b-r-1 { + border-right: 1px solid var(--mat-sys-outline-variant) !important; + } + + .b-l-1 { + border-left: 1px solid var(--mat-sys-outline-variant); + } + + // fill + .customizer-button-group .mat-button-toggle-appearance-standard.mat-button-toggle-checked i-tabler.fill-icon { + fill: var(--mat-sys-primary-fixed-dim); + } + +} + +// horizontal + dark + +html.dark-theme { + .logodark { + display: none; + } +} + +html.light-theme { + .logolight { + display: none; + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/grid/_grid.scss b/theme/packages/main/src/assets/scss/grid/_grid.scss new file mode 100644 index 0000000..bfbd802 --- /dev/null +++ b/theme/packages/main/src/assets/scss/grid/_grid.scss @@ -0,0 +1,35 @@ +@use 'variables'; +@use 'mixins'; + +.row { + display: flex; + flex-wrap: wrap; + margin-right: variables.$grid-gutter * -.5; + margin-left: variables.$grid-gutter * -.5; +} + +.no-gutters { + margin-right: 0; + margin-left: 0; + + > .col, + > [class*='col-'] { + padding-right: 0; + padding-left: 0; + } +} + +@include mixins.make-grid-columns(); + + +@each $breakpoint, $infix in variables.$breakpoint-infixs { + @if ($breakpoint== 'xsmall') { + @include mixins.loop-grid-columns(variables.$grid-columns, $infix); + } + + @else { + @include mixins.bp-gt($breakpoint) { + @include mixins.loop-grid-columns(variables.$grid-columns, $infix); + } + } +} diff --git a/theme/packages/main/src/assets/scss/grid/_mixins.scss b/theme/packages/main/src/assets/scss/grid/_mixins.scss new file mode 100644 index 0000000..dde3026 --- /dev/null +++ b/theme/packages/main/src/assets/scss/grid/_mixins.scss @@ -0,0 +1,79 @@ +@use 'sass:map'; +@use 'sass:math'; +@use 'variables'; + +@function bp($name, $breakpoints: variables.$breakpoints) { + $min: map.get($breakpoints, $name); + + @return $min; +} + +// Media of at least the minimum breakpoint width. +@mixin bp-gt($name, $breakpoints: variables.$breakpoints) { + $min: bp($name, $breakpoints); + + @if $min { + @media (min-width: $min) { + @content; + } + } + @else { + @content; + } +} + +// Media of at most the maximum breakpoint width. +@mixin bp-lt($name, $breakpoints: variables.$breakpoints) { + $max: bp($name, $breakpoints) - 1px; + + @if $max { + @media (max-width: $max) { + @content; + } + } + @else { + @content; + } +} + +@mixin make-grid-columns($i: 1, $list: '.col') { + @each $breakpoint, $infix in variables.$breakpoint-infixs { + $infix: if($infix == '', '', '-#{$infix}'); + + @if ($infix != '') { + $list: '#{$list}, .col#{$infix}'; + } + + @for $i from 1 through variables.$grid-columns { + $list: '#{$list}, .col#{$infix}-#{$i}'; + } + } + + #{$list} { + position: relative; + width: 100%; + padding-right: variables.$grid-gutter * .5; + padding-left: variables.$grid-gutter * .5; + } +} + +@mixin loop-grid-columns($columns: $grid-columns, $breakpoint-infix: '') { + $infix: if($breakpoint-infix == '', '', '-#{$breakpoint-infix}'); + + .col#{$infix} { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } + + @for $i from 1 through $columns { + .col#{$infix}-#{$i} { + flex: 0 0 math.percentage(math.div($i, $columns)); + max-width: math.percentage(math.div($i, $columns)); + } + + .offset#{$infix}-#{$i} { + margin-left: math.percentage(math.div($i, $columns)); + } + } +} diff --git a/theme/packages/main/src/assets/scss/grid/_variables.scss b/theme/packages/main/src/assets/scss/grid/_variables.scss new file mode 100644 index 0000000..2f3edbc --- /dev/null +++ b/theme/packages/main/src/assets/scss/grid/_variables.scss @@ -0,0 +1,18 @@ +$grid-columns: 12 !default; +$grid-gutter: 30px !default; + +$breakpoints: ( + xsmall: 0, + small: 600px, + medium: 960px, + large: 1280px, + xlarge: 2100px +) !default; + +$breakpoint-infixs: ( + xsmall: '', + small: 'sm', + medium: 'md', + large: 'lg', + xlarge: 'xl' +) !default; \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/helpers/_border-color.scss b/theme/packages/main/src/assets/scss/helpers/_border-color.scss new file mode 100644 index 0000000..86197ad --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_border-color.scss @@ -0,0 +1,18 @@ +@use "../variables" as *; +@use "sass:meta"; // Import meta module for working with keyword arguments + +// Mixin to dynamically generate classes based on provided colors +@mixin syntax-colors2($args2...) { + @each $name2, $color2 in meta.keywords($args2) { + html .border-#{$name2} { + border: 1px solid #{$color2} !important; + } + } +} + +// Including the mixin with variables and CSS variables +@include syntax-colors2($primary: var(--mat-sys-primary), + $secondary: var(--mat-sys-secondary), + $success: $success, + $warning: $warning, + $error: var(--mat-sys-error)); \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/helpers/_border.scss b/theme/packages/main/src/assets/scss/helpers/_border.scss new file mode 100644 index 0000000..a1e0393 --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_border.scss @@ -0,0 +1,32 @@ +@use 'variables'; + +$utilities: ( + 'border': ( + property: border, + class: b, + values: variables.$borders + ), + 'border-top': ( + property: border-top, + class: b-t, + values: variables.$borders + ), + 'border-bottom': ( + property: border-bottom, + class: b-b, + values: variables.$borders + ), + 'border-left': ( + property: border-left, + class: b-l, + values: variables.$borders + ), + 'border-right': ( + property: border-right, + class: b-r, + values: variables.$borders + ), + +); + + diff --git a/theme/packages/main/src/assets/scss/helpers/_color.scss b/theme/packages/main/src/assets/scss/helpers/_color.scss new file mode 100644 index 0000000..45e559b --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_color.scss @@ -0,0 +1,37 @@ +@use "sass:meta"; +@use "../variables" as *; + +@mixin syntax-colors($args...) { + @each $name, $color in meta.keywords($args) { + html .bg-#{$name} { + background-color: $color !important; + } + + html .text-#{$name} { + color: $color !important; + } + } +} + +@include syntax-colors($primary: var(--mat-sys-primary), + $secondary: var(--mat-sys-secondary), + $success: $success, + $warning: $warning, + $error: var(--mat-sys-error), + $white: $white, + $light: $light, + $light-error: var(--mat-sys-error-fixed-dim), + $light-secondary: var(--mat-sys-secondary-fixed-dim), + $light-success: $light-success, + $light-warning: $light-warning, + $light-primary: var(--mat-sys-primary-fixed-dim)); + +.fill-warning svg { + fill: $warning; + color: $warning; +} + +.fill-light svg { + fill: $light; + color: $light; +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/helpers/_custom-flex.scss b/theme/packages/main/src/assets/scss/helpers/_custom-flex.scss new file mode 100644 index 0000000..fb36a29 --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_custom-flex.scss @@ -0,0 +1,59 @@ +@media (min-width: 1200px) { + body { + .d-lg-flex { + display: flex !important; + } + + .d-lg-none { + display: none !important; + } + + .d-lg-block { + display: block !important; + } + + .align-items-lg-center { + align-items: center !important; + } + } +} + +@media (min-width: 960px) { + .d-md-none { + display: none !important; + } +} + +@media (min-width: 768px) { + body { + .d-sm-flex { + display: flex !important; + } + } +} + +@media (max-width: 767px) { + .p-xs-6 { + padding: 0 6px !important; + } +} + +.flex-shrink-0 { + flex-shrink: 0; +} + +.flex-1-auto { + flex: 1 1 0%; +} + +.hstack { + display: flex; + flex-direction: row; + gap: 20px; +} + +@media (max-width: 767px) { + .hstack { + flex-direction: column; + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/helpers/_display.scss b/theme/packages/main/src/assets/scss/helpers/_display.scss new file mode 100644 index 0000000..ae8250e --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_display.scss @@ -0,0 +1,8 @@ +@use "variables"; + +$utilities: ( + "display": (property: display, + class: d, + values: inline inline-block block grid table table-row table-cell flex inline-flex none, + ), +); \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/helpers/_flexbox.scss b/theme/packages/main/src/assets/scss/helpers/_flexbox.scss new file mode 100644 index 0000000..d7d21d5 --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_flexbox.scss @@ -0,0 +1,71 @@ +@use "variables"; + +$utilities: ( + "flex": (property: flex, + class: flex, + values: (fill: 1 1 auto, + ), + ), + "flex-direction": (property: flex-direction, + class: flex, + values: (row: row, + row-reverse: row-reverse, + col: column, + col-reverse: column-reverse, + ), + ), + "flex-grow": (property: flex-grow, + class: flex, + values: (grow-0: 0, + grow-1: 1, + ), + ), + "flex-shrink": (property: flex-shrink, + class: flex, + values: (shrink-0: 0, + shrink-1: 1, + ), + ), + "flex-wrap": (property: flex-wrap, + class: flex, + values: wrap nowrap wrap-reverse, + ), + "justify-content": (property: justify-content, + class: justify-content, + values: (start: flex-start, + end: flex-end, + center: center, + between: space-between, + around: space-around, + ), + ), + "align-content": (property: align-content, + class: align-content, + values: (start: flex-start, + end: flex-end, + center: center, + between: space-between, + around: space-around, + stretch: stretch, + ), + ), + "align-items": (property: align-items, + class: align-items, + values: (start: flex-start, + end: flex-end, + center: center, + baseline: baseline, + stretch: stretch, + ), + ), + "align-self": (property: align-self, + class: align-self, + values: (auto: auto, + start: flex-start, + end: flex-end, + center: center, + baseline: baseline, + stretch: stretch, + ), + ), +); \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/helpers/_functions.scss b/theme/packages/main/src/assets/scss/helpers/_functions.scss new file mode 100644 index 0000000..1c7dd6c --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_functions.scss @@ -0,0 +1,25 @@ +@use "sass:map"; + +// It makes the value negative. +@function negativify-map($map) { + $result: (); + + @each $key, $value in $map { + @if $key !=0 { + $result: map.merge($result, ("-" + $key: (-$value))); + } + } + + @return $result; +} + +// It allows to combine multiple maps together. +@function map-collect($maps...) { + $collection: (); + + @each $map in $maps { + $collection: map.merge($collection, $map); + } + + @return $collection; +} diff --git a/theme/packages/main/src/assets/scss/helpers/_icon-size.scss b/theme/packages/main/src/assets/scss/helpers/_icon-size.scss new file mode 100644 index 0000000..ac526ef --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_icon-size.scss @@ -0,0 +1,15 @@ +@use "sass:meta"; + +$columns: 54; + +@mixin icon_size { + @for $i from 1 through $columns { + .icon-#{$i} { + height: #{$i}px !important; + width: #{$i}px !important; + line-height: #{$i + 8}px !important; + } + } +} + +@include icon_size; diff --git a/theme/packages/main/src/assets/scss/helpers/_index.scss b/theme/packages/main/src/assets/scss/helpers/_index.scss new file mode 100644 index 0000000..3ca9bce --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_index.scss @@ -0,0 +1,108 @@ +@use "sass:map"; +@use "sass:meta"; +@use "sass:list"; +@use "variables"; + +@use "functions"; +@use "flexbox"; +@use "display"; +@use "border"; +@use "text"; +@use "spacing"; +@use "rounded"; + +$utilities: functions.map-collect(variables.$utilities, + display.$utilities, + flexbox.$utilities, + spacing.$utilities, + border.$utilities, + rounded.$utilities, + text.$utilities); + +@each $key, $utility in $utilities { + $values: map.get($utility, values); + + // If the values are a list or string, convert it into a map + @if meta.type-of($values)=="string" or meta.type-of(list.nth($values, 1)) !="list" + + { + $values: list.zip($values, $values); + } + + $properties: map.get($utility, property); + $property-class-prefix: map.get($utility, class); + + // Utility class maybe empty, (e.g. with position class) + $property-class-prefix-hyphen: if($property-class-prefix =="", + $property-class-prefix, + $property-class-prefix + "-" + ); + + @each $class-modifier, $value in $values { + .#{$property-class-prefix-hyphen + $class-modifier} { + @each $property in $properties { + #{$property}: $value !important; + } + } + } +} + +$ltrutilities: functions.map-collect(spacing.$ltr); + +@each $key, $utility in $ltrutilities { + $values: map.get($utility, values); + + // If the values are a list or string, convert it into a map + @if meta.type-of($values)=="string" or meta.type-of(list.nth($values, 1)) !="list" + + { + $values: list.zip($values, $values); + } + + $properties: map.get($utility, property); + $property-class-prefix: map.get($utility, class); + + // Utility class maybe empty, (e.g. with position class) + $property-class-prefix-hyphen: if($property-class-prefix =="", + $property-class-prefix, + $property-class-prefix + "-" + ); + + @each $class-modifier, $value in $values { + [dir="ltr"] .#{$property-class-prefix-hyphen + $class-modifier} { + @each $property in $properties { + #{$property}: $value !important; + } + } + } +} + +$rtlutilities: functions.map-collect(spacing.$rtl); + +@each $key, $utility in $rtlutilities { + $values: map.get($utility, values); + + // If the values are a list or string, convert it into a map + @if meta.type-of($values)=="string" or meta.type-of(list.nth($values, 1)) !="list" + + { + $values: list.zip($values, $values); + } + + $properties: map.get($utility, property); + $property-class-prefix: map.get($utility, class); + + // Utility class maybe empty, (e.g. with position class) + $property-class-prefix-hyphen: if($property-class-prefix =="", + $property-class-prefix, + $property-class-prefix + "-" + ); + + @each $class-modifier, $value in $values { + [dir="rtl"] .#{$property-class-prefix-hyphen + $class-modifier} { + @each $property in $properties { + #{$property}: $value !important; + } + } + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/helpers/_rounded.scss b/theme/packages/main/src/assets/scss/helpers/_rounded.scss new file mode 100644 index 0000000..9bbf013 --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_rounded.scss @@ -0,0 +1,40 @@ +@use "variables"; + +$utilities: ( + "border-radius": (property: border-radius, + class: rounded, + values: variables.$radius, + ), + "border-top-left-radius": (property: border-top-left-radius, + class: r-t-l, + values: variables.$radius, + ), + "border-top-right-radius": (property: border-top-right-radius, + class: r-t-r, + values: variables.$radius, + ), + "border-bottom-right-radius": (property: border-bottom-right-radius, + class: r-b-r, + values: variables.$radius, + ), + "border-bottom-left-radius": (property: border-bottom-left-radius, + class: r-b-l, + values: variables.$radius, + ), + "border-top-radius": (property: border-top-left-radius border-top-right-radius, + class: r-t, + values: variables.$radius, + ), + "border-bottom-radius": (property: border-bottom-left-radius border-bottom-right-radius, + class: r-b, + values: variables.$radius, + ), + "border-left-radius": (property: border-top-left-radius border-bottom-left-radius, + class: r-l, + values: variables.$radius, + ), + "border-right-radius": (property: border-top-right-radius border-bottom-right-radius, + class: r-r, + values: variables.$radius, + ), +); \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/helpers/_spacing.scss b/theme/packages/main/src/assets/scss/helpers/_spacing.scss new file mode 100644 index 0000000..6d8a8f3 --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_spacing.scss @@ -0,0 +1,136 @@ +@use "sass:map"; +@use "variables"; + +$utilities: ( + "margin": (property: margin, + class: m, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "margin-x": (property: margin-left margin-right, + class: m-x, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "margin-y": (property: margin-top margin-bottom, + class: m-y, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "margin-top": (property: margin-top, + class: m-t, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + + "margin-bottom": (property: margin-bottom, + class: m-b, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + + "negative-margin": (property: margin, + class: m, + values: variables.$negative-spacers, + ), + "negative-margin-x": (property: margin-left margin-right, + class: m-x, + values: variables.$negative-spacers, + ), + "negative-margin-y": (property: margin-top margin-bottom, + class: m-y, + values: variables.$negative-spacers, + ), + "negative-margin-top": (property: margin-top, + class: m-t, + values: variables.$negative-spacers, + ), + "negative-margin-right": (property: margin-right, + class: m-r, + values: variables.$negative-spacers, + ), + "negative-margin-bottom": (property: margin-bottom, + class: m-b, + values: variables.$negative-spacers, + ), + "negative-margin-left": (property: margin-left, + class: m-l, + values: variables.$negative-spacers, + ), + "padding": (property: padding, + class: p, + values: variables.$spacers, + ), + "padding-x": (property: padding-left padding-right, + class: p-x, + values: variables.$spacers, + ), + "padding-y": (property: padding-top padding-bottom, + class: p-y, + values: variables.$spacers, + ), + "padding-top": (property: padding-top, + class: p-t, + values: variables.$spacers, + ), + + "padding-bottom": (property: padding-bottom, + class: p-b, + values: variables.$spacers, + ), + "gap": (property: gap, + class: gap, + values: variables.$spacers, + ), +); + +$ltr: ( + "margin-right": (property: margin-right, + class: m-r, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "margin-left": (property: margin-left, + class: m-l, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "padding-left": (property: padding-left, + class: p-l, + values: variables.$spacers, + ), + "padding-right": (property: padding-right, + class: p-r, + values: variables.$spacers, + ), +); + +$rtl: ( + "margin-right": (property: margin-left, + class: m-r, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "margin-left": (property: margin-right, + class: m-l, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "padding-left": (property: padding-right, + class: p-l, + values: variables.$spacers, + ), + "padding-right": (property: padding-left, + class: p-r, + values: variables.$spacers, + ), +); \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/helpers/_text.scss b/theme/packages/main/src/assets/scss/helpers/_text.scss new file mode 100644 index 0000000..1c2636e --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_text.scss @@ -0,0 +1,84 @@ +@use "sass:map"; +@use "variables"; + +$utilities: ( + "font-size": ( + property: font-size, + class: f-s, + values: variables.$font-sizes, + ), + "font-weight": ( + property: font-weight, + class: f-w, + values: variables.$font-wieghts, + ), + "font-style": ( + property: font-style, + class: font, + values: italic normal, + ), + "text-align": ( + property: text-align, + class: text, + values: center right left, + ), + "text-decoration": ( + property: text-decoration, + class: text, + values: none underline line-through, + ), + "text-transform": ( + property: text-transform, + class: text, + values: capitalize uppercase lowercase, + ), + "white-space": ( + property: white-space, + class: text, + values: ( + wrap: normal, + nowrap: nowrap, + ), + ), + "word-wrap": ( + property: word-wrap word-break, + class: text, + values: ( + break: break-word, + ), + ), + "text-overflow": ( + property: text-overflow, + class: text, + values: ellipsis, + ), + "text-color": ( + property: color, + class: text, + values: ( + reset: inherit, + current: currentColor, + ), + ), +); + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0px; +} + +.lh-lg { + line-height: 36px !important; +} + +.lh-sm { + line-height: 20px !important; +} + +.lh-normal { + line-height: normal !important; +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/helpers/_variables.scss b/theme/packages/main/src/assets/scss/helpers/_variables.scss new file mode 100644 index 0000000..844ddf4 --- /dev/null +++ b/theme/packages/main/src/assets/scss/helpers/_variables.scss @@ -0,0 +1,102 @@ +@use "functions" as *; + +// Utility Map + +$utilities: () !default; + +// Spacing + +$spacer: 16px !default; +$spacers: ( + 0: 0, + 2: $spacer * 0.125, + 4: $spacer * 0.25, + 5: 5px, + 6: 7px, + 8: $spacer * 0.5, + 10: 10px, + 12: $spacer * 0.75, + 14: 14px, + 15: 15px, + 16: $spacer, + 20: 20px, + 24: $spacer * 1.5, + 30: 30px, + 32: $spacer * 2, + 44: 44px, + 48: $spacer * 3, + 60: 60px, + 66: 66px, + 80: 80px, +) !default; +$negative-spacers: negativify-map($spacers) !default; + +// Border + +$border-color: var(--mat-sys-outline-variant) !default; +$borders: ( + 0: 0, + 1: 1px solid $border-color, + 2: 2px solid $border-color, + 4: 4px solid $border-color, + 8: 8px solid $border-color, +) !default; + +// Border radius + +$radius-base: 7px !default; +$radius: ( + 0: 0, + 7: $radius-base, + 8: $radius-base * 2, + 12: $radius-base * 3, + 16: $radius-base * 4, + full: 9999px, +) !default; + +// Text + +$font-wieghts: ( + 100: 100, + 200: 200, + 300: 300, + 400: 400, + 500: 500, + 600: 600, + 700: 700, + 800: 800, + 900: 900, +) !default; + +$font-sizes: ( + 0: 0, + 10: 10px, + 12: 12px, + 14: 14px, + 15: 15px, + 16: 16px, + 18: 18px, + 20: 20px, + 21: 21px, + 24: 24px, + 28: 28px, + 30: 30px, + 36: 36px, + 40: 40px, + 48: 48px, +) !default; + +// Sizing + +$sizes: ( + 0: 0, + 20: 20%, + 25: 25%, + 40: 40%, + 50: 50%, + 60: 60%, + 75: 75%, + 80: 80%, + full: 100%, + auto: auto, +) !default; diff --git a/theme/packages/main/src/assets/scss/horizontal/_horizontal.scss b/theme/packages/main/src/assets/scss/horizontal/_horizontal.scss new file mode 100644 index 0000000..57658c5 --- /dev/null +++ b/theme/packages/main/src/assets/scss/horizontal/_horizontal.scss @@ -0,0 +1,208 @@ +@use "../variables" as *; + +.sidebarNav-horizontal { + .childBox { + background: var(--mat-sys-surface); + } + + // header + .horizontal-topbar { + box-shadow: var(--mat-sys-level2); + + .branding { + padding-left: 0; + } + + .container { + max-width: $boxedWidth; + display: flex; + align-items: center; + width: 100%; + } + } + + // sidebar + .horizontal-navbar { + position: relative; + gap: 3px !important; + + .parentBox { + position: relative; + z-index: 5; + margin: 5px 0; + + &.mega-menu { + position: static; + + &:hover { + >.childBox>.ddmenu { + display: inline-block; + } + } + + >.childBox { + width: 100%; + left: 0; + + >.ddmenu { + width: 24%; + } + } + } + + &.two-column { + &:hover { + >.childBox>.ddmenu { + display: inline-block; + } + } + + >.childBox { + width: 600px; + + >.ddmenu { + width: 49%; + border-radius: $border-radius; + } + } + } + + .menuLink { + padding: 10px; + border-radius: $border-radius; + display: flex; + align-items: center; + height: 40px; + gap: 10px; + font-size: 14px; + } + + &:hover>.menuLink { + background-color: var(--mat-sys-surface-bright); + } + + &:hover>.activeMenu, + .activeMenu { + color: $white !important; + background-color: $primary; + } + + .down-icon .mat-icon { + width: 18px; + height: 18px; + font-size: 18px; + } + + .childBox { + border-radius: $border-radius; + box-shadow: var(--mat-sys-level1); + position: absolute; + width: 250px; + background-color: var(--mat-sys-surface); + + .ddmenu { + display: none; + padding: 10px; + margin: 6px; + position: relative; + border-radius: $border-radius; + } + } + + &:hover>.childBox>.ddmenu:hover { + background-color: var(--mat-sys-surface-bright); + + &:hover>.childBox>.ddmenu:hover { + background-color: var(--mat-sys-surface-bright); + } + } + + &:hover>.childBox>.ddmenu:hover>.childBox { + left: 230px; + top: 0px; + z-index: 9; + + >.ddmenu:hover>.childBox { + left: 235px; + top: 0; + } + } + + &:hover>.childBox>.ddmenu { + display: block; + padding: 0; + + &:hover>.childBox>.ddmenu { + display: block; + padding: 0; + + &:hover>.childBox>.ddmenu { + display: block; + padding: 0; + } + } + } + } + } +} + +.sidebarNav-horizontal { + + .topbar, + .mainWrapper { + width: 100%; + } + + .horizontal-navbar { + .parentBox { + + &.pactive>a, + &.pactive>a:hover, + &.pactive:hover>a { + background-color: var(--mat-sys-primary); + color: $white !important; + border-radius: $border-radius; + } + } + } +} + +.ltr { + .sidebarNav-horizontal { + .horizontal-navbar { + .parentBox { + &:last-child:hover>.childBox>.ddmenu { + &:hover>.childBox { + right: 250px; + left: unset; + + >.ddmenu:hover>.childBox { + right: 250px; + left: unset; + } + } + } + } + } + } +} + +.rtl { + .sidebarNav-horizontal { + .horizontal-navbar { + .parentBox { + &:last-child:hover>.childBox>.ddmenu { + &:hover>.childBox { + left: 250px; + right: unset; + + >.ddmenu:hover>.childBox { + left: 250px; + right: unset; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/layouts/_breacrumb.scss b/theme/packages/main/src/assets/scss/layouts/_breacrumb.scss new file mode 100644 index 0000000..28a6c54 --- /dev/null +++ b/theme/packages/main/src/assets/scss/layouts/_breacrumb.scss @@ -0,0 +1,33 @@ +@use "../variables" as *; + +.breadcrumb-icon { + position: absolute; + top: -20px; + right: 19px; +} + +.breadcrumb { + list-style: none; + margin: 0; + padding: 0px; + display: flex; +} + +.breadcrumb-item { + padding: 0 10px 0 0; + + &:first-child { + &::marker { + display: none; + } + } + + a { + text-decoration: none; + font-size: 14px; + + &:hover { + color: $primary; + } + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/layouts/_customizer.scss b/theme/packages/main/src/assets/scss/layouts/_customizer.scss new file mode 100644 index 0000000..a0c58e5 --- /dev/null +++ b/theme/packages/main/src/assets/scss/layouts/_customizer.scss @@ -0,0 +1,118 @@ +@use "../variables" as *; + +html .customizerNav { + border-radius: 0px !important; + width: 100%; +} + +.customizer-button-group { + &.two-row { + display: inline-block; + + &.theme-colors { + .mat-button-toggle-appearance-standard { + margin-left: 16px; + + &:first-child { + margin-left: 0; + } + } + } + + .mat-button-toggle-appearance-standard { + width: 80px; + height: 65px; + float: left; + display: flex; + align-items: center; + margin-bottom: 16px; + + .mat-button-toggle-button { + display: flex; + justify-content: center; + } + + &:nth-child(4) { + margin-left: 0; + } + + &.mat-button-toggle-checked { + .theme-circle { + .theme-icon { + display: flex; + color: $white; + } + } + } + + .theme-circle { + width: 25px; + height: 25px; + border-radius: var(--mat-sys-corner-full); + color: $white; + display: flex; + align-items: center; + justify-content: center; + + .theme-icon { + display: none; + } + + &.orange_theme { + background-color: rgb(250, 137, 107); + } + + &.blue_theme { + background-color: rgb(93, 135, 255); + } + + &.aqua_theme { + background-color: rgb(0, 116, 186); + } + + &.purple_theme { + background-color: rgb(118, 62, 189); + } + + &.green_theme { + background-color: rgb(10, 126, 164); + } + + &.cyan_theme { + background-color: rgb(1, 192, 200); + } + } + } + } + + .mat-button-toggle-appearance-standard { + padding: 9px; + border: 1px solid var(--mat-sys-outline-variant) !important; + box-shadow: none; + border-radius: $border-radius; + transition: all 0.1s ease-in 0s; + + &:hover { + transform: scale(1.05); + } + + &.mat-button-toggle-checked { + background-color: var(--mat-sys-primary-fixed-dim); + + i-tabler.fill-icon { + color: var(--mat-sys-primary); + fill: var(--mat-sys-on-primary); + } + } + } + + &.mat-button-toggle-group { + overflow: unset; + border-radius: 0; + } + + .mat-button-toggle-standalone.mat-button-toggle-appearance-standard, + &.mat-button-toggle-group-appearance-standard { + border: 0 !important; + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/layouts/_header.scss b/theme/packages/main/src/assets/scss/layouts/_header.scss new file mode 100644 index 0000000..d24e1f8 --- /dev/null +++ b/theme/packages/main/src/assets/scss/layouts/_header.scss @@ -0,0 +1,64 @@ +@use "../variables" as *; + +html .topbar { + position: sticky; + top: 0; + z-index: 9; + height: $header-height; + + .notification-badge{ + .mat-badge-content{ + left: 80%; + bottom: 85%; + width: 16px; + height: 16px; + } + } +} + +.topbar-dd { + min-width: 360px !important; +} + +.apps-dd { + min-width: 830px !important; + overflow: unset !important; + + .mat-mdc-menu-content { + padding: 0; + } +} + +.text-hover-primary:hover { + .hover-text { + color: $primary; + } +} + +.upgrade-bg { + position: absolute; + top: 0px; + right: 0px; + height: 100%; +} + +.object-cover { + object-fit: cover; +} + +.profile-dd { + margin-top: -5px; + margin-left: -5px; +} + +.dark-theme { + .topbar { + .mat-mdc-icon-button { + color: $dark-text-secondary !important; + } + + .mdc-button { + --mat-button-text-label-text-color: $dark-text-secondary !important; + } + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/layouts/_layouts.scss b/theme/packages/main/src/assets/scss/layouts/_layouts.scss new file mode 100644 index 0000000..c56764a --- /dev/null +++ b/theme/packages/main/src/assets/scss/layouts/_layouts.scss @@ -0,0 +1,4 @@ +@use "sidebar"; +@use "header"; +@use "customizer"; +@use "breacrumb"; \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/layouts/_sidebar.scss b/theme/packages/main/src/assets/scss/layouts/_sidebar.scss new file mode 100644 index 0000000..1c9c1f8 --- /dev/null +++ b/theme/packages/main/src/assets/scss/layouts/_sidebar.scss @@ -0,0 +1,210 @@ +@use "../variables" as *; + +.mat-drawer.sidebarNav { + width: $sidenav-desktop; + flex-shrink: 0; + transition: swift-ease-out(width); + position: absolute; + overflow-x: hidden; + border-right: 1px solid $borderColor; + border-radius: 0px !important; +} + +.branding { + padding: 20px; +} + +.sidebarNav-mini { + .sidebarNav { + width: $sidenav-mini; + + .profile-bar { + display: none; + } + + .sidebar-list { + .menu-list-item { + padding: 8px 17px; + + .mdc-list-item__content { + display: none; + } + + .mdc-list-item__start { + margin-left: 6px !important; + margin-right: 8px !important; + } + } + } + + &:hover { + width: $sidenav-desktop; + + .profile-bar { + display: block; + } + + .sidebar-list { + .menu-list-item { + padding: 8px 10px; + + .mdc-list-item__content { + display: inline; + } + + .mdc-list-item__start { + margin-left: 0 !important; + } + } + + &.mdc-list { + padding: 0 24px; + max-width: $sidenav-desktop; + + .mdc-list-group__subheader { + text-align: left; + } + } + } + } + } + + .hideMenu { + overflow: hidden; + width: $sidenav-mini; + } + + .branding { + width: $sidenav-mini - 15px; + overflow: hidden; + } + + .sidebar-list { + &.mdc-list { + padding: 0 12px; + + .mdc-list-group__subheader { + text-align: center; + } + } + } + + .contentWrapper { + transition: swift-ease-out(width); + } +} + +@media (min-width: 1024px) { + .sidebarNav-mini { + .contentWrapper { + margin-left: $sidenav-mini !important; + } + } +} + +.customizerBtn { + position: fixed; + right: 30px; + bottom: 30px; + z-index: 9; +} + +.sidebar-list { + &.mdc-list { + padding: 0 24px; + + .mdc-list-group__subheader { + margin: 12px 0; + text-transform: uppercase; + font-size: 0.75rem; + font-weight: 700; + margin-top: 24px; + } + + .menu-list-item { + height: 45px; + padding: 8px 10px !important; + margin-bottom: 2px; + + &.twoline { + height: 60px; + align-items: center; + } + + &:before, + &:focus { + z-index: -1; + } + + &.disabled { + opacity: 0.38; + } + + .item-chip { + height: 24px; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; + } + + &.activeMenu { + background-color: var(--mat-sys-primary); + + .mdc-list-item__primary-text { + color: $white !important; + } + + .mat-mdc-list-item-icon { + color: $white !important; + } + } + + .mdc-list-item__start { + margin-right: 14px; + margin-left: 0 !important; + width: 20px; + height: 20px; + line-height: 0px; + fill: transparent !important; + } + + .mdc-list-item__primary-text { + display: flex; + align-items: center; + justify-content: space-between; + + .arrow-icon { + display: flex; + + .mat-icon { + font-size: 18px; + width: 18px; + height: 18px; + display: flex; + align-items: center; + justify-content: center; + } + } + } + } + } +} + +.sidebar-list .top-parent .menu-list-item.activemenu { + background-color: color-mix(in srgb, var(--mat-sys-primary) 10%, transparent); + + .mdc-list-item__primary-text { + color: var(--mat-sys-primary) !important; + } + + .mat-mdc-list-item-icon { + color: var(--mat-sys-primary) !important; + } +} + +.flex-layout { + display: flex; + flex-direction: column; + height: 100%; +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/layouts/_transitions.scss b/theme/packages/main/src/assets/scss/layouts/_transitions.scss new file mode 100644 index 0000000..fdc42bc --- /dev/null +++ b/theme/packages/main/src/assets/scss/layouts/_transitions.scss @@ -0,0 +1,17 @@ +$swift-ease-out-duration: 400ms; +$swift-ease-out-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1); + +@function swift-ease-out($property) { + // The Material default animation curves. + $transition: $property $swift-ease-out-duration + $swift-ease-out-timing-function; + + @return $transition; +} + +@function fast-out-slow($property) { + // The Material default animation curves. + $transition: $property 225ms cubic-bezier(0.4, 0, 0.2, 1); + + @return $transition; +} diff --git a/theme/packages/main/src/assets/scss/override-component/_autocomplete.scss b/theme/packages/main/src/assets/scss/override-component/_autocomplete.scss new file mode 100644 index 0000000..c93ff43 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_autocomplete.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.autocomplete-overrides( + ( + container-elevation-shadow: var(--mat-sys-level2), + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_badge.scss b/theme/packages/main/src/assets/scss/override-component/_badge.scss new file mode 100644 index 0000000..cb94c06 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_badge.scss @@ -0,0 +1,7 @@ +@use "sass:map"; +@use "@angular/material" as mat; +@include mat.badge-overrides( + ( + background-color: var(--mat-sys-primary), + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_button-toggle.scss b/theme/packages/main/src/assets/scss/override-component/_button-toggle.scss new file mode 100644 index 0000000..bdd2d6d --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_button-toggle.scss @@ -0,0 +1,9 @@ +@use "sass:map"; +@use "@angular/material" as mat; +@use "../variables" as *; + +@include mat.button-toggle-overrides( + ( + shape: $border-radius, + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_button.scss b/theme/packages/main/src/assets/scss/override-component/_button.scss new file mode 100644 index 0000000..f85ed5a --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_button.scss @@ -0,0 +1,136 @@ +@use "sass:map"; +@use "@angular/material" as mat; +@use "../variables" as *; + +@include mat.button-overrides( + ( + protected-hover-container-elevation-shadow: var(--mat-sys-level1), + filled-horizontal-padding: 15px, + outlined-horizontal-padding: 15px, + protected-horizontal-padding: 15px, + text-horizontal-padding: 15px, + filled-container-shape: var(--mat-sys-corner-small), + outlined-container-shape: var(--mat-sys-corner-small), + protected-container-shape: var(--mat-sys-corner-small), + text-container-shape: var(--mat-sys-corner-small), + ) +); + +@include mat.icon-button-overrides( + ( + icon-color: $text-color, + ) +); + +// styles +html { + .mat-mdc-button-base.bg-light-primary:hover, + .mat-mdc-button-base.bg-light-secondary:hover, + .mat-mdc-button-base.bg-light-error:hover, + .mat-mdc-button-base.bg-light-warning:hover, + .mat-mdc-button-base.bg-light-success:hover { + color: $white !important; + } + + .mat-mdc-button-base.bg-light-primary { + &:hover { + background-color: var(--mat-sys-primary) !important; + } + } + + .mat-mdc-button-base.bg-light-secondary { + &:hover { + background-color: var(--mat-sys-secondary) !important; + } + } + + .mat-mdc-button-base.bg-light-error { + &:hover { + background-color: var(--mat-sys-error) !important; + } + } + + .mat-mdc-button-base.bg-light-warning { + &:hover { + background-color: $warning !important; + } + } + + .mat-mdc-button-base.bg-light-success { + &:hover { + background-color: $success !important; + } + } + + .mat-mdc-outlined-button:not(:disabled) { + border-color: inherit !important; + } + + .mat-mdc-button-base.text-secondary:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $secondary; + } + } + + .mat-mdc-button-base.text-error:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $error; + } + } + + .mat-mdc-button-base.text-warning:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $warning; + } + } + + .mat-mdc-button-base.text-success:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $success; + } + } + + .mat-mdc-outlined-button:not(:disabled).mat-secondary { + color: var(--mat-sys-secondary); + border-color: var(--mat-sys-secondary); + + &:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $secondary; + } + } + } + + .mat-mdc-outlined-button:not(:disabled).mat-success { + color: $success; + border-color: $success; + + &:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $success; + } + } + } + + .mat-mdc-outlined-button:not(:disabled).mat-error { + color: $error; + border-color: $error; + + &:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $error; + } + } + } + + .mat-mdc-outlined-button:not(:disabled).mat-warning { + color: $warning; + border-color: $warning; + + &:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $warning; + } + } + } +} diff --git a/theme/packages/main/src/assets/scss/override-component/_card.scss b/theme/packages/main/src/assets/scss/override-component/_card.scss new file mode 100644 index 0000000..660e579 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_card.scss @@ -0,0 +1,60 @@ +@use "sass:map"; +@use "@angular/material" as mat; +@use "../variables" as *; + +@include mat.card-overrides( + ( + elevated-container-color: $white, + title-text-size: 1.125rem, + subtitle-text-size: 14px, + title-text-line-height: 1.6rem, + title-text-weight: 600, + subtitle-text-weight: 400, + elevated-container-shape: var(--mat-sys-corner-small), + outlined-container-shape: var(--mat-sys-corner-small), + elevated-container-elevation: var(--mat-sys-level2), + ) +); + +// styles +html { + .mat-mdc-card { + margin-bottom: $card-spacer; + + .mat-mdc-card-header { + padding: $card-spacer $card-spacer 0 !important; + } + + .mat-mdc-card-header + .mat-mdc-card-content { + padding: 0 $card-spacer $card-spacer; + } + + > .mat-mdc-card-content { + padding: $card-spacer !important; + } + + .mdc-card__actions { + padding: $card-spacer !important; + } + } + + .card-hover { + transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &:hover { + scale: 1.01; + transition: all 0.1s ease-in 0s; + } + } + + .cardBorder { + .mdc-card { + box-shadow: none !important; + border: 1px solid $borderColor !important; + + &.shadow-none { + border: 0 !important; + } + } + } +} diff --git a/theme/packages/main/src/assets/scss/override-component/_checkbox.scss b/theme/packages/main/src/assets/scss/override-component/_checkbox.scss new file mode 100644 index 0000000..eba7679 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_checkbox.scss @@ -0,0 +1,23 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.checkbox-overrides( + ( + unselected-focus-icon-color: + var(--mat-checkbox-unselected-hover-state-layer-color), + ) +); + +// styles +html { + .mdc-checkbox__background { + border-radius: 4px; + width: 21px; + height: 21px; + border: 1px solid var(--mat-sys-outline); + } + + .mdc-checkbox .mdc-checkbox__native-control:focus ~ .mdc-checkbox__ripple { + background-color: var(--mat-checkbox-unselected-hover-state-layer-color); + } +} diff --git a/theme/packages/main/src/assets/scss/override-component/_chip.scss b/theme/packages/main/src/assets/scss/override-component/_chip.scss new file mode 100644 index 0000000..6aabfd0 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_chip.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.chips-overrides( + ( + focus-state-layer-color: var(--mat-option-focus-state-layer-color), + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_datepicker.scss b/theme/packages/main/src/assets/scss/override-component/_datepicker.scss new file mode 100644 index 0000000..2686873 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_datepicker.scss @@ -0,0 +1,11 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.datepicker-overrides( + ( + calendar-container-background-color: + var(--mat-card-elevated-container-color), + calendar-container-touch-elevation-shadow: var(--mat-sys-level1), + calendar-container-elevation-shadow: var(--mat-sys-level1), + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_dialog.scss b/theme/packages/main/src/assets/scss/override-component/_dialog.scss new file mode 100644 index 0000000..1dee46e --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_dialog.scss @@ -0,0 +1,15 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.dialog-overrides( + ( + container-shape: var(--mat-sys-corner-small), + subhead-size: 18px, + subhead-weight: 600, + content-padding: 20px 24px, + actions-padding: 20px 24px, + container-min-width: 300px, + subhead-tracking: unset, + supporting-text-tracking: unset, + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_drawer.scss b/theme/packages/main/src/assets/scss/override-component/_drawer.scss new file mode 100644 index 0000000..1ed3a41 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_drawer.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.sidenav-overrides( + ( + container-shape: 0, + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_expansion.scss b/theme/packages/main/src/assets/scss/override-component/_expansion.scss new file mode 100644 index 0000000..0c5f781 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_expansion.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.expansion-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_fab.scss b/theme/packages/main/src/assets/scss/override-component/_fab.scss new file mode 100644 index 0000000..77b39ed --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_fab.scss @@ -0,0 +1,15 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.fab-overrides( + ( + small-container-shape: 30px, + container-shape: 30px, + container-elevation-shadow: none, + small-container-elevation-shadow: none, + small-hover-container-elevation-shadow: var(--mat-sys-level3), + hover-container-elevation-shadow: var(--mat-sys-level3), + extended-hover-container-elevation-shadow: var(--mat-sys-level3), + extended-container-elevation-shadow: none, + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_form-field.scss b/theme/packages/main/src/assets/scss/override-component/_form-field.scss new file mode 100644 index 0000000..a1eda9b --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_form-field.scss @@ -0,0 +1,27 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.form-field-overrides( + ( + container-height: 37px, + outlined-container-shape: var(--mat-sys-corner-small), + container-vertical-padding: 6px, + ) +); + +// forms +html { + .hide-hint { + .mat-mdc-form-field-subscript-wrapper { + display: none; + } + } + + .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label { + top: calc(var(--mat-form-field-container-height) / 2.15); + } + + .demo-inline-calendar-card { + width: 300px; + } +} diff --git a/theme/packages/main/src/assets/scss/override-component/_index.scss b/theme/packages/main/src/assets/scss/override-component/_index.scss new file mode 100644 index 0000000..aa0a651 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_index.scss @@ -0,0 +1,23 @@ +@use "autocomplete"; +@use "badge"; +@use "button"; +@use "button-toggle"; +@use "card"; +@use "checkbox"; +@use "chip"; +@use "dialog"; +@use "datepicker"; +@use "fab"; +@use "form-field"; +@use "radio"; +@use "list"; +@use "menu"; +@use "paginator"; +@use "theme"; +@use "table"; +@use "tree"; +@use "typography"; +@use "stepper"; +@use "expansion"; +@use "drawer"; +@use "progress"; \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/override-component/_list.scss b/theme/packages/main/src/assets/scss/override-component/_list.scss new file mode 100644 index 0000000..de39959 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_list.scss @@ -0,0 +1,12 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.list-overrides( + ( + list-item-hover-state-layer-color: var(--mat-sys-primary), + list-item-container-shape: var(--mat-sys-corner-small), + active-indicator-shape: var(--mat-sys-corner-small), + list-item-two-line-container-height: 70px, + list-item-three-line-container-height: 100px, + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_menu.scss b/theme/packages/main/src/assets/scss/override-component/_menu.scss new file mode 100644 index 0000000..32a6e73 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_menu.scss @@ -0,0 +1,19 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.menu-overrides( + ( + container-shape: var(--mat-sys-corner-small), + ) +); + +// styles +html { + .mat-mdc-menu-panel { + box-shadow: var(--mat-sys-level3) !important; + } + + .mat-mdc-select-panel { + padding: 8px !important; + } +} diff --git a/theme/packages/main/src/assets/scss/override-component/_paginator.scss b/theme/packages/main/src/assets/scss/override-component/_paginator.scss new file mode 100644 index 0000000..35479e7 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_paginator.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.paginator-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_progress.scss b/theme/packages/main/src/assets/scss/override-component/_progress.scss new file mode 100644 index 0000000..5fb08d0 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_progress.scss @@ -0,0 +1,7 @@ +html { + .mat-secondary { + .mdc-linear-progress__bar-inner { + border-color: var(--mat-sys-secondary); + } + } +} diff --git a/theme/packages/main/src/assets/scss/override-component/_radio.scss b/theme/packages/main/src/assets/scss/override-component/_radio.scss new file mode 100644 index 0000000..2433356 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_radio.scss @@ -0,0 +1,14 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.radio-overrides( + ( + unselected-icon-color: var(--mat-sys-outline-variant), + ) +); + +html { + .mat-mdc-radio-button .mdc-radio__outer-circle { + border-width: 1px; + } +} diff --git a/theme/packages/main/src/assets/scss/override-component/_stepper.scss b/theme/packages/main/src/assets/scss/override-component/_stepper.scss new file mode 100644 index 0000000..6a21bd4 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_stepper.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.stepper-overrides( + ( + container-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_table.scss b/theme/packages/main/src/assets/scss/override-component/_table.scss new file mode 100644 index 0000000..379ddcd --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_table.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.table-overrides( + ( + background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_theme.scss b/theme/packages/main/src/assets/scss/override-component/_theme.scss new file mode 100644 index 0000000..e840626 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_theme.scss @@ -0,0 +1,25 @@ +@use "sass:map"; +@use "@angular/material" as mat; +@use "../variables" as *; + +html { + @include mat.theme( + ( + color: mat.$azure-palette, + typography: $font-family, + ) + ); + + @include mat.theme-overrides( + ( + primary: rgb(93, 135, 255), + error: rgb(250, 137, 107), + body-medium-size: 14px, + body-large-size: 14px, + outline-variant: #d7dde2, + level1: 0px 12px 24px -4px rgb(145 158 171 / 30%), + level2: rgba(145, 158, 171, 0.12) 0px 1px 16px, + level3: 0px 12px 24px -4px rgb(145 158 171 / 30%), + ) + ); +} diff --git a/theme/packages/main/src/assets/scss/override-component/_tree.scss b/theme/packages/main/src/assets/scss/override-component/_tree.scss new file mode 100644 index 0000000..e755adc --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_tree.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.tree-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/main/src/assets/scss/override-component/_typography.scss b/theme/packages/main/src/assets/scss/override-component/_typography.scss new file mode 100644 index 0000000..c65fc04 --- /dev/null +++ b/theme/packages/main/src/assets/scss/override-component/_typography.scss @@ -0,0 +1,9 @@ +@use "../variables" as *; +html { + .mdc-list-item__primary-text, + .mat-drawer-container, + .mat-drawer, + .text-body { + color: $text-color; + } +} diff --git a/theme/packages/main/src/assets/scss/pages/_auth.scss b/theme/packages/main/src/assets/scss/pages/_auth.scss new file mode 100644 index 0000000..1b51841 --- /dev/null +++ b/theme/packages/main/src/assets/scss/pages/_auth.scss @@ -0,0 +1,109 @@ +@use "../variables" as *; + +.blank-layout-container { + height: 100vh; + display: flex; + background-size: cover; + align-items: center; +} + +.auth-title { + font-size: 36px; + line-height: 44px; +} + +.bg-gredient { + &::before { + content: ""; + position: absolute; + height: 100%; + width: 100%; + opacity: 0.3; + background: radial-gradient(rgb(210, 241, 223), + rgb(211, 215, 250), + rgb(186, 216, 244)) 0% 0% / 400% 400%; + animation: 15s ease 0s infinite normal none running gradient; + z-index: -1; + } +} + +@keyframes gradient { + 0% { + background-position: 0% 50%; + } + + 50% { + background-position: 100% 50%; + } + + 100% { + background-position: 50% 0%; + } +} + +.img-height { + height: calc(100vh - 83px); +} + +.custom-row { + &.row { + margin-right: -8px; + margin-left: -8px; + + .col-2, + .col-12 { + padding-right: 8px; + padding-left: 8px; + } + } +} + +.or-border { + position: relative; + text-align: center; + + &:before { + content: ""; + position: absolute; + left: 0; + width: 120px; + top: 50%; + height: 1px; + background: var(--mat-sys-outline); + } + + &:after { + content: ""; + position: absolute; + right: 0; + width: 120px; + top: 50%; + height: 1px; + background: var(--mat-sys-outline); + } +} + +.boxed-auth { + width: 100%; + max-width: 480px; + margin: 0 auto; +} + +.max-width-form { + max-width: 450px; +} + +.mat-mdc-form-field.mat-form-field-invalid { + + .mdc-notched-outline__leading, + .mdc-notched-outline__notch, + .mdc-notched-outline__trailing { + border-color: $error !important; + } +} + +.error-msg { + position: absolute; + top: -19px; + right: 3px; +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/pages/_dashboards.scss b/theme/packages/main/src/assets/scss/pages/_dashboards.scss new file mode 100644 index 0000000..796c344 --- /dev/null +++ b/theme/packages/main/src/assets/scss/pages/_dashboards.scss @@ -0,0 +1,126 @@ +@use "../variables" as *; + +.social-chips { + img { + margin-left: -9px; + border: 2px solid $white; + + &:first-child { + margin-left: 0; + } + } +} + +.minus-img { + margin-bottom: -65px !important; +} + +// theme select +.theme-select { + width: 145px; +} + +// dashboard 2 +.welcome-img { + margin-bottom: -82px; + margin-top: -9px; +} + +.timeline { + position: relative; + + .timeline-item { + position: relative; + height: 70px; + + .time { + padding: 6px 16px 6px 0; + min-width: 90px; + flex-shrink: 0; + } + + .desc { + padding: 6px 16px; + } + + .timline-border { + width: 1px; + height: 100%; + background-color: $borderColor; + flex-shrink: 0; + } + + .point { + flex-direction: column; + + .timeline-badge { + width: 12px; + height: 12px; + border-radius: 50px; + background-color: transparent; + flex-shrink: 0; + + &.border-primary { + border: 2px solid $primary; + } + + &.border-accent { + border: 2px solid $accent; + } + + &.border-success { + border: 2px solid $success; + } + + &.border-warning { + border: 2px solid $warning; + } + + &.border-error { + border: 2px solid $error; + } + } + + .timeline-border { + width: 1px; + height: 100%; + background-color: $borderColor; + flex-shrink: 0; + } + } + + &:last-child { + .timeline-border { + display: none !important; + } + } + } +} + +// expansion panel + +html .mat-expansion-panel:not([class*="mat-elevation-z"]) { + box-shadow: var(--mat-sys-level2); +} + +.most-visit-chart { + .apexcharts-bar-series.apexcharts-plot-series .apexcharts-series path { + clip-path: inset(0 0 5% 0 round 20px); + } +} + + +// User Profile Tab +.profileTabs { + background-color: var(--mat-sys-surface-bright); + + .mat-mdc-tab-label-container{ + border-bottom-width: 0; + } + + .mat-mdc-tab.mdc-tab-indicator--active{ + .mdc-tab__text-label{ + color: var(--mat-sys-primary) !important; + } + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/pages/_frontend.scss b/theme/packages/main/src/assets/scss/pages/_frontend.scss new file mode 100644 index 0000000..db45c10 --- /dev/null +++ b/theme/packages/main/src/assets/scss/pages/_frontend.scss @@ -0,0 +1,143 @@ +.front-topbar { + &.fixed-topbar { + position: fixed; + top: 0; + width: 100%; + background-color: var(--mat-sys-background) !important; + z-index: 9; + } +} + +.back-to-top { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 999; + transition: opacity 0.3s ease; +} + +.tab-header { + + .profileTabs { + + .mat-mdc-tab { + padding: 30px 16px; + height: auto; + border-right: 1px solid var(--mat-sys-outline); + + &:last-child { + border-right: 0; + } + } + + .mat-mdc-tab-label-container { + border-top-width: 0; + } + } + +} + +.home-page .expansion-panel .mat-expansion-panel-body { + padding: 16px 0; +} + +.faq-accordion { + .mat-expansion-panel-body { + padding: 16px 24px !important; + } +} + +.mobile-sidebar { + .mdc-list { + .mdc-list-item { + .mat-mdc-button { + color: var(--mat-sys-on-background); + min-width: 100%; + justify-content: flex-start; + + &.selected { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); + transition: background-color 0.3s ease; + } + } + } + } +} + + +.spacing-top-bottom { + padding: 80px 0; +} + +.spacing-left-right { + padding: 0 80px; +} + +.spacing-left { + padding-left: 80px; +} + +.spacing-top { + padding-top: 80px; +} + +.spacing-bottom { + padding-bottom: 80px; +} + +@media (max-width: 959px) { + .section-sub-title { + font-size: 30px !important; + } + + .spacing-top-bottom { + padding: 60px 0; + } + + .spacing-left-right { + padding: 0 60px; + } + + .spacing-left { + padding-left: 60px; + } + + .spacing-top { + padding-top: 60px; + } + + .spacing-bottom { + padding-bottom: 60px; + } +} + +@media (max-width: 767px) { + .section-sub-title { + font-size: 24px !important; + } + + .spacing-top-bottom { + padding: 30px 0; + } + + .spacing-left-right { + padding: 0 30px; + } + + .spacing-left { + padding-left: 30px; + } + + .spacing-top { + padding-top: 30px; + } + + .spacing-bottom { + padding-bottom: 30px; + } + + .footer-content .left-side-content { + padding: 30px !important; + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/pages/_landingpage.scss b/theme/packages/main/src/assets/scss/pages/_landingpage.scss new file mode 100644 index 0000000..7b20efe --- /dev/null +++ b/theme/packages/main/src/assets/scss/pages/_landingpage.scss @@ -0,0 +1,244 @@ +@use "../variables" as *; + +.demos-dd { + max-width: $boxedWidth !important; +} + +.img-overlay { + position: relative; + border: 1px solid var(--mat-sys-outline); + .overlay-content { + display: none; + } + + &:hover { + &:before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 8; + background-color: rgba(55, 114, 255, 0.2); + border-radius: $border-radius; + } + + .overlay-content { + display: flex; + position: absolute; + top: 0; + z-index: 9; + align-items: center; + justify-content: center; + height: 100%; + width: 100%; + } + } +} + +.topbar-xl { + height: 80px; + z-index: 1; +} + +// ---------------------------------------------------------- +// banner +// ---------------------------------------------------------- +@media (min-width: 900px) { + .banner-title { + font-size: 54px !important; + line-height: 60px !important; + } +} + +@media (max-width: 1200px) { + .banner-section { + padding-top: 60px; + } +} + +.banner-title { + font-size: 36px; + line-height: 44px; +} + +.banner-subtitle { + line-height: 25px; +} + +.btn-custom { + height: 56px !important; + padding: 0 52px !important; + font-size: 16px; + + &.sm { + padding: 0 34px !important; + } +} + +@media (max-width: 767px) { + .btn-custom { + padding: 0 36px !important; + } +} + +.banner-slider { + background-color: $light-primary; + min-width: 2000px; + height: calc(100vh - 100px); + max-height: 790px; + border-radius: $border-radius; + overflow: hidden; +} + +.slider-img { + animation: slideup 35s linear infinite; +} + +.slider-img2 { + animation: slidedown 35s linear infinite; +} + +@keyframes slideup { + 0% { + transform: translate3d(0, 0, 0); + } + + 100% { + transform: translate3d(0px, -100%, 0px); + } +} + +@keyframes slidedown { + 0% { + transform: translate3d(0, -100%, 0); + } + + 100% { + transform: translate3d(0px, 0, 0px); + } +} + +// sections + +.spacer { + padding: 80px 0 100px; +} + +.section-title { + font-size: 28px; + line-height: 32px; +} + +@media (min-width: 991px) { + .section-title { + font-size: 36px; + line-height: 43px; + } +} + +// demo slider +.demo-slider { + margin-top: 40px; + + .demo-slide { + animation: slide 45s linear infinite; + } +} + +@keyframes slide { + 0% { + transform: translate3d(0, 0, 0); + } + + 100% { + transform: translate3d(-100%, 0, 0); + } +} + +.lh-base { + line-height: 1.75; +} + +// call to action + +.shape-card { + background-repeat: no-repeat; + background-position: center center; + overflow: hidden; +} + +.spacer-sm { + padding-top: 60px; + padding-bottom: 30px; +} + +.spacer-bottom { + padding-bottom: 60px; +} + +.section-title2 { + font-size: 30px; + line-height: 36px; + font-weight: 700; +} + +.c2a-card { + margin-top: -70px; + background-repeat: no-repeat; + background-position: center; +} + +.border-white { + border: 1px solid $white !important; +} + +.border-accent { + border: 1px solid $accent !important; +} + +.border-primary { + border: 1px solid $primary !important; +} + +.hstack { + display: flex; + flex-direction: row; + gap: 20px; +} + +@media (max-width: 767px) { + .hstack { + flex-direction: column; + } + + .bg-size-cover { + background-size: cover; + } +} + +.shapes-component { + &::before { + content: ""; + position: absolute; + left: 0; + bottom: -32px; + width: 388px; + height: 382px; + z-index: -1; + background-image: url(/assets/images/shapes/shape-2.svg); + background-repeat: no-repeat; + } + &::after { + content: ""; + position: absolute; + top: -125px; + right: -96px; + width: 267px; + height: 252px; + z-index: -1; + background-image: url(/assets/images/shapes/shape-1.svg); + background-repeat: no-repeat; + } +} diff --git a/theme/packages/main/src/assets/scss/pages/_pricing.scss b/theme/packages/main/src/assets/scss/pages/_pricing.scss new file mode 100644 index 0000000..920e5ad --- /dev/null +++ b/theme/packages/main/src/assets/scss/pages/_pricing.scss @@ -0,0 +1,33 @@ +.plan-title { + font-size: 50px; + margin-top: 40px; + line-height: 50px; + font-weight: 600; +} + +.dollar-sign { + margin-top: 22px; + margin-right: 8px; +} + +.per-month { + margin-top: 45px; + margin-left: 12px; +} + +.popular-badge { + position: absolute; + right: 16px; +} + +// widget cards + +.text-decoration-line-through { + text-decoration: line-through; +} + +.cart-btn { + position: absolute; + right: 16px; + top: -21px; +} diff --git a/theme/packages/main/src/assets/scss/pages/_toast.scss b/theme/packages/main/src/assets/scss/pages/_toast.scss new file mode 100644 index 0000000..6c8461c --- /dev/null +++ b/theme/packages/main/src/assets/scss/pages/_toast.scss @@ -0,0 +1,24 @@ +@use "../variables" as *; + +html { + .toast-success { + background-color: $success; + } + + .toast-error { + background-color: $error; + } + + .toast-warning { + background-color: $warning; + } + + .toast-info { + background-color: $primary; + } + + .toast-container .ngx-toastr { + box-shadow: var(--mat-sys-level2); + border-radius: $border-radius; + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/rtl/_rtl.scss b/theme/packages/main/src/assets/scss/rtl/_rtl.scss new file mode 100644 index 0000000..aaefab6 --- /dev/null +++ b/theme/packages/main/src/assets/scss/rtl/_rtl.scss @@ -0,0 +1,99 @@ +@use "../variables" as *; + +[dir="rtl"] { + +.mat-drawer.mat-drawer-end { + transform: translate3d(0, 0, 0); + &.mat-drawer-opened { + transform: none !important; + } +} + + // ------------------------------------------------------ + // header + // ------------------------------------------------------ + .upgrade-bg { + left: 0; + right: unset; + transform: scaleX(-1); + } + + // highlight + td.hljs-ln-line.hljs-ln-numbers { + padding-left: 10px; + padding-right: 0; + } + + // customizer + .customizerBtn { + left: 30px; + right: unset; + } + + // logo flip + .branding img { + transform: scaleX(-1); + } + + .breadcrumb-icon { + left: 19px; + right: unset; + } + + .breadcrumb-item { + &:first-child { + margin-left: 0; + margin-right: -20px; + } + + &.active { + margin-left: 0; + margin-right: 20px; + } + } + + // sidebar + + .mat-drawer.sidebarNav { + border-left: 1px solid var(--mat-sys-outline-variant); + border-right: 0; + } + + .sidebar-list.mdc-list .menu-list-item .mdc-list-item__start { + margin-right: 0 !important; + margin-left: 14px !important; + } + + // minisidebar + &.sidebarNav-mini { + .contentWrapper { + margin-right: $sidenav-mini !important; + margin-left: 0 !important; + transition: swift-ease-out(width); + } + + .sidebarNav { + + // sidebar + .sidebar-list { + .menu-list-item { + .mdc-list-item__start { + margin-right: 8px !important; + margin-left: 7px !important; + } + } + } + + &:hover { + .sidebar-list { + .menu-list-item { + .mdc-list-item__start { + margin-right: 0 !important; + margin-left: 16px !important; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/style.scss b/theme/packages/main/src/assets/scss/style.scss new file mode 100644 index 0000000..177d3f7 --- /dev/null +++ b/theme/packages/main/src/assets/scss/style.scss @@ -0,0 +1,51 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@use "themecolors/blue_theme"; +@use "themecolors/orange_theme"; +@use "themecolors/aqua_theme"; +@use "themecolors/cyan_theme"; +@use "themecolors/green_theme"; +@use "themecolors/purple_theme"; + +@use "variables" as *; +@use "override-component"; +@use "theme-variables/default-variables"; +@use "theme-variables/light-theme-variables"; +@use "theme-variables/dark-theme-variables"; + +//container layout +@use "layouts/transitions"; +@use "helpers/color"; +@use "helpers/border-color"; +@use "helpers/icon-size"; +@use "container"; +@use "layouts/layouts"; +@use "grid/grid"; +@use "helpers/custom-flex"; +@use "helpers"; + +// horizontal +@use "horizontal/horizontal"; +@use "dark/dark"; + +// apps +@use "apps/calendar"; +@use "apps/email"; +@use "apps/blogs"; +@use "apps/chat"; +@use "apps/contact-list"; +@use "apps/kanban"; +@use "apps/courses"; +@use "apps/todo"; +@use "apps/ecommerce"; + +@use "pages/auth"; +@use "pages/dashboards"; +@use "pages/landingpage"; +@use "pages/toast"; +@use "pages/pricing"; +@use "pages/frontend"; + +// RTL Theme +@use "rtl/rtl"; \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/theme-variables/_dark-theme-variables.scss b/theme/packages/main/src/assets/scss/theme-variables/_dark-theme-variables.scss new file mode 100644 index 0000000..0375fc4 --- /dev/null +++ b/theme/packages/main/src/assets/scss/theme-variables/_dark-theme-variables.scss @@ -0,0 +1,32 @@ +@use "@angular/material" as mat; + +html.dark-theme { + color-scheme: dark; + --mat-sys-background: #141a21; + --mat-sys-on-background: rgba(255, 255, 255, 0.9); + --mat-sys-on-primary: #fff; + --mat-sys-surface-bright: #ffffff05; + --mat-sys-surface: #141a21; + --mat-sys-surface-container: #141a21; + --mat-sys-surface-container-low: #141a21; + --mat-sys-outline-variant: #2e3f50; + --mat-sys-outline: #2e3f50; + --mat-form-field-outlined-hover-outline-color: #465670; + --mat-checkbox-unselected-hover-state-layer-color: #19212a; + --mat-menu-item-hover-state-layer-color: #19212a; + --mat-button-toggle-state-layer-color: #19212a; + --mat-option-focus-state-layer-color: #19212a; + --mat-option-hover-state-layer-color: #19212a; + --mat-slide-toggle-unselected-track-color: #19212a; + --mat-stepper-header-focus-state-layer-color: #19212a; + --mat-stepper-header-hover-state-layer-color: #19212a; + --mat-expansion-header-hover-state-layer-color: #19212a; + @include mat.card-overrides((elevated-container-color: #1c252e, + elevated-container-elevation: rgba(0, 0, 0, 0.2) 0px 0px 2px 0px, + subtitle-text-color: rgba(255, 255, 255, 0.67), + )); + @include mat.theme-overrides((level1: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level2: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level3: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + )); +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/theme-variables/_default-variables.scss b/theme/packages/main/src/assets/scss/theme-variables/_default-variables.scss new file mode 100644 index 0000000..e3adeb2 --- /dev/null +++ b/theme/packages/main/src/assets/scss/theme-variables/_default-variables.scss @@ -0,0 +1,12 @@ +html { + --mat-sys-error-fixed-dim: rgba(247, 68, 86, 0.15); + --mat-select-container-elevation-shadow: var(--mat-sys-level3); + --mat-list-list-item-label-text-tracking: 0; + --mat-slide-toggle-track-height: 28px; + --mat-sidenav-container-divider-color: var(--mat-sys-outline-variant); + --mat-dialog-with-actions-content-padding: 20px 24px; + --mat-form-field-container-text-tracking: unset; + --mat-slide-toggle-with-icon-handle-size: 21px; + --mat-badge-text-color: white; + --mat-slide-toggle-selected-with-icon-handle-horizontal-margin: 0 26px; +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/theme-variables/_light-theme-variables.scss b/theme/packages/main/src/assets/scss/theme-variables/_light-theme-variables.scss new file mode 100644 index 0000000..735309e --- /dev/null +++ b/theme/packages/main/src/assets/scss/theme-variables/_light-theme-variables.scss @@ -0,0 +1,23 @@ +html.light-theme { + color-scheme: light; + --mat-sys-corner-small: 7px; + --mat-sys-background: #fff; + --mat-sys-surface-bright: #f2f6fa; + --mat-sys-surface: #fff; + --mat-sys-surface-container: #fff; + --mat-sys-surface-container-low: #fff; + --mat-sys-on-background: #2a3547; + --mat-sys-outline: #d7dde2; + --mat-sys-outline-variant: #d7dde2; + --mat-form-field-outlined-hover-outline-color: #d7dde2; + --mat-checkbox-unselected-hover-state-layer-color: #d7dde2; + --mat-menu-item-hover-state-layer-color: #f6f9fc; + --mat-button-toggle-state-layer-color: #f6f9fc; + --mat-option-focus-state-layer-color: #f6f9fc; + --mat-option-hover-state-layer-color: #f6f9fc; + --mat-slide-toggle-unselected-track-color: #f6f9fc; + --mat-stepper-header-focus-state-layer-color: #f6f9fc; + --mat-stepper-header-hover-state-layer-color: #f6f9fc; + --mat-dialog-supporting-text-color: var(--mat-sys-on-background); + --mat-expansion-header-hover-state-layer-color: #f6f9fc; + } \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/themecolors/_aqua_theme.scss b/theme/packages/main/src/assets/scss/themecolors/_aqua_theme.scss new file mode 100644 index 0000000..185291b --- /dev/null +++ b/theme/packages/main/src/assets/scss/themecolors/_aqua_theme.scss @@ -0,0 +1,7 @@ +html.aqua_theme { + --mat-sys-primary: rgb(0, 116, 186); + --mat-sys-primary-fixed-dim: rgb(0, 116, 186, 0.15); + --mat-sys-secondary: rgb(71, 215, 188); + --mat-sys-secondary-fixed-dim: rgb(71, 215, 188, 0.15); + --mat-sys-tertiary: rgb(71, 215, 188); +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/themecolors/_blue_theme.scss b/theme/packages/main/src/assets/scss/themecolors/_blue_theme.scss new file mode 100644 index 0000000..b34c0bd --- /dev/null +++ b/theme/packages/main/src/assets/scss/themecolors/_blue_theme.scss @@ -0,0 +1,6 @@ +html.blue_theme { + --mat-sys-primary: rgb(93, 135, 255); + --mat-sys-primary-fixed-dim: rgb(93, 135, 255, 0.15); + --mat-sys-secondary: rgb(68, 183, 247); + --mat-sys-secondary-fixed-dim: rgb(68, 183, 247, 0.15); +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/themecolors/_cyan_theme.scss b/theme/packages/main/src/assets/scss/themecolors/_cyan_theme.scss new file mode 100644 index 0000000..7dea9b0 --- /dev/null +++ b/theme/packages/main/src/assets/scss/themecolors/_cyan_theme.scss @@ -0,0 +1,7 @@ +html.cyan_theme { + --mat-sys-primary: rgb(0, 185, 192); + --mat-sys-primary-fixed-dim: rgb(0, 185, 192, 0.15); + --mat-sys-secondary: rgb(244, 139, 108); + --mat-sys-secondary-fixed-dim: rgb(244, 139, 108, 0.15); + --mat-sys-tertiary: rgb(244, 139, 108); +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/themecolors/_green_theme.scss b/theme/packages/main/src/assets/scss/themecolors/_green_theme.scss new file mode 100644 index 0000000..d80c4b8 --- /dev/null +++ b/theme/packages/main/src/assets/scss/themecolors/_green_theme.scss @@ -0,0 +1,7 @@ +html.green_theme { + --mat-sys-primary: rgb(6, 118, 154); + --mat-sys-primary-fixed-dim: rgb(6, 118, 154, 0.15); + --mat-sys-secondary: rgb(195, 208, 70); + --mat-sys-secondary-fixed-dim: rgb(195, 208, 70, 0.15); + --mat-sys-tertiary: rgb(195, 208, 70); +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/themecolors/_orange_theme.scss b/theme/packages/main/src/assets/scss/themecolors/_orange_theme.scss new file mode 100644 index 0000000..20bed3b --- /dev/null +++ b/theme/packages/main/src/assets/scss/themecolors/_orange_theme.scss @@ -0,0 +1,7 @@ +html.orange_theme { + --mat-sys-primary: rgb(250, 137, 107); + --mat-sys-primary-fixed-dim: rgb(250, 137, 107, 0.15); + --mat-sys-secondary: rgb(0, 127, 180); + --mat-sys-secondary-fixed-dim: rgb(0, 127, 180, 0.15); + --mat-sys-error-fixed-dim: rgba(247, 68, 86, 0.15); +} \ No newline at end of file diff --git a/theme/packages/main/src/assets/scss/themecolors/_purple_theme.scss b/theme/packages/main/src/assets/scss/themecolors/_purple_theme.scss new file mode 100644 index 0000000..1476625 --- /dev/null +++ b/theme/packages/main/src/assets/scss/themecolors/_purple_theme.scss @@ -0,0 +1,7 @@ +html.purple_theme { + --mat-sys-primary: rgb(110, 53, 183); + --mat-sys-primary-fixed-dim: rgb(110, 53, 183, 0.15); + --mat-sys-secondary: rgb(139, 200, 206); + --mat-sys-secondary-fixed-dim: rgb(139, 200, 206, 0.15); + --mat-sys-tertiary: rgb(139, 200, 206); +} \ No newline at end of file diff --git a/theme/packages/main/src/favicon.ico b/theme/packages/main/src/favicon.ico new file mode 100644 index 0000000..997406a Binary files /dev/null and b/theme/packages/main/src/favicon.ico differ diff --git a/theme/packages/main/src/index.html b/theme/packages/main/src/index.html new file mode 100644 index 0000000..344a5f2 --- /dev/null +++ b/theme/packages/main/src/index.html @@ -0,0 +1,17 @@ + + + + + Modernize Angular 20 Admin Template + + + + + + + + + + + \ No newline at end of file diff --git a/theme/packages/main/src/main.ts b/theme/packages/main/src/main.ts new file mode 100644 index 0000000..514c89a --- /dev/null +++ b/theme/packages/main/src/main.ts @@ -0,0 +1,7 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err) +); diff --git a/theme/packages/main/src/styles.scss b/theme/packages/main/src/styles.scss new file mode 100644 index 0000000..7e7239a --- /dev/null +++ b/theme/packages/main/src/styles.scss @@ -0,0 +1,4 @@ +/* You can add global styles to this file, and also import other style files */ + +html, body { height: 100%; } +body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } diff --git a/theme/packages/main/tsconfig.app.json b/theme/packages/main/tsconfig.app.json new file mode 100644 index 0000000..374cc9d --- /dev/null +++ b/theme/packages/main/tsconfig.app.json @@ -0,0 +1,14 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/theme/packages/main/tsconfig.json b/theme/packages/main/tsconfig.json new file mode 100644 index 0000000..c3587c1 --- /dev/null +++ b/theme/packages/main/tsconfig.json @@ -0,0 +1,34 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "strictPropertyInitialization": false, + "lib": [ + "ES2022", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true, + } +} diff --git a/theme/packages/main/tsconfig.spec.json b/theme/packages/main/tsconfig.spec.json new file mode 100644 index 0000000..be7e9da --- /dev/null +++ b/theme/packages/main/tsconfig.spec.json @@ -0,0 +1,14 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/theme/packages/minisidebar/angular.json b/theme/packages/minisidebar/angular.json new file mode 100644 index 0000000..0f19c10 --- /dev/null +++ b/theme/packages/minisidebar/angular.json @@ -0,0 +1,126 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "Modernize": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "allowedCommonJsDependencies": ["apexcharts", "bezier-easing", "chance"], + "outputPath": { + "base": "dist/Modernize" + }, + "index": "src/index.html", + "polyfills": ["zone.js"], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": [ + + "src/styles.scss", + "src/assets/scss/style.scss", + "node_modules/ngx-toastr/toastr.css", + "node_modules/angular-calendar/css/angular-calendar.css", + "node_modules/highlight.js/styles/atom-one-dark.min.css" + ], + "scripts": [], + "browser": "src/main.ts" + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "12mb", + "maximumError": "12mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "12mb", + "maximumError": "12mb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "Modernize:build:production" + }, + "development": { + "buildTarget": "Modernize:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular/build:extract-i18n", + "options": { + "buildTarget": "Modernize:build" + } + }, + "test": { + "builder": "@angular/build:karma", + "options": { + "polyfills": ["zone.js", "zone.js/testing"], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], + "scripts": [] + } + } + } + } + }, + "cli": { + "analytics": false + }, + "schematics": { + "@schematics/angular:component": { + "type": "component" + }, + "@schematics/angular:directive": { + "type": "directive" + }, + "@schematics/angular:service": { + "type": "service" + }, + "@schematics/angular:guard": { + "typeSeparator": "." + }, + "@schematics/angular:interceptor": { + "typeSeparator": "." + }, + "@schematics/angular:module": { + "typeSeparator": "." + }, + "@schematics/angular:pipe": { + "typeSeparator": "." + }, + "@schematics/angular:resolver": { + "typeSeparator": "." + } + } +} diff --git a/theme/packages/minisidebar/package.json b/theme/packages/minisidebar/package.json new file mode 100644 index 0000000..51d6f74 --- /dev/null +++ b/theme/packages/minisidebar/package.json @@ -0,0 +1,62 @@ +{ + "name": "modernize", + "version": "3.1.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^20.0.4", + "@angular/cdk": "^20.0.3", + "@angular/common": "^20.0.4", + "@angular/compiler": "^20.0.4", + "@angular/core": "^20.0.4", + "@angular/forms": "^20.0.4", + "@angular/material": "^20.0.3", + "@angular/platform-browser": "^20.0.4", + "@angular/platform-browser-dynamic": "^20.0.4", + "@angular/router": "^20.0.4", + "@ng-matero/extensions": "^20.1.0", + "@ngx-translate/core": "^16.0.4", + "@ngx-translate/http-loader": "^16.0.1", + "angular-calendar": "^0.31.1", + "angular-tabler-icons": "^3.26.0", + "apexcharts": "^4.7.0", + "chance": "^1.1.13", + "date-fns": "^4.1.0", + "highlight.js": "^11.11.1", + "ng-apexcharts": "^1.16.0", + "ng2-search-filter": "^0.5.1", + "ngx-dropzone": "^3.1.0", + "ngx-editor": "^19.0.0-beta.1", + "ngx-highlightjs": "^14.0.1", + "ngx-owl-carousel-o": "^20.0.0", + "ngx-pagination": "^6.0.3", + "ngx-permissions": "^19.0.0", + "ngx-scrollbar": "^18.0.0", + "ngx-toastr": "^19.0.0", + "rxjs": "~7.8.2", + "sass": "^1.89.2", + "tslib": "^2.8.1", + "zone.js": "~0.15.1" + }, + "devDependencies": { + "@angular/build": "^20.0.3", + "@angular/cli": "~20.0.3", + "@angular/compiler-cli": "^20.0.4", + "@types/chance": "^1.1.6", + "@types/date-fns": "^2.6.3", + "@types/jasmine": "~5.1.8", + "jasmine-core": "~5.8.0", + "karma": "~6.4.4", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.1", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.8.3" + } +} diff --git a/theme/packages/minisidebar/src/app/app.routes.ts b/theme/packages/minisidebar/src/app/app.routes.ts new file mode 100644 index 0000000..f1bf19f --- /dev/null +++ b/theme/packages/minisidebar/src/app/app.routes.ts @@ -0,0 +1,107 @@ +import { Routes } from '@angular/router'; +import { BlankComponent } from './layouts/blank/blank.component'; +import { FullComponent } from './layouts/full/full.component'; + +export const routes: Routes = [ + { + path: '', + component: FullComponent, + children: [ + { + path: '', + redirectTo: '/dashboards/dashboard1', + pathMatch: 'full', + }, + { + path: 'starter', + loadChildren: () => + import('./pages/pages.routes').then((m) => m.PagesRoutes), + }, + { + path: 'dashboards', + loadChildren: () => + import('./pages/dashboards/dashboards.routes').then( + (m) => m.DashboardsRoutes + ), + }, + + { + path: 'forms', + loadChildren: () => + import('./pages/forms/forms.routes').then((m) => m.FormsRoutes), + }, + { + path: 'charts', + loadChildren: () => + import('./pages/charts/charts.routes').then((m) => m.ChartsRoutes), + }, + { + path: 'apps', + loadChildren: () => + import('./pages/apps/apps.routes').then((m) => m.AppsRoutes), + }, + { + path: 'widgets', + loadChildren: () => + import('./pages/widgets/widgets.routes').then((m) => m.WidgetsRoutes), + }, + { + path: 'tables', + loadChildren: () => + import('./pages/tables/tables.routes').then((m) => m.TablesRoutes), + }, + { + path: 'datatable', + loadChildren: () => + import('./pages/datatable/datatable.routes').then( + (m) => m.DatatablesRoutes + ), + }, + { + path: 'theme-pages', + loadChildren: () => + import('./pages/theme-pages/theme-pages.routes').then( + (m) => m.ThemePagesRoutes + ), + }, + { + path: 'ui-components', + loadChildren: () => + import('./pages/ui-components/ui-components.routes').then( + (m) => m.UiComponentsRoutes + ), + }, + ], + }, + { + path: '', + component: BlankComponent, + children: [ + { + path: 'authentication', + loadChildren: () => + import('./pages/authentication/authentication.routes').then( + (m) => m.AuthenticationRoutes + ), + }, + { + path: 'landingpage', + loadChildren: () => + import('./pages/theme-pages/landingpage/landingpage.routes').then( + (m) => m.LandingPageRoutes + ), + }, + { + path: 'front-pages', + loadChildren: () => + import('./pages/front-pages/front-pages.routes').then( + (m) => m.FrontPagesRoutes + ), + }, + ], + }, + { + path: '**', + redirectTo: 'authentication/error', + }, +]; diff --git a/theme/packages/minisidebar/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html b/theme/packages/minisidebar/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html new file mode 100644 index 0000000..fa78891 --- /dev/null +++ b/theme/packages/minisidebar/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html @@ -0,0 +1,55 @@ + + + Yearly Breakup + + +
+
+

$36,358

+
+ +
+9%
+
last year
+
+ +
+
+ +
2025
+
+
+ +
2024
+
+
+
+
+ + + + +
+
+
+
diff --git a/theme/packages/minisidebar/src/app/config.ts b/theme/packages/minisidebar/src/app/config.ts new file mode 100644 index 0000000..c65cb27 --- /dev/null +++ b/theme/packages/minisidebar/src/app/config.ts @@ -0,0 +1,25 @@ +export interface AppSettings { + dir: 'ltr' | 'rtl'; + theme: string; + sidenavOpened: boolean; + sidenavCollapsed: boolean; + boxed: boolean; + horizontal: boolean; + activeTheme: string; + language: string; + cardBorder: boolean; + navPos: 'side' | 'top'; +} + +export const defaults: AppSettings = { + dir: 'ltr', + theme: 'light', + sidenavOpened: false, + sidenavCollapsed: true, + boxed: true, + horizontal: false, + cardBorder: false, + activeTheme: 'blue_theme', + language: 'en-us', + navPos: 'side', +}; \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/layouts/full/full.component.html b/theme/packages/minisidebar/src/app/layouts/full/full.component.html new file mode 100644 index 0000000..2ffaeb5 --- /dev/null +++ b/theme/packages/minisidebar/src/app/layouts/full/full.component.html @@ -0,0 +1,197 @@ + + + + + + @if (!options.horizontal) { + +
+ + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+
+ } + + + + + @if (resView) { + + + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+ } + + + + + + + + + @if (!options.horizontal) { + + } @else { + + + } @if(options.horizontal) { + + } + +
+ + + + + +
+ +
+
+ + +
+
+
+
+ @if(options.theme === 'light') { + + logo + + } @else { + + logo + + } +
+ +
+ + + + + Apps + +
+
+ @for(appdd of apps; track appdd.img) { + + } +
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+ + +
+
+
+ + +
+

Settings

+ +
+ + + +
+
+
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/layouts/full/full.component.ts b/theme/packages/minisidebar/src/app/layouts/full/full.component.ts new file mode 100644 index 0000000..459faac --- /dev/null +++ b/theme/packages/minisidebar/src/app/layouts/full/full.component.ts @@ -0,0 +1,284 @@ +import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout'; +import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { MatSidenav, MatSidenavContent } from '@angular/material/sidenav'; +import { CoreService } from 'src/app/services/core.service'; +import { AppSettings } from 'src/app/config'; +import { filter } from 'rxjs/operators'; +import { NavigationEnd, Router } from '@angular/router'; +import { navItems } from './vertical/sidebar/sidebar-data'; +import { NavService } from '../../services/nav.service'; +import { AppNavItemComponent } from './vertical/sidebar/nav-item/nav-item.component'; +import { RouterModule } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { SidebarComponent } from './vertical/sidebar/sidebar.component'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { HeaderComponent } from './vertical/header/header.component'; +import { AppHorizontalHeaderComponent } from './horizontal/header/header.component'; +import { AppHorizontalSidebarComponent } from './horizontal/sidebar/sidebar.component'; +import { AppBreadcrumbComponent } from './shared/breadcrumb/breadcrumb.component'; +import { CustomizerComponent } from './shared/customizer/customizer.component'; + +const MOBILE_VIEW = 'screen and (max-width: 768px)'; +const TABLET_VIEW = 'screen and (min-width: 769px) and (max-width: 1024px)'; +const MONITOR_VIEW = 'screen and (min-width: 1024px)'; +const BELOWMONITOR = 'screen and (max-width: 1023px)'; + +// for mobile app sidebar +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +@Component({ + selector: 'app-full', + imports: [ + RouterModule, + AppNavItemComponent, + MaterialModule, + CommonModule, + SidebarComponent, + NgScrollbarModule, + TablerIconsModule, + HeaderComponent, + AppHorizontalHeaderComponent, + AppHorizontalSidebarComponent, + AppBreadcrumbComponent, + CustomizerComponent, + ], + templateUrl: './full.component.html', + + encapsulation: ViewEncapsulation.None +}) +export class FullComponent implements OnInit { + navItems = navItems; + + + + @ViewChild('leftsidenav') + public sidenav: MatSidenav; + resView = false; + @ViewChild('content', { static: true }) content!: MatSidenavContent; + //get options from service + options = this.settings.getOptions(); + private layoutChangesSubscription = Subscription.EMPTY; + private isMobileScreen = false; + private isContentWidthFixed = true; + private isCollapsedWidthFixed = false; + private htmlElement!: HTMLHtmlElement; + + get isOver(): boolean { + return this.isMobileScreen; + } + + get isTablet(): boolean { + return this.resView; + } + + // for mobile app sidebar + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/apps/chat', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'Todo App', + subtitle: 'Completed task', + link: '/apps/todo', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/apps/invoice', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/apps/calendar', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/apps/contacts', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/apps/tickets', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/apps/email/inbox', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Courses', + subtitle: 'Create new course', + link: '/apps/courses', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/theme-pages/pricing', + }, + { + id: 2, + title: 'Authentication Design', + link: '/authentication/login', + }, + { + id: 3, + title: 'Register Now', + link: '/authentication/side-register', + }, + { + id: 4, + title: '404 Error Page', + link: '/authentication/error', + }, + { + id: 5, + title: 'Notes App', + link: '/apps/notes', + }, + { + id: 6, + title: 'Employee App', + link: '/apps/employee', + }, + { + id: 7, + title: 'Todo Application', + link: '/apps/todo', + }, + { + id: 8, + title: 'Treeview', + link: '/theme-pages/treeview', + }, + ]; + + constructor( + private settings: CoreService, + private mediaMatcher: MediaMatcher, + private router: Router, + private breakpointObserver: BreakpointObserver, + private navService: NavService, private cdr: ChangeDetectorRef + ) { + this.htmlElement = document.querySelector('html')!; + this.layoutChangesSubscription = this.breakpointObserver + .observe([MOBILE_VIEW, TABLET_VIEW, MONITOR_VIEW, BELOWMONITOR]) + .subscribe((state) => { + // SidenavOpened must be reset true when layout changes + this.options.sidenavOpened = true; + this.isMobileScreen = state.breakpoints[BELOWMONITOR]; + if (this.options.sidenavCollapsed == false) { + this.options.sidenavCollapsed = state.breakpoints[TABLET_VIEW]; + } + this.isContentWidthFixed = state.breakpoints[MONITOR_VIEW]; + this.resView = state.breakpoints[BELOWMONITOR]; + }); + + // Initialize project theme with options + this.receiveOptions(this.options); + + // This is for scroll to top + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .subscribe((e) => { + this.content.scrollTo({ top: 0 }); + }); + } + + isFilterNavOpen = false; + + toggleFilterNav() { + this.isFilterNavOpen = !this.isFilterNavOpen; + console.log('Sidebar open:', this.isFilterNavOpen); + this.cdr.detectChanges(); // Ensures Angular updates the view + } + + ngOnInit(): void {} + + ngOnDestroy() { + this.layoutChangesSubscription.unsubscribe(); + } + + toggleCollapsed() { + this.isContentWidthFixed = false; + this.options.sidenavCollapsed = !this.options.sidenavCollapsed; + this.resetCollapsedState(); + } + + resetCollapsedState(timer = 400) { + setTimeout(() => this.settings.setOptions(this.options), timer); + } + + onSidenavClosedStart() { + this.isContentWidthFixed = false; + } + + onSidenavOpenedChange(isOpened: boolean) { + this.isCollapsedWidthFixed = !this.isOver; + this.options.sidenavOpened = isOpened; + this.settings.setOptions(this.options); + } + + receiveOptions(options: AppSettings): void { + this.toggleDarkTheme(options); + this.toggleColorsTheme(options); + } + + toggleDarkTheme(options: AppSettings) { + if (options.theme === 'dark') { + this.htmlElement.classList.add('dark-theme'); + this.htmlElement.classList.remove('light-theme'); + } else { + this.htmlElement.classList.remove('dark-theme'); + this.htmlElement.classList.add('light-theme'); + } + } + + toggleColorsTheme(options: AppSettings) { + // Remove any existing theme class dynamically + this.htmlElement.classList.forEach((className) => { + if (className.endsWith('_theme')) { + this.htmlElement.classList.remove(className); + } + }); + + // Add the selected theme class + this.htmlElement.classList.add(options.activeTheme); + } +} diff --git a/theme/packages/minisidebar/src/app/layouts/full/horizontal/header/header.component.html b/theme/packages/minisidebar/src/app/layouts/full/horizontal/header/header.component.html new file mode 100644 index 0000000..f076a2c --- /dev/null +++ b/theme/packages/minisidebar/src/app/layouts/full/horizontal/header/header.component.html @@ -0,0 +1,296 @@ + +
+
+ +
+ + + + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/minisidebar/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts b/theme/packages/minisidebar/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts new file mode 100644 index 0000000..3bdf202 --- /dev/null +++ b/theme/packages/minisidebar/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts @@ -0,0 +1,633 @@ +import { NavItem } from '../../vertical/sidebar/nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Dashboards', + iconName: 'home', + route: 'dashboards', + children: [ + { + displayName: 'Analytical', + iconName: 'point', + route: 'dashboards/dashboard1', + }, + { + displayName: 'eCommerce', + iconName: 'point', + route: 'dashboards/dashboard2', + }, + ], + }, + { + displayName: 'Frontend pages', + iconName: 'app-window', + route: 'front-pages', + children: [ + { + displayName: 'Home Page', + iconName: 'point', + route: 'front-pages/homepage', + } , + { + displayName: 'About Us', + iconName: 'point', + route: 'front-pages/about', + } , + { + displayName: 'Blog', + iconName: 'point', + route: 'front-pages/blog', + } , + { + displayName: 'Blog Details', + iconName: 'point', + route: 'front-pages/blog-details', + } , + { + displayName: 'Portfolio', + iconName: 'point', + route: 'front-pages/portfolio', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'front-pages/pricing', + }, + { + displayName: 'Contact', + iconName: 'point', + route: 'front-pages/contact', + } + ] + }, + { + displayName: 'Apps', + iconName: 'apps', + route: 'apps', + ddType: '', + children: [ + { + displayName: 'Chat', + iconName: 'point', + route: 'apps/chat', + }, + { + displayName: 'Calendar', + iconName: 'point', + route: 'apps/calendar', + }, + { + displayName: 'Email', + iconName: 'point', + route: 'apps/email/inbox', + }, + { + displayName: 'Contacts', + iconName: 'point', + route: 'apps/contacts', + }, + { + displayName: 'Contact List', + iconName: 'point', + route: 'apps/contact-list', + }, + { + displayName: 'Courses', + iconName: 'point', + route: 'apps/courses', + }, + { + displayName: 'Employee', + iconName: 'point', + route: 'apps/employee', + }, + { + displayName: 'Notes', + iconName: 'point', + route: 'apps/notes', + }, + { + displayName: 'Tickets', + iconName: 'point', + route: 'apps/tickets', + }, + { + displayName: 'Invoice', + iconName: 'point', + route: 'apps/invoice', + }, + { + displayName: 'ToDo', + iconName: 'point', + route: 'apps/todo', + }, + { + displayName: 'Kanban', + iconName: 'point', + route: 'apps/kanban', + }, + { + displayName: 'Blog', + iconName: 'point', + route: 'apps/blog', + children: [ + { + displayName: 'Post', + iconName: 'point', + route: 'apps/blog/post', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + }, + ], + }, + { + displayName: 'User Profile', + iconName: 'point', + route: 'apps/profile-details', + children: [ + { + displayName: 'Profile', + iconName: 'point', + route: 'apps/profile-details/profile', + }, + { + displayName: 'Followers', + iconName: 'point', + route: 'apps/profile-details/followers', + }, + { + displayName: 'Friends', + iconName: 'point', + route: 'apps/profile-details/friends', + }, + { + displayName: 'Gellary', + iconName: 'point', + route: 'apps/profile-details/gallery', + }, + ], + }, + { + displayName: 'Ecommerce', + iconName: 'point', + route: 'apps/product', + children: [ + { + displayName: 'Product List', + iconName: 'point', + route: 'apps/product/product-list', + }, + { + displayName: 'Add Product', + iconName: 'point', + route: 'apps/product/add-product', + }, + { + displayName: 'Edit Product', + iconName: 'point', + route: 'apps/product/edit-product', + }, + { + displayName: 'Shop', + iconName: 'point', + route: 'apps/product/shop', + }, + ], + }, + ], + }, + { + displayName: 'Ui', + iconName: 'components', + route: 'ui-components', + ddType: '', + children: [ + { + displayName: 'Badge', + iconName: 'point', + route: 'ui-components/badge', + }, + { + displayName: 'Expansion Panel', + iconName: 'point', + route: 'ui-components/expansion', + }, + { + displayName: 'Chips', + iconName: 'point', + route: 'ui-components/chips', + }, + { + displayName: 'Dialog', + iconName: 'point', + route: 'ui-components/dialog', + }, + { + displayName: 'Lists', + iconName: 'point', + route: 'ui-components/lists', + }, + { + displayName: 'Divider', + iconName: 'point', + route: 'ui-components/divider', + }, + { + displayName: 'Menu', + iconName: 'point', + route: 'ui-components/menu', + }, + { + displayName: 'Paginator', + iconName: 'point', + route: 'ui-components/paginator', + }, + { + displayName: 'Progress Bar', + iconName: 'point', + route: 'ui-components/progress', + }, + { + displayName: 'Progress Spinner', + iconName: 'point', + route: 'ui-components/progress-spinner', + }, + { + displayName: 'Ripples', + iconName: 'point', + route: 'ui-components/ripples', + }, + { + displayName: 'Slide Toggle', + iconName: 'point', + route: 'ui-components/slide-toggle', + }, + { + displayName: 'Slider', + iconName: 'point', + route: 'ui-components/slider', + }, + { + displayName: 'Snackbar', + iconName: 'point', + route: 'ui-components/snackbar', + }, + { + displayName: 'Tabs', + iconName: 'point', + route: 'ui-components/tabs', + }, + { + displayName: 'Toolbar', + iconName: 'point', + route: 'ui-components/toolbar', + }, + { + displayName: 'Tooltips', + iconName: 'point', + route: 'ui-components/tooltips', + }, + ], + }, + { + displayName: 'Pages', + iconName: 'clipboard', + route: 'theme-pages', + ddType: '', + children: [ + { + displayName: 'Treeview', + iconName: 'point', + route: 'theme-pages/treeview', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'theme-pages/pricing', + }, + { + displayName: 'Account Setting', + iconName: 'point', + route: 'theme-pages/account-setting', + }, + { + displayName: 'FAQ', + iconName: 'point', + route: 'theme-pages/faq', + }, + { + displayName: 'Landingpage', + iconName: 'point', + route: 'landingpage', + }, + { + displayName: 'Widgets', + iconName: 'point', + route: 'widgets', + children: [ + { + displayName: 'Cards', + iconName: 'point', + route: 'widgets/cards', + }, + { + displayName: 'Banners', + iconName: 'point', + route: 'widgets/banners', + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'widgets/charts', + }, + ], + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'charts', + children: [ + { + displayName: 'Line', + iconName: 'point', + route: '/charts/line', + }, + { + displayName: 'Gredient', + iconName: 'point', + route: '/charts/gredient', + }, + { + displayName: 'Area', + iconName: 'point', + route: '/charts/area', + }, + { + displayName: 'Candlestick', + iconName: 'point', + route: '/charts/candlestick', + }, + { + displayName: 'Column', + iconName: 'point', + route: '/charts/column', + }, + { + displayName: 'Doughnut & Pie', + iconName: 'point', + route: '/charts/doughnut-pie', + }, + { + displayName: 'Radialbar & Radar', + iconName: 'point', + route: '/charts/radial-radar', + }, + ], + }, + { + displayName: 'Auth', + iconName: 'point', + route: '/', + children: [ + { + displayName: 'Login', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/login', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-login', + }, + ], + }, + { + displayName: 'Register', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/side-register', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-register', + }, + ], + }, + { + displayName: 'Forgot Password', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Side Forgot Password', + iconName: 'point', + route: '/authentication/side-forgot-pwd', + }, + { + displayName: 'Boxed Forgot Password', + iconName: 'point', + route: '/authentication/boxed-forgot-pwd', + }, + ], + }, + { + displayName: 'Two Steps', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Side Two Steps', + iconName: 'point', + route: '/authentication/side-two-steps', + }, + { + displayName: 'Boxed Two Steps', + iconName: 'point', + route: '/authentication/boxed-two-steps', + }, + ], + }, + { + displayName: 'Error', + iconName: 'point', + route: '/authentication/error', + }, + { + displayName: 'Maintenance', + iconName: 'point', + route: '/authentication/maintenance', + }, + ], + }, + ], + }, + { + displayName: 'Forms', + iconName: 'file-description', + route: 'forms', + ddType: '', + children: [ + { + displayName: 'Form elements', + iconName: 'point', + route: 'forms/forms-elements', + children: [ + { + displayName: 'Autocomplete', + iconName: 'point', + route: 'forms/forms-elements/autocomplete', + }, + { + displayName: 'Button', + iconName: 'point', + route: 'forms/forms-elements/button', + }, + { + displayName: 'Checkbox', + iconName: 'point', + route: 'forms/forms-elements/checkbox', + }, + { + displayName: 'Radio', + iconName: 'point', + route: 'forms/forms-elements/radio', + }, + { + displayName: 'Datepicker', + iconName: 'point', + route: 'forms/forms-elements/datepicker', + }, + ], + }, + { + displayName: 'Form Layouts', + iconName: 'point', + route: '/forms/form-layouts', + }, + { + displayName: 'Form Horizontal', + iconName: 'point', + route: '/forms/form-horizontal', + }, + { + displayName: 'Form Vertical', + iconName: 'point', + route: '/forms/form-vertical', + }, + { + displayName: 'Form Wizard', + iconName: 'point', + route: '/forms/form-wizard', + }, + { + displayName: 'Toastr', + iconName: 'point', + route: '/forms/form-toastr', + }, + { + displayName: 'Editor', + iconName: 'point', + route: '/forms/form-editor', + }, + ], + }, + { + displayName: 'Tables', + iconName: 'layout', + route: 'tables', + ddType: '', + children: [ + { + displayName: 'Basic Table', + iconName: 'point', + route: 'tables/basic-table', + }, + { + displayName: 'Dynamic Table', + iconName: 'point', + route: 'tables/dynamic-table', + }, + { + displayName: 'Expand Table', + iconName: 'point', + route: 'tables/expand-table', + }, + { + displayName: 'Filterable Table', + iconName: 'point', + route: 'tables/filterable-table', + }, + { + displayName: 'Footer Row Table', + iconName: 'point', + route: 'tables/footer-row-table', + }, + { + displayName: 'HTTP Table', + iconName: 'point', + route: 'tables/http-table', + }, + { + displayName: 'Mix Table', + iconName: 'point', + route: 'tables/mix-table', + }, + { + displayName: 'Multi Header Footer', + iconName: 'point', + route: 'tables/multi-header-footer-table', + }, + { + displayName: 'Pagination Table', + iconName: 'point', + route: 'tables/pagination-table', + }, + { + displayName: 'Row Context Table', + iconName: 'point', + route: 'tables/row-context-table', + }, + { + displayName: 'Selection Table', + iconName: 'point', + route: 'tables/selection-table', + }, + { + displayName: 'Sortable Table', + iconName: 'point', + route: 'tables/sortable-table', + }, + { + displayName: 'Sticky Column', + iconName: 'point', + route: 'tables/sticky-column-table', + }, + { + displayName: 'Sticky Header Footer', + iconName: 'point', + route: 'tables/sticky-header-footer-table', + }, + { + displayName: 'Data table', + iconName: 'point', + route: '/datatable/kichen-sink', + }, + ], + }, +]; diff --git a/theme/packages/minisidebar/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts b/theme/packages/minisidebar/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts new file mode 100644 index 0000000..f0e13f5 --- /dev/null +++ b/theme/packages/minisidebar/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts @@ -0,0 +1,48 @@ +import { + Component, + OnInit, + Input, + ChangeDetectorRef, + OnChanges, +} from '@angular/core'; +import { navItems } from './sidebar-data'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../services/nav.service'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { AppHorizontalNavItemComponent } from './nav-item/nav-item.component'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-horizontal-sidebar', + imports: [AppHorizontalNavItemComponent, CommonModule], + templateUrl: './sidebar.component.html', +}) +export class AppHorizontalSidebarComponent implements OnInit { + navItems = navItems; + parentActive = ''; + + mobileQuery: MediaQueryList; + private _mobileQueryListener: () => void; + + constructor( + public navService: NavService, + public router: Router, + media: MediaMatcher, + changeDetectorRef: ChangeDetectorRef + ) { + this.mobileQuery = media.matchMedia('(min-width: 1100px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + this.router.events.subscribe( + () => (this.parentActive = this.router.url.split('/')[1]) + ); + } + + ngOnInit(): void { + this.parentActive = this.router.url.split('/')[1]; + + this.router.events.subscribe(() => { + this.parentActive = this.router.url.split('/')[1]; + }); + } +} diff --git a/theme/packages/minisidebar/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts b/theme/packages/minisidebar/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts new file mode 100644 index 0000000..3cf2292 --- /dev/null +++ b/theme/packages/minisidebar/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { Router, NavigationEnd, ActivatedRoute, Data } from '@angular/router'; +import { filter, map, mergeMap } from 'rxjs/operators'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-breadcrumb', + imports: [RouterModule, TablerIconsModule], + templateUrl: './breadcrumb.component.html', + styleUrls: [] +}) +export class AppBreadcrumbComponent { + // @Input() layout; + pageInfo: Data | any = Object.create(null); + myurl: any = this.router.url.slice(1).split('/'); + constructor( + private router: Router, + private activatedRoute: ActivatedRoute, + private titleService: Title + ) { + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .pipe(map(() => this.activatedRoute)) + .pipe( + map((route) => { + while (route.firstChild) { + route = route.firstChild; + } + return route; + }) + ) + .pipe(filter((route) => route.outlet === 'primary')) + .pipe(mergeMap((route) => route.data)) + // tslint:disable-next-line - Disables all + .subscribe((event) => { + // tslint:disable-next-line - Disables all + this.titleService.setTitle(event['title'] + ' - Angular 20'); + this.pageInfo = event; + }); + } +} diff --git a/theme/packages/minisidebar/src/app/layouts/full/vertical/header/header.component.html b/theme/packages/minisidebar/src/app/layouts/full/vertical/header/header.component.html new file mode 100644 index 0000000..3949a30 --- /dev/null +++ b/theme/packages/minisidebar/src/app/layouts/full/vertical/header/header.component.html @@ -0,0 +1,301 @@ + + + + @if(showToggle) { + + } + + + @if(!showToggle) { + + } + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently + Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ + @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/minisidebar/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts b/theme/packages/minisidebar/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts new file mode 100644 index 0000000..3782536 --- /dev/null +++ b/theme/packages/minisidebar/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts @@ -0,0 +1,103 @@ +import { + Component, + HostBinding, + Input, + OnInit, + OnChanges, + Output, + EventEmitter, +} from '@angular/core'; +import { NavItem } from './nav-item'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../../services/nav.service'; +import { + animate, + state, + style, + transition, + trigger, +} from '@angular/animations'; +import { TranslateModule } from '@ngx-translate/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-nav-item', + imports: [TranslateModule, TablerIconsModule, MaterialModule, CommonModule], + templateUrl: './nav-item.component.html', + styleUrls: [], + animations: [ + trigger('indicatorRotate', [ + state('collapsed', style({ transform: 'rotate(0deg)' })), + state('expanded', style({ transform: 'rotate(180deg)' })), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4,0.0,0.2,1)')), + ]), + ] +}) +export class AppNavItemComponent implements OnChanges { + @Output() toggleMobileLink: any = new EventEmitter(); + @Output() notify: EventEmitter = new EventEmitter(); + + expanded: any = false; + disabled: any = false; + twoLines: any = false; + @HostBinding('attr.aria-expanded') ariaExpanded = this.expanded; + @Input() item: NavItem | any; + @Input() depth: any; + + constructor(public navService: NavService, public router: Router) { + if (this.depth === undefined) { + this.depth = 0; + } + } + + ngOnChanges() { + const url = this.navService.currentUrl(); + if (this.item.route && url) { + this.expanded = url.indexOf(`/${this.item.route}`) === 0; + this.ariaExpanded = this.expanded; + } + } + + onItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + this.router.navigate([item.route]); + + } + if (item.children && item.children.length) { + this.expanded = !this.expanded; + } + //scroll + window.scroll({ + top: 0, + left: 0, + behavior: 'smooth', + }); + if (!this.expanded) { + if (window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + onSubItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + if (this.expanded && window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + isDirectlyActive(item: NavItem): boolean { + return !!item.route && this.router.isActive(item.route, true); + } + + isChildActive(item: NavItem): boolean { + if (!item.children) return false; + return item.children.some( + (child) => this.isDirectlyActive(child) || this.isChildActive(child) + ); + } + +} diff --git a/theme/packages/minisidebar/src/app/layouts/full/vertical/sidebar/sidebar-data.ts b/theme/packages/minisidebar/src/app/layouts/full/vertical/sidebar/sidebar-data.ts new file mode 100644 index 0000000..e52b956 --- /dev/null +++ b/theme/packages/minisidebar/src/app/layouts/full/vertical/sidebar/sidebar-data.ts @@ -0,0 +1,705 @@ +import { NavItem } from './nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Analytical', + iconName: 'aperture', + route: '/dashboards/dashboard1', + }, + { + displayName: 'eCommerce', + iconName: 'shopping-cart', + route: '/dashboards/dashboard2', + }, + { + displayName: 'Frontend pages', + iconName: 'app-window', + route: 'front-pages', + children: [ + { + displayName: 'Home Page', + iconName: 'point', + route: 'front-pages/homepage', + } , + { + displayName: 'About Us', + iconName: 'point', + route: 'front-pages/about', + } , + { + displayName: 'Blog', + iconName: 'point', + route: 'front-pages/blog', + } , + { + displayName: 'Blog Details', + iconName: 'point', + route: 'front-pages/blog-details', + } , + { + displayName: 'Portfolio', + iconName: 'point', + route: 'front-pages/portfolio', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'front-pages/pricing', + }, + { + displayName: 'Contact', + iconName: 'point', + route: 'front-pages/contact', + } + ] + }, + { + navCap: 'Apps', + }, + { + displayName: 'Chat', + iconName: 'message-2', + route: 'apps/chat', + }, + { + displayName: 'Calendar', + iconName: 'calendar-event', + route: 'apps/calendar', + }, + { + displayName: 'Email', + iconName: 'mail', + route: 'apps/email/inbox', + }, + { + displayName: 'Kanban', + iconName: 'checklist', + route: 'apps/kanban', + }, + { + displayName: 'User Profile', + iconName: 'user-circle', + route: 'apps/profile-details', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'New', + children: [ + { + displayName: 'Profile', + iconName: 'point', + route: 'apps/profile-details/profile', + }, + { + displayName: 'Followers', + iconName: 'point', + route: 'apps/profile-details/followers', + }, + { + displayName: 'Friends', + iconName: 'point', + route: 'apps/profile-details/friends', + }, + { + displayName: 'Gellary', + iconName: 'point', + route: 'apps/profile-details/gallery', + }, + ], + }, + { + displayName: 'Ecommerce', + iconName: 'basket', + route: 'apps/product', + chip: true, + chipClass: 'border-error text-error', + chipContent: 'New', + children: [ + { + displayName: 'Product List', + iconName: 'point', + route: 'apps/product/product-list', + }, + { + displayName: 'Add Product', + iconName: 'point', + route: 'apps/product/add-product', + }, + { + displayName: 'Edit Product', + iconName: 'point', + route: 'apps/product/edit-product', + }, + { + displayName: 'Shop', + iconName: 'point', + route: 'apps/product/shop', + }, + ], + }, + { + displayName: 'Contacts', + iconName: 'phone', + route: 'apps/contacts', + }, + { + displayName: 'Courses', + iconName: 'certificate', + route: 'apps/courses', + }, + { + displayName: 'Employee', + iconName: 'brand-ctemplar', + route: 'apps/employee', + }, + { + displayName: 'Notes', + iconName: 'note', + route: 'apps/notes', + }, + { + displayName: 'Tickets', + iconName: 'ticket', + route: 'apps/tickets', + }, + { + displayName: 'Contact List', + iconName: 'phone', + route: 'apps/contact-list', + }, + { + displayName: 'Invoice', + iconName: 'file-invoice', + route: 'apps/invoice', + children: [ + { + displayName: 'List', + iconName: 'point', + route: 'apps/invoice/list', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/invoice/viewInvoice/101', + }, + { + displayName: 'Create', + iconName: 'point', + route: 'apps/invoice/addInvoice', + }, + { + displayName: 'Edit', + iconName: 'point', + route: 'apps/invoice/editinvoice/101', + }, + ], + }, + { + displayName: 'ToDo', + iconName: 'edit', + route: 'apps/todo', + }, + { + displayName: 'Blog', + iconName: 'chart-donut-3', + route: 'apps/blog', + children: [ + { + displayName: 'Post', + iconName: 'point', + route: 'apps/blog/post', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + }, + ], + }, + { + navCap: 'Pages', + }, + { + displayName: 'Roll Base Access', + iconName: 'lock-access', + route: 'apps/permission', + }, + { + displayName: 'Treeview', + iconName: 'git-merge', + route: 'theme-pages/treeview', + }, + { + displayName: 'Pricing', + iconName: 'currency-dollar', + route: 'theme-pages/pricing', + }, + { + displayName: 'Account Setting', + iconName: 'user-circle', + route: 'theme-pages/account-setting', + }, + { + displayName: 'FAQ', + iconName: 'help', + route: 'theme-pages/faq', + }, + { + displayName: 'Landingpage', + iconName: 'app-window', + route: 'landingpage', + }, + { + displayName: 'Widgets', + iconName: 'layout', + route: 'widgets', + children: [ + { + displayName: 'Cards', + iconName: 'point', + route: 'widgets/cards', + }, + { + displayName: 'Banners', + iconName: 'point', + route: 'widgets/banners', + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'widgets/charts', + }, + ], + }, + { + navCap: 'Forms', + }, + { + displayName: 'Form elements', + iconName: 'apps', + route: 'forms/forms-elements', + children: [ + { + displayName: 'Autocomplete', + iconName: 'point', + route: 'forms/forms-elements/autocomplete', + }, + { + displayName: 'Button', + iconName: 'point', + route: 'forms/forms-elements/button', + }, + { + displayName: 'Checkbox', + iconName: 'point', + route: 'forms/forms-elements/checkbox', + }, + { + displayName: 'Radio', + iconName: 'point', + route: 'forms/forms-elements/radio', + }, + { + displayName: 'Datepicker', + iconName: 'point', + route: 'forms/forms-elements/datepicker', + }, + ], + }, + { + displayName: 'Form Layouts', + iconName: 'file-description', + route: '/forms/form-layouts', + }, + { + displayName: 'Form Horizontal', + iconName: 'box-align-bottom', + route: '/forms/form-horizontal', + }, + { + displayName: 'Form Vertical', + iconName: 'box-align-left', + route: '/forms/form-vertical', + }, + { + displayName: 'Form Wizard', + iconName: 'files', + route: '/forms/form-wizard', + }, + { + displayName: 'Toastr', + iconName: 'notification', + route: '/forms/form-toastr', + }, + { + displayName: 'Editor', + iconName: 'edit', + route: '/forms/form-editor', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'New', + }, + { + navCap: 'Tables', + }, + { + displayName: 'Tables', + iconName: 'layout', + route: 'tables', + children: [ + { + displayName: 'Basic Table', + iconName: 'point', + route: 'tables/basic-table', + }, + { + displayName: 'Dynamic Table', + iconName: 'point', + route: 'tables/dynamic-table', + }, + { + displayName: 'Expand Table', + iconName: 'point', + route: 'tables/expand-table', + }, + { + displayName: 'Filterable Table', + iconName: 'point', + route: 'tables/filterable-table', + }, + { + displayName: 'Footer Row Table', + iconName: 'point', + route: 'tables/footer-row-table', + }, + { + displayName: 'HTTP Table', + iconName: 'point', + route: 'tables/http-table', + }, + { + displayName: 'Mix Table', + iconName: 'point', + route: 'tables/mix-table', + }, + { + displayName: 'Multi Header Footer', + iconName: 'point', + route: 'tables/multi-header-footer-table', + }, + { + displayName: 'Pagination Table', + iconName: 'point', + route: 'tables/pagination-table', + }, + { + displayName: 'Row Context Table', + iconName: 'point', + route: 'tables/row-context-table', + }, + { + displayName: 'Selection Table', + iconName: 'point', + route: 'tables/selection-table', + }, + { + displayName: 'Sortable Table', + iconName: 'point', + route: 'tables/sortable-table', + }, + { + displayName: 'Sticky Column', + iconName: 'point', + route: 'tables/sticky-column-table', + }, + { + displayName: 'Sticky Header Footer', + iconName: 'point', + route: 'tables/sticky-header-footer-table', + }, + ], + }, + { + displayName: 'Data table', + iconName: 'border-outer', + route: '/datatable/kichen-sink', + }, + { + navCap: 'Chart', + }, + { + displayName: 'Line', + iconName: 'chart-line', + route: '/charts/line', + }, + { + displayName: 'Gredient', + iconName: 'chart-arcs', + route: '/charts/gredient', + }, + { + displayName: 'Area', + iconName: 'chart-area', + route: '/charts/area', + }, + { + displayName: 'Candlestick', + iconName: 'chart-candle', + route: '/charts/candlestick', + }, + { + displayName: 'Column', + iconName: 'chart-dots', + route: '/charts/column', + }, + { + displayName: 'Doughnut & Pie', + iconName: 'chart-donut-3', + route: '/charts/doughnut-pie', + }, + { + displayName: 'Radialbar & Radar', + iconName: 'chart-radar', + route: '/charts/radial-radar', + }, + { + navCap: 'UI', + }, + { + displayName: 'Ui Components', + iconName: 'box', + route: 'ui-components', + children: [ + { + displayName: 'Badge', + iconName: 'point', + route: 'ui-components/badge', + }, + { + displayName: 'Expansion Panel', + iconName: 'point', + route: 'ui-components/expansion', + }, + { + displayName: 'Chips', + iconName: 'point', + route: 'ui-components/chips', + }, + { + displayName: 'Dialog', + iconName: 'point', + route: 'ui-components/dialog', + }, + { + displayName: 'Lists', + iconName: 'point', + route: 'ui-components/lists', + }, + { + displayName: 'Divider', + iconName: 'point', + route: 'ui-components/divider', + }, + { + displayName: 'Menu', + iconName: 'point', + route: 'ui-components/menu', + }, + { + displayName: 'Paginator', + iconName: 'point', + route: 'ui-components/paginator', + }, + { + displayName: 'Progress Bar', + iconName: 'point', + route: 'ui-components/progress', + }, + { + displayName: 'Progress Spinner', + iconName: 'point', + route: 'ui-components/progress-spinner', + }, + { + displayName: 'Ripples', + iconName: 'point', + route: 'ui-components/ripples', + }, + { + displayName: 'Slide Toggle', + iconName: 'point', + route: 'ui-components/slide-toggle', + }, + { + displayName: 'Slider', + iconName: 'point', + route: 'ui-components/slider', + }, + { + displayName: 'Snackbar', + iconName: 'point', + route: 'ui-components/snackbar', + }, + { + displayName: 'Tabs', + iconName: 'point', + route: 'ui-components/tabs', + }, + { + displayName: 'Toolbar', + iconName: 'point', + route: 'ui-components/toolbar', + }, + { + displayName: 'Tooltips', + iconName: 'point', + route: 'ui-components/tooltips', + }, + ], + }, + { + navCap: 'Auth', + }, + { + displayName: 'Login', + iconName: 'login', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/login', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-login', + }, + ], + }, + { + displayName: 'Register', + iconName: 'user-plus', + route: '/authentication', + children: [ + { + displayName: 'Side Register', + iconName: 'point', + route: '/authentication/side-register', + }, + { + displayName: 'Boxed Register', + iconName: 'point', + route: '/authentication/boxed-register', + }, + ], + }, + { + displayName: 'Forgot Password', + iconName: 'rotate', + route: '/authentication', + children: [ + { + displayName: 'Side Forgot Password', + iconName: 'point', + route: '/authentication/side-forgot-pwd', + }, + { + displayName: 'Boxed Forgot Password', + iconName: 'point', + route: '/authentication/boxed-forgot-pwd', + }, + ], + }, + { + displayName: 'Two Steps', + iconName: 'zoom-code', + route: '/authentication', + children: [ + { + displayName: 'Side Two Steps', + iconName: 'point', + route: '/authentication/side-two-steps', + }, + { + displayName: 'Boxed Two Steps', + iconName: 'point', + route: '/authentication/boxed-two-steps', + }, + ], + }, + { + displayName: 'Error', + iconName: 'alert-circle', + route: '/authentication/error', + }, + { + displayName: 'Maintenance', + iconName: 'settings', + route: '/authentication/maintenance', + }, + { + navCap: 'Other', + }, + { + displayName: 'Menu Level', + iconName: 'box-multiple', + route: '/menu-level', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + { + displayName: 'Disabled', + iconName: 'ban', + route: '/disabled', + disabled: true, + }, + { + displayName: 'Chip', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-primary text-white', + chipContent: '9', + }, + { + displayName: 'Outlined', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'outlined', + }, + { + displayName: 'External Link', + iconName: 'star', + route: 'https://www.google.com/', + external: true, + }, +]; diff --git a/theme/packages/minisidebar/src/app/material.module.ts b/theme/packages/minisidebar/src/app/material.module.ts new file mode 100644 index 0000000..8fd4750 --- /dev/null +++ b/theme/packages/minisidebar/src/app/material.module.ts @@ -0,0 +1,89 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +// Material Form Controls +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatSelectModule } from '@angular/material/select'; +import { MatSliderModule } from '@angular/material/slider'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +// Material Navigation +import { MatMenuModule } from '@angular/material/menu'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatToolbarModule } from '@angular/material/toolbar'; +// Material Layout +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatListModule } from '@angular/material/list'; +import { MatStepperModule } from '@angular/material/stepper'; +import { MatTabsModule } from '@angular/material/tabs'; +import { MatTreeModule } from '@angular/material/tree'; +// Material Buttons & Indicators +import { MatButtonModule } from '@angular/material/button'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatIconModule } from '@angular/material/icon'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +// Material Popups & Modals +import { MatBottomSheetModule } from '@angular/material/bottom-sheet'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { MatTooltipModule } from '@angular/material/tooltip'; +// Material Data tables +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatSortModule } from '@angular/material/sort'; +import { MatTableModule } from '@angular/material/table'; + +@NgModule({ + declarations: [], + imports: [ + + ], + exports: [ + MatAutocompleteModule, + MatCheckboxModule, + MatDatepickerModule, + MatFormFieldModule, + MatInputModule, + MatRadioModule, + MatSelectModule, + MatSliderModule, + MatSlideToggleModule, + MatMenuModule, + MatSidenavModule, + MatToolbarModule, + MatCardModule, + MatDividerModule, + MatExpansionModule, + MatGridListModule, + MatListModule, + MatStepperModule, + MatTabsModule, + MatTreeModule, + MatButtonModule, + MatButtonToggleModule, + MatBadgeModule, + MatChipsModule, + MatIconModule, + MatProgressSpinnerModule, + MatProgressBarModule, + MatRippleModule, + MatBottomSheetModule, + MatDialogModule, + MatSnackBarModule, + MatTooltipModule, + MatPaginatorModule, + MatSortModule, + MatTableModule, + ], + +}) +export class MaterialModule {} diff --git a/theme/packages/minisidebar/src/app/pages/apps/chat/chat.component.html b/theme/packages/minisidebar/src/app/pages/apps/chat/chat.component.html new file mode 100644 index 0000000..1530c1f --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/apps/chat/chat.component.html @@ -0,0 +1,123 @@ + + + + + + + +
+ +
+

Mathew Anderson

+ info@modernize.com +
+
+ +
+ + + + + + + +
+ + @if (filteredMessages() && filteredMessages().length > 0) { +
+ + @for(message of filteredMessages(); track message.from) { + + + + +

+ {{ message.from }} +

+

+ {{ message.subject }} +

+
+ } +
+
+ } @else { +
+ No messages found. +
+ } +
+
+ + + + + + +
+ +
+ {{ selectedMessage()?.from }} +
+
+ + + + + + +
+ + + + + + + @for(c of selectedMessage()?.chat; track c) { @if(c.type === 'odd') { +
+
+
+ + {{ c.msg }} +
+ + {{ c.date | date }} + +
+
+ } @else { +
+
+
+ {{ c.msg }} +
+ + {{ c.date | date }} + +
+
+ } } +
+
+ +
+ + + + +
+
+
+
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/apps/fullcalendar/fullcalendar.component.ts b/theme/packages/minisidebar/src/app/pages/apps/fullcalendar/fullcalendar.component.ts new file mode 100644 index 0000000..a4565ca --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/apps/fullcalendar/fullcalendar.component.ts @@ -0,0 +1,286 @@ +import { + Component, + ChangeDetectionStrategy, + Inject, + signal, + DOCUMENT +} from '@angular/core'; +import { CommonModule, NgSwitch } from '@angular/common'; +import { + MatDialog, + MatDialogRef, + MatDialogConfig, + MAT_DIALOG_DATA, + MatDialogModule, +} from '@angular/material/dialog'; +import { + FormsModule, + ReactiveFormsModule, + UntypedFormGroup, +} from '@angular/forms'; +import { CalendarFormDialogComponent } from './calendar-form-dialog/calendar-form-dialog.component'; +import { + startOfDay, + subDays, + addDays, + endOfMonth, + isSameDay, + isSameMonth, + addHours, + subMonths, + addMonths, +} from 'date-fns'; +import { Subject } from 'rxjs'; +import { + CalendarDateFormatter, + CalendarEvent, + CalendarEventAction, + CalendarEventTimesChangedEvent, + CalendarModule, + CalendarView, +} from 'angular-calendar'; +import { MaterialModule } from 'src/app/material.module'; +import { + MatNativeDateModule, + provideNativeDateAdapter, +} from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +const colors: any = { + red: { + primary: '#fa896b', + secondary: '#fdede8', + }, + blue: { + primary: '#5d87ff', + secondary: '#ecf2ff', + }, + yellow: { + primary: '#ffae1f', + secondary: '#fef5e5', + }, +}; + +@Component({ + selector: 'app-calendar-dialog', + templateUrl: './dialog.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + CommonModule, + MatNativeDateModule, + MatDialogModule, + MatDatepickerModule, TablerIconsModule + ], + providers: [provideNativeDateAdapter()], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CalendarDialogComponent { + options!: UntypedFormGroup; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) {} +} + +@Component({ + selector: 'app-fullcalendar', + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './fullcalendar.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + NgSwitch, + CalendarModule, + CommonModule, + MatDatepickerModule, + MatDialogModule, + MatFormFieldModule, + ], + providers: [provideNativeDateAdapter(), CalendarDateFormatter] +}) +export class AppFullcalendarComponent { + dialogRef = signal | any>(null); + dialogRef2 = signal | any>(null); + lastCloseResult = signal(''); + actionsAlignment = signal(''); + view = signal('month'); + viewDate = signal(new Date()); + activeDayIsOpen = signal(true); + + config: MatDialogConfig = { + disableClose: false, + width: '', + height: '', + position: { + top: '', + bottom: '', + left: '', + right: '', + }, + data: { + action: '', + event: [], + }, + }; + numTemplateOpens = 0; + + actions: CalendarEventAction[] = [ + { + label: ': Edit', + onClick: ({ event }: { event: CalendarEvent }): void => { + this.handleEvent('Edit', event); + }, + }, + { + label: 'Delete', + onClick: ({ event }: { event: CalendarEvent }): void => { + this.events.set( + this.events().filter((iEvent: CalendarEvent) => iEvent !== event) + ); + this.handleEvent('Deleted', event); + }, + }, + ]; + + refresh: Subject = new Subject(); + + events = signal([ + { + start: subDays(startOfDay(new Date()), 1), + end: addDays(new Date(), 1), + title: 'A 3 day event', + color: colors.red, + actions: this.actions, + }, + { + start: startOfDay(new Date()), + title: 'An event with no end date', + color: colors.blue, + actions: this.actions, + }, + { + start: subDays(endOfMonth(new Date()), 3), + end: addDays(endOfMonth(new Date()), 3), + title: 'A long event that spans 2 months', + color: colors.blue, + }, + { + start: addHours(startOfDay(new Date()), 2), + end: new Date(), + title: 'A draggable and resizable event', + color: colors.yellow, + actions: this.actions, + resizable: { + beforeStart: true, + afterEnd: true, + }, + draggable: true, + }, + ]); + + constructor(public dialog: MatDialog, @Inject(DOCUMENT) doc: any) {} + + dayClicked({ date, events }: { date: Date; events: CalendarEvent[] }): void { + if (isSameMonth(date, this.viewDate())) { + if ( + (isSameDay(this.viewDate(), date) && this.activeDayIsOpen() === true) || + events.length === 0 + ) { + this.activeDayIsOpen.set(false); + } else { + this.activeDayIsOpen.set(true); + this.viewDate.set(date); + } + } + } + + eventTimesChanged({ + event, + newStart, + newEnd, + }: CalendarEventTimesChangedEvent): void { + this.events.set( + this.events().map((iEvent: CalendarEvent) => { + if (iEvent === event) { + return { + ...event, + start: newStart, + end: newEnd, + }; + } + return iEvent; + }) + ); + + this.handleEvent('Dropped or resized', event); + } + + handleEvent(action: string, event: CalendarEvent): void { + this.config.data = { event, action }; + this.dialogRef.set(this.dialog.open(CalendarDialogComponent, this.config)); + + this.dialogRef() + .afterClosed() + .subscribe((result: string) => { + this.lastCloseResult.set(result); + this.dialogRef.set(null); + this.refresh.next(result); + }); + } + + addEvent(): void { + this.dialogRef2.set( + this.dialog.open(CalendarFormDialogComponent, { + panelClass: 'calendar-form-dialog', + autoFocus: false, + data: { + action: 'add', + date: new Date(), + }, + }) + ); + this.dialogRef2() + .afterClosed() + .subscribe((res: { action: any; event: any }) => { + if (!res) { + return; + } + const dialogAction = res.action; + const responseEvent = res.event; + responseEvent.actions = this.actions; + this.events.set([...this.events(), responseEvent]); + this.dialogRef2.set(null); + this.refresh.next(res); + }); + } + + deleteEvent(eventToDelete: CalendarEvent): void { + this.events.set( + this.events().filter( + (event: CalendarEvent) => event !== eventToDelete + ) + ); + } + + setView(view: CalendarView | any): void { + this.view.set(view); + } + + goToPreviousMonth(): void { + this.viewDate.set(subMonths(this.viewDate(), 1)); + } + + goToNextMonth(): void { + this.viewDate.set(addMonths(this.viewDate(), 1)); + } + + goToToday() { + this.viewDate.set(new Date()); + } +} diff --git a/theme/packages/minisidebar/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html b/theme/packages/minisidebar/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html new file mode 100644 index 0000000..027a82b --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html @@ -0,0 +1,156 @@ + + +
+
+
+

+ # + + {{ invoice().id }} +

+
+
+ + Cancel + + +
+
+ + + +
+
+ + Order Status: + + +
+ {{ invoice().status }} +
+
+
+
+ + Order Date + +
+ {{ invoice().orderDate | date : "dd-MM-yyyy" }} +
+
+
+
+ + + +
+
+ + Bill From + + +
+
+ + Bill To + + +
+
+ + Enter From Address + + +
+
+ + Bill From + + +
+
+
+ +
+
+ + + + + + + + + + + + + @for(row of addForm.get('rows')['controls']; track row; let index = + $index) { + + + + + + + + + + + + + + } + +
#Item NameUnit PriceUnitsUnit Total Price
+ {{ index + 1 }} + + + + + + + + + + + + + + + + + + @if(addForm.get('rows')) { + + } + + @if(index > 0) { + + } +
+
+ +
+
Sub total: {{ subTotal() }}
+
Total Vat: {{ vat() }}%
+ +

Grand Total: {{ grandTotal() }}

+
+
+
+
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html b/theme/packages/minisidebar/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html new file mode 100644 index 0000000..f5f0397 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html @@ -0,0 +1,239 @@ + + + @if( invoice()) { + +
+
+
+

+ # + + {{ invoice().id }} +

+
+
+ + Cancel + + + +
+
+ + + +
+
+ Order Status: + + + Pending + Shipped + Delivered + + +
+
+
+ Order Date +
+ {{ invoice().orderDate | date : "dd-MM-yyyy" }} +
+
+
+
+ + + +
+
+ + Bill From + + +
+
+ + Bill To + + +
+
+ + Enter From Address + + +
+
+ + Bill From + + +
+
+
+
+ } + +
+
+ + + + + + + + + + + + + @for(a of addForm.get('item')['controls']; track a; let i =$index) { + + + + + + + + + + + + } +
#Item NameUnit PriceUnitsUnit Total Price
+ {{ i + 1 }} + + + + + + + + + + + + + + + + + + + + @if(addForm.get('item')?.length > 1) { + + } +
+
+ +
+
+ @if(addForm.get('rows')) { + + } + +
Sub total: {{ subTotal() }}
+
Total Vat: {{ vat() }}%
+ +

Grand Total: {{ grandTotal() }}

+
+
+
+
+
diff --git a/theme/packages/minisidebar/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts b/theme/packages/minisidebar/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts new file mode 100644 index 0000000..3e5b5b4 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts @@ -0,0 +1,164 @@ +import { Component, signal } from '@angular/core'; +import { ActivatedRoute, Router, RouterLink } from '@angular/router'; +import { InvoiceService } from 'src/app/services/apps/invoice/invoice.service'; +import { InvoiceList, order } from '../invoice'; +import { + UntypedFormGroup, + UntypedFormArray, + UntypedFormBuilder, + Validators, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { OkDialogComponent } from './ok-dialog/ok-dialog.component'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatSnackBar } from '@angular/material/snack-bar'; +@Component({ + selector: 'app-edit-invoice', + templateUrl: './edit-invoice.component.html', + imports: [ + MaterialModule, + CommonModule, + RouterLink, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ], +}) +export class AppEditInvoiceComponent { + id = signal(null); + subTotal = signal(0); + vat = signal(0); + grandTotal = signal(0); + addForm: UntypedFormGroup | any; + invoice = signal([]); + constructor( + activatedRouter: ActivatedRoute, + private invoiceService: InvoiceService, + private router: Router, + private fb: UntypedFormBuilder, + public dialog: MatDialog, + private snackBar: MatSnackBar + ) { + this.id.set(activatedRouter.snapshot.paramMap.get('id')); + this.loadInvoice(); // Load invoice here + this.subTotal.set(this.invoice()?.totalCost || 0); + this.vat.set(this.invoice()?.vat || 0); + this.grandTotal.set(this.invoice()?.grandTotal || 0); + this.addForm = this.fb.group({ + item: this.fb.array([this.itemControl()]), + }); + + this.fillAddControls(); + } + + loadInvoice(): void { + const invoiceData = this.invoiceService + .getInvoiceList() + .find((x) => x.id === +this.id()); + this.invoice.set(invoiceData); // Set the invoice signal + } + itemControl(): UntypedFormGroup { + return this.fb.group({ + itemName: ['', Validators.required], + itemCost: ['', Validators.required], + itemSold: ['', Validators.required], + itemTotal: [{ value: 0, disabled: true }], + }); + } + + fillAddControls(): void { + this.addForm.setControl('item', this.setItem(this.invoice()?.orders)); + } + + setItem(order: any): UntypedFormArray { + const fa = new UntypedFormArray([]); + order?.forEach((s: any) => { + fa.push( + this.fb.group({ + itemName: s.itemName, + itemCost: s.unitPrice, + itemSold: s.units, + itemTotal: s.unitTotalPrice, + }) + ); + }); + return fa; + } + + btnAddItemClick(): void { + (this.addForm.get('item')).push(this.itemControl()); + } + + btnRemoveClick(i: number): void { + const totalCostOfItem = + this.addForm.get('item')?.value[i].itemCost * + this.addForm.get('item')?.value[i].itemSold; + + this.subTotal.set(this.subTotal() - totalCostOfItem); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + + (this.addForm.get('item')).removeAt(i); + } + + itemsChanged(): void { + let total = 0; + for ( + let t = 0; + t < (this.addForm.get('item')).length; + t++ + ) { + if ( + this.addForm.get('item')?.value[t].itemCost != '' && + this.addForm.get('item')?.value[t].itemSold + ) { + total += + this.addForm.get('item')?.value[t].itemCost * + this.addForm.get('item')?.value[t].itemSold; + } + } + this.subTotal.set(total); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + } + + saveDetail(event: Event): void { + event.preventDefault(); + const currentInvoice = this.invoice(); + if (currentInvoice) { + currentInvoice.grandTotal = this.grandTotal(); + currentInvoice.totalCost = this.subTotal(); + currentInvoice.vat = this.vat(); + currentInvoice.orders = []; + + for ( + let t = 0; + t < (this.addForm.get('item')).length; + t++ + ) { + const o: order = new order(); + o.itemName = this.addForm.get('item')?.value[t].itemName; + o.unitPrice = this.addForm.get('item')?.value[t].itemCost; + o.units = this.addForm.get('item')?.value[t].itemSold; + o.unitTotalPrice = o.units * o.unitPrice; + currentInvoice.orders.push(o); + } + this.dialog.open(OkDialogComponent); + this.invoiceService.updateInvoice(currentInvoice.id, currentInvoice); + this.router.navigate(['/apps/invoice/list']); + this.showSnackbar('Invoice updated successfully!'); + } + } + + showSnackbar(message: string): void { + this.snackBar.open(message, 'Close', { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } +} diff --git a/theme/packages/minisidebar/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html b/theme/packages/minisidebar/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html new file mode 100644 index 0000000..3942ba6 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html @@ -0,0 +1,281 @@ +
+
+ + +
+ +
+
+
Total
+
+ {{ allInvoices().length }} invoices +
+
+
+
+
+
+ + +
+ +
+
+
Shipped
+
+ {{ countInvoicesByStatus("Shipped") }} invoices +
+
+
+
+
+ +
+ + +
+ +
+
+
Delivered
+
+ {{ countInvoicesByStatus("Delivered") }} invoices +
+
+
+
+
+ +
+ + +
+ +
+
+
Pending
+
+ {{ countInvoicesByStatus("Pending") }} invoices +
+
+
+
+
+
+ + + +
+
+ + + + + + +
+ +
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + Id + + {{ element.id }} + + Bill From + + {{ element.billFrom }} + + Bill To + + {{ element.billTo }} + + Total Cost + + {{ element.totalCost }} + + Status + + + {{ element.status }} + + + Action + + + + + + + + + + + +
+ +
+
+
diff --git a/theme/packages/minisidebar/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html b/theme/packages/minisidebar/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html new file mode 100644 index 0000000..b3bbc15 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html @@ -0,0 +1,125 @@ + + + @if(invoiceDetail()){ + +
+
+

#{{ invoiceDetail()?.id }}

+
+ +
+ +
+
+ Order Status: +
+ {{ invoiceDetail()?.status }} +
+
+
+ Order Date: +
+ {{ invoiceDetail()?.orderDate | date : "fullDate" }} +
+
+
+ +
+
+ Bill From: +
+ {{ invoiceDetail()?.billFrom }} +
+
+ {{ invoiceDetail()?.billFromEmail }} +
+
+ {{ invoiceDetail()?.billFromAddress }} +
+
+ {{ invoiceDetail()?.billFromPhone }} +
+
+
+ Bill To: +
+ {{ invoiceDetail()?.billTo }} +
+
+ {{ invoiceDetail()?.billToEmail }} +
+
+ {{ invoiceDetail()?.billToAddress }} +
+
+ {{ invoiceDetail()?.billToPhone }} +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ Item Name + + {{ element.itemName }} + + Unit Price + + {{ element.unitPrice }} + + Unit + + {{ element.units }} + + Total Cost + + {{ element.unitTotalPrice }} +
+
+ +
+
+ Sub total: {{ invoiceDetail()?.totalCost }} +
+ Vat: 10% +

+ Grand Total: {{ invoiceDetail()?.grandTotal }} +

+
+
+ } +
+
diff --git a/theme/packages/minisidebar/src/app/pages/apps/tickets/ticket-dialog-content.html b/theme/packages/minisidebar/src/app/pages/apps/tickets/ticket-dialog-content.html new file mode 100644 index 0000000..19f96d5 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/apps/tickets/ticket-dialog-content.html @@ -0,0 +1,132 @@ +@if(action !== 'Delete') { + +
+

{{action}} Ticket

+ +
+
+
+ @if(action === 'Update') { +
+ Ticket Id + + + +
+ } + +
+ Ticket Title + + + +
+
+ Ticket Subtext + + + +
+
+ Assign User + + + @for(user of users; track trackByUser(user)) { + +
+ {{ user.name }} + {{ user.name }} +
+
+ } +
+
+
+ @if(action === 'Update'){ +
+ Status + + + +
+ } @if(action === 'Update') { +
+ + Date + + + + +
+ } +
+
+
+} @else { +
+ Sure to delete {{local_data.title}}? +
+} +
+ + +
diff --git a/theme/packages/minisidebar/src/app/pages/apps/tickets/tickets.component.ts b/theme/packages/minisidebar/src/app/pages/apps/tickets/tickets.component.ts new file mode 100644 index 0000000..f1b5f6c --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/apps/tickets/tickets.component.ts @@ -0,0 +1,177 @@ +import { + Component, + OnInit, + ViewChild, + AfterViewInit, + Inject, +} from '@angular/core'; +import { MatTableDataSource, MatTable } from '@angular/material/table'; +import { + MatDialog, + MatDialogRef, + MAT_DIALOG_DATA, +} from '@angular/material/dialog'; +import { MatPaginator } from '@angular/material/paginator'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TicketService } from 'src/app/services/apps/ticket/ticket.service'; +import { TicketElement } from 'src/app/pages/apps/tickets/ticket'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +@Component({ + selector: 'app-ticket-list', + templateUrl: './tickets.component.html', + imports: [MaterialModule, CommonModule, TablerIconsModule], +}) +export class AppTicketlistComponent implements OnInit, AfterViewInit { + @ViewChild(MatTable, { static: true }) table: MatTable; + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; + + searchText: string = ''; + totalCount = 0; + Closed = 0; + Inprogress = 0; + Open = 0; + + displayedColumns: string[] = [ + 'id', + 'title', + 'assignee', + 'status', + 'date', + 'action', + ]; + + dataSource = new MatTableDataSource([]); + + constructor(private ticketService: TicketService, public dialog: MatDialog) {} + + ngOnInit(): void { + this.loadTickets(); // Load the initial tickets + } + + private loadTickets(): void { + const tickets = this.ticketService.tickets$; // Get tickets from the service + this.dataSource.data = tickets; // Set the dataSource to the tickets + + // Update counts based on the current tickets + this.updateCounts(); + } + + private updateCounts(): void { + this.totalCount = this.dataSource.data.length; + this.Open = this.countTicketsByStatus('open'); + this.Closed = this.countTicketsByStatus('closed'); + this.Inprogress = this.countTicketsByStatus('inprogress'); + } + + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + } + + onKeyup(event: KeyboardEvent): void { + const input = event.target as HTMLInputElement; + this.applyFilter(input.value); + } + applyFilter(filterValue: string): void { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + btnCategoryClick(val: string): number { + this.dataSource.filter = val.trim().toLowerCase(); + return this.dataSource.filteredData.length; + } + + openDialog(action: string, ticket: TicketElement | any): void { + const dialogRef = this.dialog.open(TicketDialogComponent, { + data: { action, ticket }, + autoFocus: false, + }); + + dialogRef.afterClosed().subscribe(() => { + this.loadTickets(); + }); + } + + countTicketsByStatus(status: string): number { + return this.dataSource.data.filter( + (ticket) => ticket.status.toLowerCase() === status.toLowerCase() + ).length; + } +} + +@Component({ + // tslint:disable-next-line - Disables all + selector: 'app-dialog-content', + templateUrl: 'ticket-dialog-content.html', + imports: [ + MaterialModule, + CommonModule, + TablerIconsModule, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ], +}) +export class TicketDialogComponent { + action: string; + local_data: TicketElement; + users: any[] = []; + dateControl = new FormControl(); + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + private ticketService: TicketService, + private snackBar: MatSnackBar + ) { + this.action = data.action; + this.local_data = { ...data.ticket }; + } + + ngOnInit(): void { + this.users = this.ticketService.getUsers(); // Get users from the service + + if (this.local_data.date) { + this.dateControl.setValue( + new Date(this.local_data.date).toISOString().split('T')[0] + ); // existing date + } else { + // Set to today's date if no existing date is available + this.dateControl.setValue(new Date().toISOString().split('T')[0]); + } + } + + doAction(): void { + this.local_data.date = this.dateControl.value; // Update local_data with the new date + + if (this.action === 'Update') { + this.ticketService.updateTicket(this.local_data); + this.openSnackBar('Ticket updated successfully!', 'Close'); + } else if (this.action === 'Add') { + this.ticketService.addTicket(this.local_data); + this.openSnackBar('Ticket added successfully!', 'Close'); + } else if (this.action === 'Delete') { + this.ticketService.deleteTicket(this.local_data.id); + this.openSnackBar('Ticket deleted successfully!', 'Close'); + } + this.dialogRef.close(); + } + + openSnackBar(message: string, action: string): void { + this.snackBar.open(message, action, { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } + closeDialog(): void { + this.dialogRef.close(); + } + + trackByUser(user: any): any { + return user.id; + } +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.html new file mode 100644 index 0000000..0fef605 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.html @@ -0,0 +1,169 @@ +
+ + +
+
+

+ The hassle-free setup process +

+
+ @for(topcard of setupCards; track topcard.title) { +
+ + +
+ @if(topcard.id!==2){ + users + } + +
+ {{ topcard.title }} +
+

+ {{ topcard.subtitle }} +

+ @if(topcard.id===2){ + image + } +
+
+
+
+ } +
+
+
+ + + +
+
+
+
+
+

Key metric at a glance

+

+ From the year we were founded to the impressive customer base + we've built, and the growth percentages that reflect our + continuous improvement, these numbers tell our story at a glance. + Explore the data that drives our mission and underscores our + commitment to excellence. +

+
+
+
+
+ @for (stat of stats; track stat) { +
+
+

+ {{ stat.label }} +

+

+ {{ stat.value }} +

+

{{ stat.description }}

+
+
+ } +
+
+
+
+
+ +
+ +
+ +
+
+
+ +
+
+

+ What our clients
think logo + about us? +

+

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+
+
+
+ + + Features availability + +
+
+ +
+
{{ currentUser().name }}
+
+ +

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+ + + +
+ + + {{ displayCount() }} + + +
+
+
+
+
+
+
+ + + +
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.scss new file mode 100644 index 0000000..e5e27d5 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.scss @@ -0,0 +1,23 @@ +.contact-page { + + .setup-process { + + mat-card-content { + padding: 0px !important; + padding: 30px 16px !important; + } + } + + .key-metric { + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + } + + .features { + + .cardWithShadow { + mat-card-content { + padding: 0px !important; + } + } + } +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.spec.ts new file mode 100644 index 0000000..0d075ce --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AboutUsComponent } from './about-us.component'; + +describe('AboutUsComponent', () => { + let component: AboutUsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AboutUsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AboutUsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.ts new file mode 100644 index 0000000..497b22d --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/about-us/about-us.component.ts @@ -0,0 +1,48 @@ +import { Component, computed, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { ImageSliderComponent } from '../image-slider/image-slider.component'; +import { FooterComponent } from '../footer/footer.component'; +//import { PagePricingComponent } from '../page-pricing/page-pricing.component'; +import { + setupCards, + stats, + users, +} from '../front-pagesData'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-about-us', + imports: [IconModule,MaterialModule ,CommonModule,ImageSliderComponent,FooterComponent, + //PagePricingComponent + ], + templateUrl: './about-us.component.html', + styleUrl: './about-us.component.scss' +}) +export class AboutUsComponent { + setupCards=setupCards; + stats = stats; + currentIndex = signal(0); // Starting from 0 + users = users; + // Computed values to auto-update template + currentUser = computed(() => this.users[this.currentIndex()]); + displayCount = computed( + () => `${this.currentIndex() + 1}/${this.users.length}` + ); + goPrev() { + if (this.currentIndex() > 0) { + this.currentIndex.update((i) => i - 1); + } + } + + goNext() { + if (this.currentIndex() < this.users.length - 1) { + this.currentIndex.update((i) => i + 1); + } + + + } + + + +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.html new file mode 100644 index 0000000..020f82c --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.html @@ -0,0 +1,116 @@ + + +
+
+ + + + @if(blogDetail()) { + + Photo of a Shiba Inu +
+ 2 mins Read +
+ +
+
+ +
+ {{ + blogDetail()?.category }} +
+ + {{ + blogDetail()?.title }} + +
+
+ {{ + blogDetail()?.views }} + 4 +
+ + + {{ blogDetail()?.date }} + +
+
+ +

Main Heading & Points

+

+ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the + industry's standard dummy text ever since + the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It + has survived not only five centuries, + but also the leap into electronic typesetting, + remaining essentially unchanged. It was popularised in the +

+
    +
  • Vivamus eu lacus scelerisque, placerat commodo lectus.
  • +
  • Etiam et ante at ex porta fringilla.
  • +
  • Nullam dignissim sem eu magna aliquet, sit amet volutpat tellus
  • +
+

+ Unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not + only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was + popularised in the +

+ +

+ We are a dedicated team of passionate product managers, developers, UX/UI designers, QA engineers experts + helping businesses from new startups +

+ +

+ There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in + some form, by injected humour, or randomised words which don't look even slightly believable making this the + first true generator on the Internet. It uses a dictionary +

+ +

Tags

+
    +
  • Trends
  • +
  • Design
  • +
  • Research
  • +
+ + +

Share

+ + + +

Join our newsletter

+

Email address : Subscribe

+
+
+ } + + + + + + @if (!blogDetail() || blogDetail().length === 0) { + + +

No blog post available.

+
+
+ } +
+
+ + \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts new file mode 100644 index 0000000..241ed7b --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlogDetailsComponent } from './blog-details.component'; + +describe('BlogDetailsComponent', () => { + let component: BlogDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BlogDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BlogDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.ts new file mode 100644 index 0000000..9633085 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/blog-details/blog-details.component.ts @@ -0,0 +1,40 @@ +import { CommonModule } from '@angular/common'; +import { Component, inject, OnInit, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; +import { FrontEndService } from 'src/app/services/apps/front-pages/front-end.service'; + +@Component({ + selector: 'app-blog-details', + imports: [IconModule, MaterialModule, CommonModule, + FooterComponent + ], + templateUrl: './blog-details.component.html', + styleUrl: './blog-details.component.scss' +}) +export class BlogDetailsComponent implements OnInit { + blogDetail = signal(null); + private frontendService = inject(FrontEndService); + ngOnInit(): void { + const selected = this.frontendService.getBlog()(); + + if (selected) { + this.blogDetail.set(selected); + } else { + // Fallback if accessed directly (e.g., from sidebar or refresh) + const defaultBlog = { + id: 1, + time: "2 mins Read", + imgSrc: "/assets/images/blog/blog-img1.jpg", + user: "/assets/images/profile/user-1.jpg", + title: "As yen tumbles, gadget-loving Japan goes for secondhand iPhones", + views: "9,125", + category: "Social", + comments: 3, + date: "Mon, Dec 23" + }; + this.blogDetail.set(defaultBlog); + } + } +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.html new file mode 100644 index 0000000..e30ba7c --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.html @@ -0,0 +1,55 @@ + + +
+
+
+ @for(cardimg of cardimgs; track cardimg.imgSrc) { +
+ + Photo of a Shiba Inu +
+ {{ + cardimg.time + }} +
+ + +
+
+ +
+ {{ + cardimg.category + }} +
+ {{ cardimg.title }} +
+
+ {{ cardimg.views }} + {{ cardimg.comments }} +
+ + + {{ cardimg.date }} + +
+
+
+
+ } +
+
+
+ + \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.scss new file mode 100644 index 0000000..e5dce08 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.scss @@ -0,0 +1,24 @@ + + +.social-btns { + margin-top: 20px; + + .btn-icon { + width: 25px !important; + height: 25px !important; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + + tabler-icon { + width: 16px !important; + height: 16px !important; + } + } + + .btn-add-story { + font-size: 0.75rem; + padding: 0.35rem 0.75rem; + } +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.spec.ts new file mode 100644 index 0000000..7998b08 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlogComponent } from './blog.component'; + +describe('BlogComponent', () => { + let component: BlogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BlogComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BlogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.ts new file mode 100644 index 0000000..d25328e --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/blog/blog.component.ts @@ -0,0 +1,32 @@ +import { Component, inject, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { cardimgs } from '../front-pagesData'; +import { FooterComponent } from '../footer/footer.component'; +import { Router } from '@angular/router'; +import { FrontEndService } from 'src/app/services/apps/front-pages/front-end.service'; + +@Component({ + selector: 'app-blog', + imports: [IconModule, MaterialModule, FooterComponent,], + templateUrl: './blog.component.html', + styleUrl: './blog.component.scss' +}) +export class BlogComponent implements OnInit { + + private router = inject(Router); + private frontendService = inject(FrontEndService); + cardimgs = cardimgs; + + ngOnInit() { + console.log(cardimgs, 'cardimgs'); + } + + getNavigate(cardimg: any) { + console.log('cardimg--->', cardimg); + this.frontendService.setBlog(cardimg); + this.router.navigate(['front-pages/blog-details']) + + } + +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.html new file mode 100644 index 0000000..f2cfc62 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.html @@ -0,0 +1,103 @@ +
+ + + +
+
+
+ +
+ +
+
+
+
+
+
+ + First Name* + + + + + Phone Number* + + + +
+
+ + Last Name* + + + + + Email* + + + +
+
+ +
+
+ Enquire related to* + + + + General Enquiry + General Enquiry 2 + + +
+
+
+
+ Message + + + +
+
+ +
+
+ + +
+
Reach Out Today
+

+ Have questions or need assistance? We're just a message + away. +

+
+ +
+
Our Location
+

+ Visit us in person or find our contact details to connect + with us directly. +

+
+
+
+
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.scss new file mode 100644 index 0000000..572fa27 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.scss @@ -0,0 +1,3 @@ +.map-container{ + margin-top: -200px; +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.spec.ts new file mode 100644 index 0000000..dae8ee6 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ContactComponent } from './contact.component'; + +describe('ContactComponent', () => { + let component: ContactComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ContactComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ContactComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.ts new file mode 100644 index 0000000..556ed9a --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/contact/contact.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; + +@Component({ + selector: 'app-contact', + imports: [MaterialModule,IconModule,FooterComponent], + templateUrl: './contact.component.html', + styleUrl: './contact.component.scss' +}) +export class ContactComponent { + +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.html new file mode 100644 index 0000000..0177911 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.html @@ -0,0 +1,94 @@ + \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.scss new file mode 100644 index 0000000..6a425bb --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.scss @@ -0,0 +1,13 @@ + +.footer-content{ + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } +} + +.imgStyleDash { + position: absolute; +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.spec.ts new file mode 100644 index 0000000..3f93915 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FooterComponent } from './footer.component'; + +describe('FooterComponent', () => { + let component: FooterComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FooterComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FooterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.ts new file mode 100644 index 0000000..7864854 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/footer/footer.component.ts @@ -0,0 +1,95 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { RouterLink } from '@angular/router'; + +@Component({ + selector: 'app-footer', + imports: [MaterialModule, IconModule, RouterLink], + templateUrl: './footer.component.html', + styleUrl: './footer.component.scss' +}) +export class FooterComponent { + applicationsItems = [ + { + title: 'Kanban', + href: "/apps/kanban" + }, + { + title: 'Invoice List', + href: "/apps/invoice/list" + }, + { + title: 'eCommerce', + href: "/apps/product/shop" + }, + { + title: 'Chats', + href: "/apps/chat" + }, + { + title: 'Tickets', + href: "/apps/tickets" + }, + { + title: 'Blog', + href: "/apps/blog/post" + }, + ]; + + formsItems = [ + { + title: 'Form Layout', + href: "/forms/form-layouts" + }, + { + title: 'Form Horizontal', + href: "/forms/form-horizontal" + }, + { + title: 'Form Wizard', + href: "/forms/form-wizard" + }, + { + title: 'Form Vertical', + href: "/forms/form-vertical" + }, + { + title: 'Form Toastr', + href: "/forms/form-toastr" + }, + ]; + + tablesItems = [ + { + title: 'Basic Table', + href: "/tables/basic-table" + }, + { + title: 'Multi Header Footer Table', + href: "/tables/multi-header-footer-table" + }, + { + title: 'Pagination Table', + href: "/tables/pagination-table" + }, + { + title: 'Dynamic Table', + href: "/tables/dynamic-table" + }, + { + title: 'HTTP Table', + href: "/tables/http-table" + }, + { + title: 'Sortable Table', + href: "/tables/sortable-table" + }, + ]; + + socialIcons = [ + { src: 'assets/images/front-pages/icon-facebook.svg', tooltip: 'Facebook' }, + { src: 'assets/images/front-pages/icon-twitter.svg', tooltip: 'Twitter' }, + { src: 'assets/images/front-pages/icon-instagram.svg', tooltip: 'Instagram' }, + ]; +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/front-pages.routes.ts b/theme/packages/minisidebar/src/app/pages/front-pages/front-pages.routes.ts new file mode 100644 index 0000000..bf9375c --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/front-pages.routes.ts @@ -0,0 +1,28 @@ +import { Routes } from '@angular/router'; +import { HomepageComponent } from './homepage/homepage.component'; +import { AboutUsComponent } from './about-us/about-us.component'; +import { HomepageDetailsComponent } from './homepage-details/homepage-details.component'; +import { BlogComponent } from './blog/blog.component'; +import { PortfolioComponent } from './portfolio/portfolio.component'; +import { PricingComponent } from './pricing/pricing.component'; +import { ContactComponent } from './contact/contact.component'; +import { BlogDetailsComponent } from './blog-details/blog-details.component'; + + +export const FrontPagesRoutes: Routes = [ + + { + path: '', + component: HomepageComponent, // acts as layout shell + children: [ + { path: '', redirectTo: 'homepage', pathMatch: 'full' }, + { path: 'homepage', component: HomepageDetailsComponent }, // real homepage content + { path: 'about', component: AboutUsComponent }, + {path:'blog',component:BlogComponent }, + { path: 'portfolio', component: PortfolioComponent }, + { path: 'pricing', component: PricingComponent }, + { path: 'contact', component: ContactComponent }, + { path: 'blog-details', component: BlogDetailsComponent }, + ], + }, +]; \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/front-pagesData.ts b/theme/packages/minisidebar/src/app/pages/front-pages/front-pagesData.ts new file mode 100644 index 0000000..0e870f4 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/front-pagesData.ts @@ -0,0 +1,768 @@ +interface cardimgs { + id: number; + time: string; + imgSrc: string; + user: string; + title: string; + views: string; + category: string; + comments: number; + date: string; +} + +interface productcards { + id: number; + imgSrc: string; + title: string; + price: string; + rprice: string; + date: string; +} + +interface Framework { + src: string; + alt: string; + tooltip: string; +} + +interface followercards { + id: number; + imgSrc: string; + title: string; +} + +interface setupCards { + id: number; + img: string; + color: string; + title: string; + subtitle: string; + imgMain?:string; +} + +export const cardimgs: cardimgs[] = [ + { + id: 1, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img1.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 2, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img2.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 3, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img3.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + { + id: 4, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img4.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 5, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img5.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 6, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img6.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + { + id: 7, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img10.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 8, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img8.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 9, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img9.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, +]; + +export const productcards: productcards[] = [ + { + id: 1, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Headphone', + price: '285', + rprice: '375', + date: 'Tue, Apr 03, 2025', + }, + { + id: 2, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Air Pro', + price: '285', + rprice: '375', + date: 'Tue, Apr 10, 2025', + }, + { + id: 3, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Red Velvet Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 15, 2025', + }, + { + id: 4, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Soft Plush Teddy', + price: '285', + rprice: '375', + date: 'Tue, Apr 12, 2025', + }, + { + id: 5, + imgSrc: 'assets/images/products/s2.jpg', + title: 'Boat Bass Booster', + price: '285', + rprice: '375', + date: 'Tue, Apr 14, 2025', + }, + { + id: 6, + imgSrc: 'assets/images/products/s6.jpg', + title: 'MacBook Ultra Slim', + price: '285', + rprice: '375', + date: 'Tue, Apr 18, 2025', + }, + { + id: 7, + imgSrc: 'assets/images/products/s8.jpg', + title: 'Crimson Party Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 20, 2025', + }, + { + id: 8, + imgSrc: 'assets/images/products/s12.jpg', + title: 'Cuddly Teddy Gift', + price: '285', + rprice: '375', + date: 'Tue, Apr 22, 2025', + }, + { + id: 9, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Sonic Headset', + price: '285', + rprice: '375', + date: 'Tue, Apr 25, 2025', + }, + { + id: 10, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Pro 2025', + price: '285', + rprice: '375', + date: 'Tue, Apr 27, 2025', + }, + { + id: 11, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Evening Gown - Red', + price: '285', + rprice: '375', + date: 'Tue, Apr 29, 2025', + }, + { + id: 12, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Fluffy Bear Surprise', + price: '285', + rprice: '375', + date: 'Tue, Apr 30, 2025', + }, +]; + +export const frameworks: Framework[] = [ + { + src: 'assets/images/landingpage/frameworks/angular.svg', + alt: 'Angular', + tooltip: 'Angular', + }, + { + src: 'assets/images/landingpage/frameworks/material.svg', + alt: 'Angular Material', + tooltip: 'Angular Material', + }, + { + src: 'assets/images/landingpage/frameworks/logo-ts.svg', + alt: 'Typescript', + tooltip: 'Typescript', + }, + { + src: 'assets/images/landingpage/frameworks/icon-tabler.svg', + alt: 'Tabler Icon', + tooltip: 'Tabler Icon', + }, +]; + +export const tiles = [ + { + id: 1, + text: 'Light & Dark Color Schemes', + cols: 1, + rows: 1, + color: '#FFF6E5', + icon: 'svgs/icon-briefcase.svg', + subtitle: 'Choose your preferred visual style effortlessly.', + }, + { + id: 2, + text: 'New Demos', + cols: 2, + rows: 2, + color: '#E9F1FF', + icon: 'logos/logoIcon.svg', + img: 'landingpage/background/screen1.png', + subtitle: + 'Brand new demos to help you build the perfect dashboard:
Dark and Right-to-Left.', + }, + { + id: 3, + text: 'Code Improvements', + cols: 1, + rows: 1, + color: '#E7FFF2', + icon: 'logos/icon-speech-bubble.svg', + subtitle: 'Benefit from continuous improvements and optimizations.', + }, + { + id: 4, + text: '12+ Ready to Use Application Designs', + cols: 1, + rows: 1, + color: '#E4F4FF', + icon: 'icon-layer.svg', + img: 'landingpage/background/feature-apps.png', + subtitle: 'Instantly deployable designs for your applications.', + }, + { + id: 5, + text: '50+ UI Components', + cols: 1, + rows: 1, + color: '#FFECEC', + icon: 'logos/icon-favorites.svg', + subtitle: 'A rich collection for seamless user experiences.', + }, +]; + +export const users = [ + { name: 'Jenny Wilson', img: '/assets/images/profile/user-1.jpg' }, + { name: 'Robert Fox', img: '/assets/images/profile/user-2.jpg' }, + { name: 'Kristin Watson', img: '/assets/images/profile/user-3.jpg' }, + { name: 'Darlene Robertson', img: '/assets/images/profile/user-4.jpg' }, + { name: 'Jacob Jones', img: '/assets/images/profile/user-5.jpg' }, +]; + +export const plans = [ + { + title: 'Single Use', + description: + 'Use for single end product which end users can’t be charged for.', + price: 49, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: false }, + { text: 'One Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Multiple Use', + description: + 'Use for unlimited end products end users can’t be charged for.', + price: 89, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: false }, + { text: 'Unlimited Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Extended Use', + description: + 'Use for single end product which end users can be charged for.', + price: 299, + period: 'one time pay', + popular: true, + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: true }, + { text: 'One Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Unlimited Use', + description: + 'Use in unlimited end products end users can be charged for.', + price: 499, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: true }, + { text: 'Unlimited Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, +]; + +export const paymentLogos = [ + { src: 'assets/images/front-pages/icon-visa.svg', alt: 'visa', tooltip: 'Visa' }, + { + src: 'assets/images/front-pages/icon-mastercard.svg', + alt: 'mastercard', + tooltip: 'Master Card', + }, + { + src: 'assets/images/front-pages/icon-american-express.svg', + alt: 'american express', + tooltip: 'American Express', + }, + { + src: 'assets/images/front-pages/icon-discover.svg', + alt: 'discover', + tooltip: 'Discover', + }, + { + src: 'assets/images/front-pages/icon-paypal.svg', + alt: 'paypal', + tooltip: 'Paypal', + }, + { + src: 'assets/images/front-pages/icon-masetro.svg', + alt: 'maestro', + tooltip: 'Maestro', + }, + { src: 'assets/images/front-pages/icon-jcb.svg', alt: 'jcb', tooltip: 'JCB' }, + { + src: 'assets/images/front-pages/icon-diners.svg', + alt: 'diners', + tooltip: 'Diners', + }, +]; + +export const faqList = [ + { + question: 'What is included with my purchase?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Are there any recurring fees?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Can i use template on multiple projects? ', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: + 'Can i use customize the admin dashboard template to match my brand?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Are any restrictions on using the template?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'How can i get support after purchase? ', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, +]; + +export const followercardsFirst: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, +]; + +export const followercardSecond: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, +]; +export const followercardThird: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-customize.svg', + title: 'Easy to Customize', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-chart.svg', + title: 'Lots of Chart Options', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-table.svg', + title: 'Lots of Table Examples', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-update.svg', + title: 'Regular Updates', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-support.svg', + title: 'Dedicated Support', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Easy to Customize', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: 'Lots of Chart Options', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Lots of Table Examples', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Regular Updates', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Dedicated Support', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Easy to Customize', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: 'Lots of Chart Options', + }, + +]; + +export const topcardsGrid = [ + { title: 'Light & Dark Color Schemes', subtitle: 'Choose your preferred visual style effortlessly.', + img: '/assets/images/svgs/icon-briefcase.svg', color: 'warning' }, + { title: '12+ Ready to Use Application Designs', subtitle: 'Instantly deployable designs for your applications.', + img: 'assets/icons/icon2.png', color: 'secondary',imgMain: '/assets/images/landingpage/background/feature-apps.png', }, + { title: 'New Demos', subtitle: 'Brand new demos to help you build the perfect dashboard: Dark and Right-to-Left.', + img: '/assets/images/front-pages/logoIcon.svg', color: 'primary',imgMain: '/assets/images/landingpage/background/screen1.png' }, + { title: 'Code Improvements', subtitle: 'Benefit from continuous improvements and optimizations.', + img: '/assets/images/front-pages/icon-speech-bubble.svg', color: 'success' }, + { title: '50+ UI Components', subtitle: 'A rich collection for seamless user experiences.', + img: '/assets/images/front-pages/icon-favorites.svg', color: 'error' }, +]; + +export const setupCards:setupCards[] = [ + { + id: 1, + color: 'warning', + img: '/assets/images/svgs/icon-briefcase.svg', + title: 'Light & Dark Color Schemes', + subtitle: 'Choose your preferred visual style effortlessly.', + }, + { + id: 2, + color: 'secondary', + img: '/assets/images/svgs/icon-connect.svg', + title: '12+ Ready to Use Application Designs', + subtitle: 'Instantly deployable designs for your applications.', + imgMain: '/assets/images/landingpage/background/feature-apps.png' + }, + + { + id: 3, + color: 'success', + img: '/assets/images/svgs/icon-speech-bubble.svg', + title: 'Code Improvements', + subtitle: 'Benefit from continuous improvements and optimizations.', + }, + { + id: 4, + color: 'error', + img: '/assets/images/svgs/icon-favorites.svg', + title: '50+ UI Components', + subtitle: 'A rich collection for seamless user experiences.', + }, + +]; + +export const stats = [ + { + label: 'Founded', + value: '2019', + description: 'When we founded Modernize', + }, + { + label: 'Growth', + value: '1,400%', + description: 'Revenue growth in 2024', + }, + { + label: 'Customers', + value: '300k+', + description: 'Customers on Modernize', + }, + { + label: 'Dashboards', + value: '25k+', + description: 'Dashboards built using Modernize', + }, +]; + +export const team = [ + {id: 1, + name: 'Alex Martinez', + position: 'CEO & Co-Founder', + image: 'assets/images/front-pages/user1.jpg' + }, + { + id: 2, + name: 'Jordan Nguyen', + position: 'CTO & Co-Founder', + image: 'assets/images/front-pages/user2.jpg' + }, + { + id: 3, + name: 'Taylor Roberts', + position: 'Product Manager', + image: 'assets/images/front-pages/user3.jpg' + }, + {id: 4, + name: 'Morgan Patel', + position: 'Lead Developer', + image: 'assets/images/front-pages/user4.jpg' + }, + { + id: 5, + name: 'Andrew Grant', + position: 'Product Manager', + image: 'assets/images/front-pages/user5.jpg' + }, + { + id: 6, + name: 'Leo Pratt', + position: 'Lead Developer', + image: 'assets/images/front-pages/user3.jpg' + }, + { + id: 7, + name: 'C. A. Nunez', + position: 'CEO & Co-Founder', + image: 'assets/images/front-pages/user2.jpg' + }, + { + id: 8, + name: 'Leo Maxwell', + position: 'Lead Developer', + image: 'assets/images/front-pages/user1.jpg' + } +]; \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.html new file mode 100644 index 0000000..b50b52c --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.html @@ -0,0 +1,603 @@ +
+
+
+
+
+

+ Most powerful & + developer friendly + dashboard +

+
+
+
+ @if(!isMobileView){ + +
+ banner-top-left +
+ } + +
+
+
+ +
+ 52,589+ developers & agencies using our templates +
+
+
+
+ Login +
+ + See how it works +
+
+
+ @for (framework of frameworks; track framework.tooltip) { + + + + } +
+
+ @if(!isMobileView){ +
+ banner-top-right +
+ + } +
+ @if (!isMobileView) { +
+
+ bottom-part +
+
+ } +
+
+ +
+
+
+
+

+ Introducing Modernize's Light & Dark Skins, Exceptional Dashboards, + and Dynamic Pages - Stay Updated on What's New! +

+
+
+ + + + + @if (!isMobileView) { +
+ +
+
+ @for (topcard of topcards; track topcard.title) { + @if (topcard.title === 'Light & Dark Color Schemes' || topcard.title.includes('12+')) { + + + @if (topcard.title === 'Light & Dark Color Schemes') { + icon + } +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+ @if (topcard.title.includes('12+')) { + image + } +
+
+ } + } +
+
+
+
+ @for (topcard of topcards; track topcard.title) + { + @if + (topcard.title.includes('New Demos')) { + + + icon +

{{ topcard.title }}

+

+ demo +
+
+ } } +
+
+ + +
+
+ @for (topcard of topcards; track topcard.title) { + @if (topcard.title.includes('Code Improvements') || topcard.title.includes('UI Components')) { + + + icon +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+
+
+ } + } +
+
+ +
+ } + + + @else { +
+ @for (topcard of topcards; track topcard.title) { + @if (!topcard.title.includes('New Demos')) { + + + @if (!topcard.title.includes('12+')) { + icon + } +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+ + @if (topcard.title.includes('12+')) { + image + } +
+
+ } + } +
+ + +
+ @for (topcard of topcards; track topcard.title) + { + @if + (topcard.title.includes('New Demos')) { + + + icon +
{{ topcard.title }}
+

+ demo +
+
+ } } +
+ } + + +
+
+ +
+ +
+ + + + + Team Scheduling + + + + + + Payments + + + + + + Embedding + + + + + + Workflows + + + + + + +
+
+
+ slider-group +
+
+ +
+
+

Defend your focus

+
+ + + + +
+ Factor in outside colleagues + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+ + + + +
+ Combine teammate schedules + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+ + + + +
+ Round robin pooling + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+
+
+ + Learn More +
+ + +
+
+
+
+ +
+ +
+ +
+
+
+ + + Save valuable time and effort spent searching for a solution. + Contact us now + +
+
+
+ +
+
+
+
+

+ Discover Powerful Dozens of
Purpose-Fit Templates +

+
+
+
+
+ + slide + +
+
+
+
+ + slide + +
+
+
+
+ + slide + +
+
+
+
+ slide +
+
+
+
+ + slide + +
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+
+
+

High Customizability

+

+ Tailor the dashboard to your exact needs. Customize layouts, color + schemes, and widgets effortlessly for a personalized user + experience. +

+
+
+

Powerful Data Analytics

+

+ Unlock the true potential of your data with our advanced analytics + tools. Gain valuable insights and make data-driven decisions with + ease. +

+
+ +
+

Interactive Charts

+

+ Visualize complex data sets beautifully with our interactive + graphs and charts. Quickly grasp trends and patterns for smarter + analysis. +

+
+
+
+
+
+
+ +
+
+
+ +
+
+

+ What our clients
think logo + about us? +

+

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+
+
+
+ + + Features availability + +
+
+ +
+
{{ currentUser().name }}
+
+ +

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+ + + +
+ + + {{ displayCount() }} + + +
+
+
+
+
+
+
+ +
+
+
+
+
+

+ Enjoy unparalleled features & exceptional flexibility. +

+
+
+ +
+
+
+ @for (followercard of followercardsfirst; track followercard.title) + { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+ @for (followercard of followercardsecond; track followercard.title) + { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+ @for (followercard of followercardthird; track followercard.title) { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+
+
+ +
+
+

Frequently Asked Questions

+
+
+ + @for (item of faqList; track item) { + + + {{ + item.question + }} + + + + + +

{{ item.answer }}

+
+ } +
+
+
+
+
+ Still have a question? + Ask on discord + or + Submit a ticket +
+
+
+
+ + + +
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.scss new file mode 100644 index 0000000..e6e0f4b --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.scss @@ -0,0 +1,189 @@ +.home-page { + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } + + .home-page-header { + + .header-container-content { + + .cardPosition { + .float-image { + animation: floatUpDown 6s ease-in-out infinite; + } + } + + .cardPositionTwo { + + .float-image { + animation: floatUpDown 6s ease-in-out infinite; + } + } + + .loginBtn { + .play-button { + background-color: transparent; + border: 2px solid var(--mat-sys-primary); // or use your theme color + color: var(--mat-sys-primary); + box-shadow: none; + } + + .textSee { + cursor: pointer; + + &:hover { + color: var(--mat-sys-primary); + } + } + } + } + } + + .dashboardCards { + + .card-container { + + mat-card-content { + padding: 0px !important; + } + } + } + + .tab-header { + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + + .profileTabs { + background-color: var(--mdc-elevated-card-container-color) !important; + + .mat-mdc-tab.mdc-tab-indicator--active { + .mdc-tab__text-label { + color: var(--mat-sys-primary); + } + } + } + + } + + .template-slider { + .template-slider-content { + .demo-slider { + .demo-slide { + animation: slide3d 15s linear infinite; + } + } + } + } + + .features { + + .cardWithShadow { + mat-card-content { + padding: 0px !important; + } + } + } + + .exceptional { + .exceptional-content { + .demo-slider { + .demo-slide { + animation: slide3d 20s linear infinite; + } + + .demo-slide-two { + animation: slide3dTwo 20s linear infinite; + } + } + } + } + + .expansion-panel { + box-shadow: none; + background: transparent; + border-radius: 0 !important; + border-bottom: 1px solid var(--mat-sys-outline); + + .mat-expansion-panel-header { + padding: 18px 0 !important; + height: auto; + } + } + + .sliderImg { + max-width: 380px; + height: 300px; + } + + .img-border { + border: 2px solid var(--mat-sys-secondary); + /* Blue border, change color as needed */ + cursor: pointer; + } + + .img-border:hover { + border-color: var(--mat-sys-secondary); + } + + .border-dash { + border: 1px dashed var(--mat-sys-outline); // Initial border color (Bootstrap primary) + transition: border-color 0.3s ease; + flex-wrap: wrap; + + &:hover { + border-color: var(--mat-sys-primary); // Use your Angular Material primary variable or a custom color + } + } + + .faq-accordion { + .mat-expansion-panel { + border-radius: 8px !important; + + .mat-expansion-panel-header { + padding: 20px 21px !important; + } + } + } +} + +@keyframes floatUpDown { + + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(-6px); // smaller bounce + } +} + +@keyframes slide3d { + from { + transform: translate3d(0, 0, 0); + } + + to { + transform: translate3d(-2028px, 0, 0); // adjust based on actual slide width + } +} + +@keyframes slide3dTwo { + from { + transform: translate3d(-2028px, 0, 0); // Rightward (starts left) + } + + to { + transform: translate3d(0, 0, 0); + } +} + + + +@media (max-width: 1199px) { + .home-page-header { + padding-bottom: 48px; + } +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts new file mode 100644 index 0000000..52b6227 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HomepageDetailsComponent } from './homepage-details.component'; + +describe('HomepageDetailsComponent', () => { + let component: HomepageDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HomepageDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HomepageDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.ts new file mode 100644 index 0000000..46f68e1 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/homepage-details/homepage-details.component.ts @@ -0,0 +1,131 @@ +import { Component, computed, DestroyRef, inject, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { + faqList, + followercardsFirst, + followercardSecond, + followercardThird, + frameworks, + tiles, + users, + topcardsGrid, +} from '../front-pagesData'; +import { CommonModule } from '@angular/common'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { ImageSliderComponent } from '../image-slider/image-slider.component'; +import { FooterComponent } from '../footer/footer.component'; +import { MatDialog } from '@angular/material/dialog'; +import { TemplateVideoComponent } from '../template-video/template-video.component'; +import { Router, RouterModule } from '@angular/router'; + + +@Component({ + selector: 'app-homepage-details', + imports: [ + MaterialModule, + IconModule, + CommonModule, + ImageSliderComponent, + FooterComponent, + RouterModule + ], + templateUrl: './homepage-details.component.html', + styleUrl: './homepage-details.component.scss', +}) +export class HomepageDetailsComponent { + + topcards=topcardsGrid; + + + centered = false; + disabled = false; + unbounded = false; + radius: number; + color: string; + showBackground: boolean = false; + frameworks = frameworks; + selectedIndex = 1; + + readonly dialog = inject(MatDialog); + private router = inject(Router); + private destroyRef = inject(DestroyRef); // ✅ For automatic cleanup + private mediaMatcher = inject(MediaMatcher); // ✅ Proper MediaMatcher injection + + mobileQuery: MediaQueryList; + isMobileView = false; + + readonly panelOpenState = signal(false); + tiles = tiles; + hideCloserBtn: boolean = true; + users = users; + expandedIndex: number | null = null; + currentIndex = signal(0); // Starting from 0 + faqList = faqList; + selectedPath: string | null = null; + clicked = false; + + followercardsfirst = followercardsFirst; + followercardsecond = followercardSecond; + followercardthird = followercardThird; + + currentUser = computed(() => this.users[this.currentIndex()]); + displayCount = computed(() => `${this.currentIndex() + 1}/${this.users.length}`); + + constructor() { + const isSmallScreen = this.mediaMatcher.matchMedia('(max-width: 599px)'); + // ✅ Setup media query for max-width: 1199px + this.mobileQuery = this.mediaMatcher.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + const listener = (e: MediaQueryListEvent) => { + this.isMobileView = e.matches; + }; + + // ✅ Listen to viewport changes + this.mobileQuery.addEventListener('change', listener); + + // ✅ Clean up listener on component destroy + this.destroyRef.onDestroy(() => { + this.mobileQuery.removeEventListener('change', listener); + }); + } + isOver(): boolean { + return this.mediaMatcher.matchMedia('(max-width: 1199px)').matches; + } + + goPrev() { + if (this.currentIndex() > 0) { + this.currentIndex.update((i) => i - 1); + } + } + + goNext() { + if (this.currentIndex() < this.users.length - 1) { + this.currentIndex.update((i) => i + 1); + } + } + openDialog(showBackground:boolean){ + this.showBackground = showBackground; + + const dialogRef = this.dialog.open(TemplateVideoComponent, { + data: {}, + width: '1000px', + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result === false) { + this.showBackground = false; // Reset or take any action + } + }); + } + + + onImageClick(path: string) { + this.selectedPath = path; + + setTimeout(() => { + this.router.navigate([path]); + }, 100); // brief delay to show border + } +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/homepage/homepage.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/homepage/homepage.component.html new file mode 100644 index 0000000..532acf0 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/homepage/homepage.component.html @@ -0,0 +1,137 @@ +
+ + + @if(hideCloserBtn){ + + + + +
+ New + Frontend Pages Included! +
+ + + + +
+ + } + +
+
+
+ +
+ + @if(!isMobileView){ +
+ + + + + + + + +
+ Login + } @if(isMobileView){ + + } +
+
+
+ +
+ +
+
+ + + +
+
+ +
+
+ + + + + + + + + + + + + + + + + Get + Started + +
+
+
+
+ @if(showBackToTop){ +
+ +
+ } +
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/homepage/homepage.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/homepage/homepage.component.scss new file mode 100644 index 0000000..3cee318 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/homepage/homepage.component.scss @@ -0,0 +1,32 @@ +.landing-page { + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } + + .heightToolbar { + height: 46px; + background-size: cover; + background-repeat: no-repeat; + background-image: url(../../../../assets/images/front-pages/topbar-bg.png); + } + + .toolBarContent { + .nav-item { + &.selected { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); // optional for visibility + transition: background-color 0.3s ease; + } + + &:hover { + color: var(--mat-sys-primary); + transition: color 0.3s ease; + } + } + + } + +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/homepage/homepage.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/homepage/homepage.component.ts new file mode 100644 index 0000000..ca1a34a --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/homepage/homepage.component.ts @@ -0,0 +1,65 @@ +import { MediaMatcher } from '@angular/cdk/layout'; +import { CommonModule } from '@angular/common'; +import { Component, HostListener, inject, ViewChild } from '@angular/core'; +import { MatSidenav } from '@angular/material/sidenav'; +import { ActivatedRoute, Router, RouterLink, RouterOutlet } from '@angular/router'; +import { IconModule } from 'src/app/icon/icon.module'; +import { BrandingComponent } from 'src/app/layouts/full/vertical/sidebar/branding.component'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-homepage', + imports: [MaterialModule, BrandingComponent, RouterLink, + IconModule, RouterOutlet, CommonModule], + templateUrl: './homepage.component.html', + styleUrl: './homepage.component.scss' +}) +export class HomepageComponent { + @ViewChild('customizerRight') customizerRight!: MatSidenav; + selected: string = ''; // default selected + mobileQuery: MediaQueryList; + isMobileView = false; + hideCloserBtn: boolean = true; + private router = inject(Router) + private mediaMatcher: MediaQueryList = matchMedia(`(max-width: 1199px)`); + showBackToTop: boolean; + isTopbarFixed: boolean; + constructor(private route: ActivatedRoute) { + const media = inject(MediaMatcher); + this.mobileQuery = media.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + this.mobileQuery.addEventListener('change', (e) => { + + this.isMobileView = e.matches; + this.closeSidenavIfNeeded(); + }); + } + closeSidenavIfNeeded() { + if (!this.isMobileView && this.customizerRight?.opened) { + this.customizerRight.close(); + } + } + isOver(): boolean { + return this.mediaMatcher.matches; + } + + isActiveRoute(route: string): boolean { + return this.router.url.includes(`/front-pages/${route}`); + } + hideCloser() { + this.hideCloserBtn = false; + } + getNavigate() { + this.router.navigate(['/dashboards/dashboard1']) + } + + scrollToTop(): void { + window.scrollTo({ top: 0, behavior: 'smooth' }); + } + @HostListener('window:scroll', []) + onWindowScroll() { + this.showBackToTop = window.scrollY > 300; + this.isTopbarFixed = scrollY > 45; + } +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.html new file mode 100644 index 0000000..f4c4b31 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.html @@ -0,0 +1,44 @@ +
+
+
+
+
+

Our leadership

+
+

+ Our robust analytics offer rich insights into the information + buyers want, informing where teams +

+
+
+ +
+
+ + +
+
+
+ +
+ @for (member of visibleTeamMembers(); track member.id){ +
+ + + imgSrc + + +

{{ member.name }}

+

{{ member.position }}

+
+
+
+ } +
+
+
+
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.scss new file mode 100644 index 0000000..0832285 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.scss @@ -0,0 +1,22 @@ +.img-slider-content { + .img-slider { + + .mat-mdc-card { + margin-bottom: 0px !important; + } + + .productcard { + position: relative; + + .info-card { + bottom: 42px; // controls overlap depth + left: 50%; + transform: translateX(-50%); + width: 90%; + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + z-index: 2; + } + } + + } +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts new file mode 100644 index 0000000..c933f20 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ImageSliderComponent } from './image-slider.component'; + +describe('ImageSliderComponent', () => { + let component: ImageSliderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ImageSliderComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ImageSliderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.ts new file mode 100644 index 0000000..d5db5ee --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/image-slider/image-slider.component.ts @@ -0,0 +1,39 @@ +import { Component, computed, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { team } from '../front-pagesData'; + +@Component({ + selector: 'app-image-slider', + imports: [MaterialModule,IconModule], + templateUrl: './image-slider.component.html', + styleUrl: './image-slider.component.scss' +}) +export class ImageSliderComponent { + team = team; + // Signals + currentPage = signal(0); + pageSize = 4; + + visibleTeamMembers = computed(() => { + const start = this.currentPage() * this.pageSize; + const end = start + this.pageSize; + return this.team.slice(start, end); + }); + + next() { + console.log('next--->',this.visibleTeamMembers().map(m => m.id)); + const totalPages = Math.ceil(this.team.length / this.pageSize); + if (this.currentPage() < totalPages - 1) { + this.currentPage.update((p) => p + 1); + } + } + + prev() { + console.log(this.visibleTeamMembers().map(m => m.id)); + if (this.currentPage() > 0) { + this.currentPage.update((p) => p - 1); + } + } + +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.html new file mode 100644 index 0000000..32bdd60 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.html @@ -0,0 +1,68 @@ +
+
+

+ 111,476+ Trusted developers & many tech giants as well +

+
+
+
+ @for(plan of plans;track plan){ +
+ + + +
+
+ {{ plan.title }} + @if (plan.popular) { + + Popular + + } +
+
+

{{ plan.description }}

+ + +
+ ${{ plan.price }} + /{{ plan.period }} +
+
+ @for(feature of plan.features; track feature) { +
+ icon-facebook-dark + + + {{ feature.text }} + +
+ } +
+ + +
+
+ +
+ } + + +
+
+

Secured payment with PayPal & Razorpay

+
+ @for( logo of paymentLogos;track logo){ + + } +
+
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts new file mode 100644 index 0000000..fb0a9c8 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PagePricingComponent } from './page-pricing.component'; + +describe('PagePricingComponent', () => { + let component: PagePricingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PagePricingComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PagePricingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.ts new file mode 100644 index 0000000..7a435ae --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/page-pricing/page-pricing.component.ts @@ -0,0 +1,17 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { paymentLogos, plans } from '../front-pagesData'; + +@Component({ + selector: 'app-page-pricing', + imports: [MaterialModule, IconModule, CommonModule], + templateUrl: './page-pricing.component.html', + styleUrl: './page-pricing.component.scss', +}) +export class PagePricingComponent { + plans = plans; + + paymentLogos = paymentLogos; +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.html new file mode 100644 index 0000000..f64670b --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.html @@ -0,0 +1,57 @@ + + +
+
+
+
+
Portfolio
+
+
{{ filteredCount }}
+
+
+ + + + search + + +
+
+ @for(productcard of filteredCardImgs; track productcard.id) { +
+ + + imgSrc + + + +
+ +
+
{{ productcard.title }}
+

{{ productcard.date }}

+
+ + + +
+
+
+
+
+ } +
+
+
+ \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts new file mode 100644 index 0000000..073ce35 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PortfolioComponent } from './portfolio.component'; + +describe('PortfolioComponent', () => { + let component: PortfolioComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PortfolioComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PortfolioComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.ts new file mode 100644 index 0000000..702ebee --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/portfolio/portfolio.component.ts @@ -0,0 +1,37 @@ + + +import { Component, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { productcards } from '../front-pagesData'; +import { FooterComponent } from '../footer/footer.component'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-portfolio', + imports: [MaterialModule, IconModule, FooterComponent, CommonModule, FormsModule], + templateUrl: './portfolio.component.html', + styleUrl: './portfolio.component.scss' +}) +export class PortfolioComponent implements OnInit { + + filteredCards = productcards; + + searchText: string = ''; + + filteredCardImgs = [...this.filteredCards]; // Initialize with full data + filteredCount: number = this.filteredCardImgs.length; + ngOnInit(): void { + console.log('filteredCards', this.filteredCards) + } + onSearchChange() { + const query = this.searchText.toLowerCase().trim(); + this.filteredCardImgs = this.filteredCards.filter(item => + item.title.toLowerCase().includes(query) || + item.date.toLowerCase().includes(query) + ); + this.filteredCount = this.filteredCardImgs.length; // ✅ update the count here + } +} + diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.html new file mode 100644 index 0000000..6c42e4a --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.html @@ -0,0 +1,18 @@ + + +
+
+ +
+
+ + \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.spec.ts new file mode 100644 index 0000000..147f94e --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PricingComponent } from './pricing.component'; + +describe('PricingComponent', () => { + let component: PricingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PricingComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PricingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.ts new file mode 100644 index 0000000..0684d59 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/pricing/pricing.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; +import { PagePricingComponent } from '../page-pricing/page-pricing.component'; + +@Component({ + selector: 'app-pricing', + imports: [MaterialModule,IconModule,FooterComponent,PagePricingComponent], + templateUrl: './pricing.component.html', + styleUrl: './pricing.component.scss' +}) +export class PricingComponent { + +} diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.html b/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.html new file mode 100644 index 0000000..9b7d777 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.html @@ -0,0 +1,11 @@ + + + +
+ + +
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.scss b/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.spec.ts b/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.spec.ts new file mode 100644 index 0000000..46d7589 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TemplateVideoComponent } from './template-video.component'; + +describe('TemplateVideoComponent', () => { + let component: TemplateVideoComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TemplateVideoComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TemplateVideoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.ts b/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.ts new file mode 100644 index 0000000..b239adb --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/front-pages/template-video/template-video.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { MatDialogRef } from '@angular/material/dialog'; +@Component({ + selector: 'app-template-video', + imports: [MaterialModule, + IconModule,], + templateUrl: './template-video.component.html', + styleUrl: './template-video.component.scss' +}) +export class TemplateVideoComponent { +constructor(private dialogRef: MatDialogRef){ + +} +closeDialog(): void { + this.dialogRef.close(false); // Pass false back to parent +} +} diff --git a/theme/packages/minisidebar/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts b/theme/packages/minisidebar/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts new file mode 100644 index 0000000..de7ba0c --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts @@ -0,0 +1,69 @@ +export const BASIC_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + + /** + * @title slide-toggle + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatSlideToggleModule], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + } +`; + +export const FORM_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component, inject} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {FormBuilder, FormGroup, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {MatButtonModule} from '@angular/material/button'; + import { MatSlideToggleModule} from '@angular/material/slide-toggle'; + + /** + * @title Slide-toggle with forms + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatSlideToggleModule, FormsModule, MatButtonModule, ReactiveFormsModule,], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + + private _formBuilder = inject(FormBuilder); + + isChecked = true; + formGroup = this._formBuilder.group({ + enableWifi: '', + acceptTerms: ['', Validators.requiredTrue], + }); + + alertFormValues(formGroup: FormGroup) { + alert(JSON.stringify(formGroup.value, null, 2)); + } + } +`; + +export const CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {MatCheckboxModule} from '@angular/material/checkbox'; + import {FormsModule} from '@angular/forms'; + import {MatRadioModule} from '@angular/material/radio'; + import {MatCardModule} from '@angular/material/card'; + + /** + * @title Configurable slide-toggle + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatCardModule, MatRadioModule, FormsModule, MatCheckboxModule, MatSlideToggleModule], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + + checked = false; + disabled = false; + } +`; \ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts b/theme/packages/minisidebar/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts new file mode 100644 index 0000000..804e79f --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts @@ -0,0 +1,63 @@ +import { Component, OnInit, inject } from '@angular/core'; +import {FormBuilder, FormGroup, Validators, ReactiveFormsModule} from '@angular/forms'; +import { + MatSlideToggleModule, + // _MatSlideToggleRequiredValidatorModule, +} from '@angular/material/slide-toggle'; +import {MatCheckboxModule} from '@angular/material/checkbox'; +import {FormsModule} from '@angular/forms'; +import {MatRadioModule} from '@angular/material/radio'; +import {MatCardModule} from '@angular/material/card'; +import {MatButtonModule} from '@angular/material/button'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_SLIDE_TOGGLE_HTML_SNIPPET, CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET, FORM_SLIDE_TOGGLE_HTML_SNIPPET } from './code/slide-toggle-html-snippet'; +import { BASIC_SLIDE_TOGGLE_TS_SNIPPET, CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET, FORM_SLIDE_TOGGLE_TS_SNIPPET } from './code/slide-toggle-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-slide-toggle', + imports: [MatCardModule, MatRadioModule, FormsModule, MatCheckboxModule, MatSlideToggleModule, ReactiveFormsModule, MatButtonModule, + // _MatSlideToggleRequiredValidatorModule + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './slide-toggle.component.html' +}) +export class AppSlideToggleComponent implements OnInit { + + // 1 [Basic with Slide Toggle] + codeForSlideToggleBasic = BASIC_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleBasicTs = BASIC_SLIDE_TOGGLE_TS_SNIPPET; + + // 2 [Form with Slide Toggle] + codeForSlideToggleForm = FORM_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleFormTs = FORM_SLIDE_TOGGLE_TS_SNIPPET; + + // 3 [Configuration with Slide Toggle] + codeForSlideToggleConfiguration = CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleConfigurationTs = CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET; + + // configuration + checked = false; + disabled = false; + + private _formBuilder = inject(FormBuilder); + + isChecked = true; + formGroup = this._formBuilder.group({ + enableWifi: '', + acceptTerms: ['', Validators.requiredTrue], + }); + + alertFormValues(formGroup: FormGroup) { + alert(JSON.stringify(formGroup.value, null, 2)); + } + + ngOnInit(): void {} +} diff --git a/theme/packages/minisidebar/src/app/pages/widgets/cards/cards.component.html b/theme/packages/minisidebar/src/app/pages/widgets/cards/cards.component.html new file mode 100644 index 0000000..051c1c9 --- /dev/null +++ b/theme/packages/minisidebar/src/app/pages/widgets/cards/cards.component.html @@ -0,0 +1,348 @@ + + + + +
+ @for(topcard of topcards; track topcard) { +
+ + + users +

+ {{ topcard.title }} +

+
+ {{ topcard.subtitle }} +
+
+
+
+ } +
+ + + + +
+ @for(cardimg of cardimgs; track cardimg.imgSrc) { +
+ + Photo of a Shiba Inu +
+ {{ + cardimg.time + }} +
+ + +
+
+ +
+ {{ + cardimg.category + }} +
+ {{ cardimg.title }} +
+
+ {{ cardimg.views }} + {{ cardimg.comments }} +
+ + + {{ cardimg.date }} + +
+
+
+
+ } +
+ + + + +
+ @for(productcard of productcards; track productcard.title) { +
+ + + imgSrc + + + + {{ + productcard.title + }} +
+
+
${{ productcard.price }}
+ ${{ productcard.rprice }} +
+
+ + + + + +
+
+
+
+
+ } +
+ + + + +
+ @for(musiccard of musiccards; track musiccard.title) { +
+ +
+
+
{{ musiccard.title }}
+ {{ musiccard.subtext }} + +
+ + + +
+
+
+ blog +
+
+
+
+ } +
+ + + + +
+ @for(followercard of followercards; track followercard.title) { +
+ + +
+
+ user +
+
{{ followercard.title }}
+ {{ followercard.subtext }} +
+
+ +
+
+
+
+ } +
+ + + + +
+ @for(friendcard of friendcards; track friendcard.title) { +
+ + + user + {{ friendcard.title }} +
+
+ user + user + user +
+ 3 mutual friends +
+ + +
+
+
+ } +
+ + + + +
+ @for(socialcard of socialcards; track socialcard.username) { +
+ + + + {{ + socialcard.username + }} + {{ + socialcard.post + }} + +
+ + + + +
+
+
+ } +
+ + + + +
+ @for(giftcard of giftcards; track giftcard.username) { +
+ + +
+ {{ + giftcard.username + }} + +
+ + user + + +
+
+
+ } +
+ +
+ +
+ + + Payment Gateways + Platform For Income + + @for(stat of stats; track stat.title) { +
+
+ + icon + + +
+
{{ stat.title }}
+ {{ stat.subtitle }} +
+ +${{ stat.percent }} +
+
+ } + + +
+
+
+ + +
+ + + Upcoming Activity + In New year + + @for(activity of activities; track activity.title) { +
+
+ + + + +
+
{{ activity.title }}
+ {{ activity.subtitle }} +
+ {{ activity.time }} +
+
+ } +
+
+
+ + +
+ + + Recent Transactions + +
+ @for(stat of stats2; track stat.subtext) { +
+
{{ stat.time }}
+
+ + +
+
+ @if(stat.subtext) { + {{ stat.subtext }} + } + + @if(stat.title) { + {{ + stat.title + }} + } + + @if(stat.link) { + #ML-3467 + } +
+
+ } +
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/minisidebar/src/app/services/apps/front-pages/front-end.service.spec.ts b/theme/packages/minisidebar/src/app/services/apps/front-pages/front-end.service.spec.ts new file mode 100644 index 0000000..950ecc8 --- /dev/null +++ b/theme/packages/minisidebar/src/app/services/apps/front-pages/front-end.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { FrontEndService } from './front-end.service'; + +describe('FrontEndService', () => { + let service: FrontEndService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(FrontEndService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/theme/packages/minisidebar/src/app/services/apps/front-pages/front-end.service.ts b/theme/packages/minisidebar/src/app/services/apps/front-pages/front-end.service.ts new file mode 100644 index 0000000..a736e66 --- /dev/null +++ b/theme/packages/minisidebar/src/app/services/apps/front-pages/front-end.service.ts @@ -0,0 +1,21 @@ +import { Injectable, signal } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class FrontEndService { + + private blog = signal(null); + + constructor() { } + + + + setBlog(blogData: any) { + this.blog.set(blogData); + } + + getBlog() { + return this.blog; + } +} diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/app-chat.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/app-chat.jpg new file mode 100644 index 0000000..cffde47 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/app-chat.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/app-email.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/app-email.jpg new file mode 100644 index 0000000..5da2d90 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/app-email.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/banner-top-left.svg b/theme/packages/minisidebar/src/assets/images/front-pages/banner-top-left.svg new file mode 100644 index 0000000..0b5d123 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/banner-top-left.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/banner-top-right.svg b/theme/packages/minisidebar/src/assets/images/front-pages/banner-top-right.svg new file mode 100644 index 0000000..ce2deff --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/banner-top-right.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/bottom-part.svg b/theme/packages/minisidebar/src/assets/images/front-pages/bottom-part.svg new file mode 100644 index 0000000..0a9f8f9 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/bottom-part.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/demo-dark.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/demo-dark.jpg new file mode 100644 index 0000000..1181c96 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/demo-dark.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/demo-horizontal.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/demo-horizontal.jpg new file mode 100644 index 0000000..a384d56 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/demo-horizontal.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/demo-main.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/demo-main.jpg new file mode 100644 index 0000000..895551e Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/demo-main.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/demo-rtl.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/demo-rtl.jpg new file mode 100644 index 0000000..a8011a3 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/demo-rtl.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/design-collection.png b/theme/packages/minisidebar/src/assets/images/front-pages/design-collection.png new file mode 100644 index 0000000..08a4a50 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/design-collection.png differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-american-express.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-american-express.svg new file mode 100644 index 0000000..0cc1e3c --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-american-express.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-chart.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-chart.svg new file mode 100644 index 0000000..fa45961 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-chart.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-circle-check.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-circle-check.svg new file mode 100644 index 0000000..458ffdb --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-circle-check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-circle-x.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-circle-x.svg new file mode 100644 index 0000000..41b5593 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-circle-x.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-color.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-color.svg new file mode 100644 index 0000000..14d5f1a --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-color.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-components.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-components.svg new file mode 100644 index 0000000..a14b4e4 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-components.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-customize.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-customize.svg new file mode 100644 index 0000000..300ee35 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-customize.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-diners.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-diners.svg new file mode 100644 index 0000000..4ea5609 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-diners.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-discover.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-discover.svg new file mode 100644 index 0000000..12eebd5 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-discover.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-facebook.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-facebook.svg new file mode 100644 index 0000000..d0cfd8a --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-facebook.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-favorites.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-favorites.svg new file mode 100644 index 0000000..84fedaa --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-favorites.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-framework.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-framework.svg new file mode 100644 index 0000000..2718d0c --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-framework.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-icons.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-icons.svg new file mode 100644 index 0000000..87d1ae4 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-icons.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-instagram.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-instagram.svg new file mode 100644 index 0000000..6a73bf9 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-instagram.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-jcb.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-jcb.svg new file mode 100644 index 0000000..b71e935 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-jcb.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-masetro.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-masetro.svg new file mode 100644 index 0000000..5a84358 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-masetro.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-mastercard.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-mastercard.svg new file mode 100644 index 0000000..da591ae --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-mastercard.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-pages.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-pages.svg new file mode 100644 index 0000000..ac7ca4b --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-pages.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-paypal.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-paypal.svg new file mode 100644 index 0000000..7f8de85 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-paypal.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-responsive.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-responsive.svg new file mode 100644 index 0000000..fc57366 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-responsive.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-sass.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-sass.svg new file mode 100644 index 0000000..5751e1a --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-sass.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-sidebar.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-sidebar.svg new file mode 100644 index 0000000..1a0ca63 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-sidebar.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-speech-bubble.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-speech-bubble.svg new file mode 100644 index 0000000..2e1f2bd --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-speech-bubble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-support.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-support.svg new file mode 100644 index 0000000..6aa77a3 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-support.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-table.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-table.svg new file mode 100644 index 0000000..3fd98d7 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-table.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-twitter.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-twitter.svg new file mode 100644 index 0000000..e0b7780 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-twitter.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-update.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-update.svg new file mode 100644 index 0000000..94b5ed9 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-update.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/icon-visa.svg b/theme/packages/minisidebar/src/assets/images/front-pages/icon-visa.svg new file mode 100644 index 0000000..7a06b63 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/icon-visa.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/logoIcon.svg b/theme/packages/minisidebar/src/assets/images/front-pages/logoIcon.svg new file mode 100644 index 0000000..90fdce0 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/front-pages/logoIcon.svg @@ -0,0 +1,11 @@ + + logoIcon + + + + + + \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/topbar-bg.png b/theme/packages/minisidebar/src/assets/images/front-pages/topbar-bg.png new file mode 100644 index 0000000..e11b4a5 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/topbar-bg.png differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/user1.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/user1.jpg new file mode 100644 index 0000000..eb505b5 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/user1.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/user2.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/user2.jpg new file mode 100644 index 0000000..f8aa6af Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/user2.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/user3.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/user3.jpg new file mode 100644 index 0000000..6478013 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/user3.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/user4.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/user4.jpg new file mode 100644 index 0000000..e599b2a Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/user4.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/front-pages/user5.jpg b/theme/packages/minisidebar/src/assets/images/front-pages/user5.jpg new file mode 100644 index 0000000..494e402 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/front-pages/user5.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/landingpage/background/accordian1.jpg b/theme/packages/minisidebar/src/assets/images/landingpage/background/accordian1.jpg new file mode 100644 index 0000000..d13def2 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/landingpage/background/accordian1.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/landingpage/background/design-collection.png b/theme/packages/minisidebar/src/assets/images/landingpage/background/design-collection.png new file mode 100644 index 0000000..2886a14 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/landingpage/background/design-collection.png differ diff --git a/theme/packages/minisidebar/src/assets/images/landingpage/background/feature-apps.png b/theme/packages/minisidebar/src/assets/images/landingpage/background/feature-apps.png new file mode 100644 index 0000000..fef18c5 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/landingpage/background/feature-apps.png differ diff --git a/theme/packages/minisidebar/src/assets/images/landingpage/background/screen1.png b/theme/packages/minisidebar/src/assets/images/landingpage/background/screen1.png new file mode 100644 index 0000000..afd642a Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/landingpage/background/screen1.png differ diff --git a/theme/packages/minisidebar/src/assets/images/landingpage/frameworks/angular.svg b/theme/packages/minisidebar/src/assets/images/landingpage/frameworks/angular.svg new file mode 100644 index 0000000..bf081ac --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/landingpage/frameworks/angular.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/theme/packages/minisidebar/src/assets/images/landingpage/frameworks/icon-tabler.svg b/theme/packages/minisidebar/src/assets/images/landingpage/frameworks/icon-tabler.svg new file mode 100644 index 0000000..6e6810e --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/landingpage/frameworks/icon-tabler.svg @@ -0,0 +1,3 @@ + + + diff --git a/theme/packages/minisidebar/src/assets/images/landingpage/frameworks/material.svg b/theme/packages/minisidebar/src/assets/images/landingpage/frameworks/material.svg new file mode 100644 index 0000000..9ac2836 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/images/landingpage/frameworks/material.svg @@ -0,0 +1 @@ +material \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/images/profile/user-11.jpg b/theme/packages/minisidebar/src/assets/images/profile/user-11.jpg new file mode 100644 index 0000000..8d54dc0 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/profile/user-11.jpg differ diff --git a/theme/packages/minisidebar/src/assets/images/profile/user-12.jpg b/theme/packages/minisidebar/src/assets/images/profile/user-12.jpg new file mode 100644 index 0000000..adbbde4 Binary files /dev/null and b/theme/packages/minisidebar/src/assets/images/profile/user-12.jpg differ diff --git a/theme/packages/minisidebar/src/assets/scss/_container.scss b/theme/packages/minisidebar/src/assets/scss/_container.scss new file mode 100644 index 0000000..730c06f --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/_container.scss @@ -0,0 +1,154 @@ +@use "variables" as *; + +*, +:after, +:before { + box-sizing: border-box; +} + +body { + font-family: $font-family; + line-height: 1.334rem; + overflow-x: hidden; + color: var(--mat-sys-on-background); +} + +.mainWrapper { + display: flex; + min-height: 100vh; + width: 100%; + flex: 1; + height: 100%; +} + +.container { + max-width: 1200px; + padding-left: 24px; + padding-right: 24px; + margin: 0 auto; + + &.full-width { + display: flex; + align-items: center; + width: 100%; + } +} + +.pageWrapper { + padding: 24px; + min-height: calc(100vh - 70px); + + margin: 0 auto; + + &.maxWidth { + max-width: $boxedWidth; + } +} + +.w-100 { + width: 100%; +} + +.h-100 { + height: 100%; +} + +.shadow-none { + box-shadow: none !important; +} + +.rounded { + border-radius: $border-radius !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 25px !important; +} + +.overflow-hidden { + overflow: hidden; +} + +.text-decoration-none { + text-decoration: none; +} + +.position-relative { + position: relative; +} + +.table-responsive { + overflow-x: auto; + + td, + mat-cell { + white-space: nowrap; + padding: 16px; + } +} + +.op-5 { + opacity: 0.5; +} + +.cursor-pointer { + cursor: pointer; +} + +.avatar-group { + img { + border: 2px solid $white; + margin-right: -5px; + + &:last-child { + margin-right: 0; + } + } +} + +a { + color: var(--mat-sys-on-background); + + &:hover { + color: $primary; + } +} + +.filter-sidebar { + width: 290px; + position: fixed; + right: -290px; + top: 0; + z-index: 10; + height: 100%; + transition: all 0.3s ease-in-out; + box-shadow: var(--mat-sys-level3); + background-color: var(--mat-sys-background); + + &.open { + right: 0; + } +} + +pre { + margin: 0; + white-space: nowrap; +} + +td.hljs-ln-line.hljs-ln-numbers { + padding-right: 10px; +} + +@media (min-width: 768px) { + html .flex-sm-row { + flex-direction: row !important; + } +} + +.mat-drawer[style*="visibility: hidden"] { + display: none; +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/scss/apps/_contact-list.scss b/theme/packages/minisidebar/src/assets/scss/apps/_contact-list.scss new file mode 100644 index 0000000..9cf1b85 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/apps/_contact-list.scss @@ -0,0 +1,59 @@ +@use "../variables" as *; + +@media (max-width: 1279px) { + .detail-part.movetodetail { + display: block; + position: absolute; + z-index: 9; + left: 0; + background: var(--mat-card-elevated-container-color); + } +} + +@media (max-width: 1279px) { + .welcome-app { + display: none; + } +} + +@media (max-width: 959px) { + .contact-detail-part { + display: none; + } + + .contact-detail-part.activeContact { + position: absolute !important; + top: 0; + left: 0; + display: block; + width: 100%; + height: 100%; + z-index: 999; + background-color: var(--mat-card-elevated-container-color); + } +} + +// contact app +.uploader { + .upload-image { + width: 100px; + height: auto; + cursor: pointer; + } + + input[type="file"] { + position: absolute; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + } +} + +.contact-listing { + .mdc-list-item__primary-text { + margin-bottom: -11px !important; + margin-top: 10px !important; + } +} diff --git a/theme/packages/minisidebar/src/assets/scss/apps/_ecommerce.scss b/theme/packages/minisidebar/src/assets/scss/apps/_ecommerce.scss new file mode 100644 index 0000000..467169d --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/apps/_ecommerce.scss @@ -0,0 +1,94 @@ +body { + + // Add Product + + .NgxEditor__Wrapper { + border: 1px solid var(--mat-sys-outline-variant); + } + + .NgxEditor__Seperator { + border-left: 1px solid var(--mat-sys-outline-variant); + } + + .NgxEditor__MenuBar { + background-color: var(--mat-card-elevated-container-color); + border-bottom: 1px solid var(--mat-sys-outline-variant) !important; + } + + .NgxEditor { + background: var(--mat-card-elevated-container-color); + color: var(--mat-sys-on-background); + } + + .NgxEditor__MenuItem .NgxEditor__MenuItem--Icon:hover { + background-color: var(--mat-sys-primary); + color: var(--mat-sys-background); + } + + .NgxEditor__Dropdown:hover { + background-color: var(--mat-sys-primary); + + .NgxEditor__Dropdown--Text { + color: var(--mat-sys-background); + } + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--Selected, + .NgxEditor__Dropdown .NgxEditor__Dropdown--Open { + color: var(--mat-sys-background); + background-color: var(--mat-sys-primary); + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--Item:hover { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--DropdownMenu { + background-color: var(--mat-card-elevated-container-color); + } + + + .dropzone-box { + border: 1px dashed var(--mat-sys-primary); + background-color: var(--mat-sys-primary-fixed-dim); + + .dropzone-content { + .preview-image { + width: 100px; + height: 70px; + object-fit: cover; + border-radius: 6px; + margin-bottom: 0.5rem; + } + } + + .headline { + margin: 0; + } + } + + .cards-circle { + width: 15px; + height: 15px; + border-radius: var(--mat-sys-corner-full); + display: flex; + align-items: center; + justify-content: center; + background-color: var(--mat-sys-primary); + + .theme-icon { + display: none; + } + + &.selected { + .theme-icon { + display: block; + color: white; + width: 18px; + height: 25px; + } + } + } + +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/scss/helpers/_custom-flex.scss b/theme/packages/minisidebar/src/assets/scss/helpers/_custom-flex.scss new file mode 100644 index 0000000..fb36a29 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/helpers/_custom-flex.scss @@ -0,0 +1,59 @@ +@media (min-width: 1200px) { + body { + .d-lg-flex { + display: flex !important; + } + + .d-lg-none { + display: none !important; + } + + .d-lg-block { + display: block !important; + } + + .align-items-lg-center { + align-items: center !important; + } + } +} + +@media (min-width: 960px) { + .d-md-none { + display: none !important; + } +} + +@media (min-width: 768px) { + body { + .d-sm-flex { + display: flex !important; + } + } +} + +@media (max-width: 767px) { + .p-xs-6 { + padding: 0 6px !important; + } +} + +.flex-shrink-0 { + flex-shrink: 0; +} + +.flex-1-auto { + flex: 1 1 0%; +} + +.hstack { + display: flex; + flex-direction: row; + gap: 20px; +} + +@media (max-width: 767px) { + .hstack { + flex-direction: column; + } +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/scss/helpers/_icon-size.scss b/theme/packages/minisidebar/src/assets/scss/helpers/_icon-size.scss new file mode 100644 index 0000000..ac526ef --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/helpers/_icon-size.scss @@ -0,0 +1,15 @@ +@use "sass:meta"; + +$columns: 54; + +@mixin icon_size { + @for $i from 1 through $columns { + .icon-#{$i} { + height: #{$i}px !important; + width: #{$i}px !important; + line-height: #{$i + 8}px !important; + } + } +} + +@include icon_size; diff --git a/theme/packages/minisidebar/src/assets/scss/helpers/_text.scss b/theme/packages/minisidebar/src/assets/scss/helpers/_text.scss new file mode 100644 index 0000000..1c2636e --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/helpers/_text.scss @@ -0,0 +1,84 @@ +@use "sass:map"; +@use "variables"; + +$utilities: ( + "font-size": ( + property: font-size, + class: f-s, + values: variables.$font-sizes, + ), + "font-weight": ( + property: font-weight, + class: f-w, + values: variables.$font-wieghts, + ), + "font-style": ( + property: font-style, + class: font, + values: italic normal, + ), + "text-align": ( + property: text-align, + class: text, + values: center right left, + ), + "text-decoration": ( + property: text-decoration, + class: text, + values: none underline line-through, + ), + "text-transform": ( + property: text-transform, + class: text, + values: capitalize uppercase lowercase, + ), + "white-space": ( + property: white-space, + class: text, + values: ( + wrap: normal, + nowrap: nowrap, + ), + ), + "word-wrap": ( + property: word-wrap word-break, + class: text, + values: ( + break: break-word, + ), + ), + "text-overflow": ( + property: text-overflow, + class: text, + values: ellipsis, + ), + "text-color": ( + property: color, + class: text, + values: ( + reset: inherit, + current: currentColor, + ), + ), +); + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0px; +} + +.lh-lg { + line-height: 36px !important; +} + +.lh-sm { + line-height: 20px !important; +} + +.lh-normal { + line-height: normal !important; +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/scss/helpers/_variables.scss b/theme/packages/minisidebar/src/assets/scss/helpers/_variables.scss new file mode 100644 index 0000000..844ddf4 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/helpers/_variables.scss @@ -0,0 +1,102 @@ +@use "functions" as *; + +// Utility Map + +$utilities: () !default; + +// Spacing + +$spacer: 16px !default; +$spacers: ( + 0: 0, + 2: $spacer * 0.125, + 4: $spacer * 0.25, + 5: 5px, + 6: 7px, + 8: $spacer * 0.5, + 10: 10px, + 12: $spacer * 0.75, + 14: 14px, + 15: 15px, + 16: $spacer, + 20: 20px, + 24: $spacer * 1.5, + 30: 30px, + 32: $spacer * 2, + 44: 44px, + 48: $spacer * 3, + 60: 60px, + 66: 66px, + 80: 80px, +) !default; +$negative-spacers: negativify-map($spacers) !default; + +// Border + +$border-color: var(--mat-sys-outline-variant) !default; +$borders: ( + 0: 0, + 1: 1px solid $border-color, + 2: 2px solid $border-color, + 4: 4px solid $border-color, + 8: 8px solid $border-color, +) !default; + +// Border radius + +$radius-base: 7px !default; +$radius: ( + 0: 0, + 7: $radius-base, + 8: $radius-base * 2, + 12: $radius-base * 3, + 16: $radius-base * 4, + full: 9999px, +) !default; + +// Text + +$font-wieghts: ( + 100: 100, + 200: 200, + 300: 300, + 400: 400, + 500: 500, + 600: 600, + 700: 700, + 800: 800, + 900: 900, +) !default; + +$font-sizes: ( + 0: 0, + 10: 10px, + 12: 12px, + 14: 14px, + 15: 15px, + 16: 16px, + 18: 18px, + 20: 20px, + 21: 21px, + 24: 24px, + 28: 28px, + 30: 30px, + 36: 36px, + 40: 40px, + 48: 48px, +) !default; + +// Sizing + +$sizes: ( + 0: 0, + 20: 20%, + 25: 25%, + 40: 40%, + 50: 50%, + 60: 60%, + 75: 75%, + 80: 80%, + full: 100%, + auto: auto, +) !default; diff --git a/theme/packages/minisidebar/src/assets/scss/layouts/_header.scss b/theme/packages/minisidebar/src/assets/scss/layouts/_header.scss new file mode 100644 index 0000000..d24e1f8 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/layouts/_header.scss @@ -0,0 +1,64 @@ +@use "../variables" as *; + +html .topbar { + position: sticky; + top: 0; + z-index: 9; + height: $header-height; + + .notification-badge{ + .mat-badge-content{ + left: 80%; + bottom: 85%; + width: 16px; + height: 16px; + } + } +} + +.topbar-dd { + min-width: 360px !important; +} + +.apps-dd { + min-width: 830px !important; + overflow: unset !important; + + .mat-mdc-menu-content { + padding: 0; + } +} + +.text-hover-primary:hover { + .hover-text { + color: $primary; + } +} + +.upgrade-bg { + position: absolute; + top: 0px; + right: 0px; + height: 100%; +} + +.object-cover { + object-fit: cover; +} + +.profile-dd { + margin-top: -5px; + margin-left: -5px; +} + +.dark-theme { + .topbar { + .mat-mdc-icon-button { + color: $dark-text-secondary !important; + } + + .mdc-button { + --mat-button-text-label-text-color: $dark-text-secondary !important; + } + } +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/scss/override-component/_checkbox.scss b/theme/packages/minisidebar/src/assets/scss/override-component/_checkbox.scss new file mode 100644 index 0000000..eba7679 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/override-component/_checkbox.scss @@ -0,0 +1,23 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.checkbox-overrides( + ( + unselected-focus-icon-color: + var(--mat-checkbox-unselected-hover-state-layer-color), + ) +); + +// styles +html { + .mdc-checkbox__background { + border-radius: 4px; + width: 21px; + height: 21px; + border: 1px solid var(--mat-sys-outline); + } + + .mdc-checkbox .mdc-checkbox__native-control:focus ~ .mdc-checkbox__ripple { + background-color: var(--mat-checkbox-unselected-hover-state-layer-color); + } +} diff --git a/theme/packages/minisidebar/src/assets/scss/override-component/_datepicker.scss b/theme/packages/minisidebar/src/assets/scss/override-component/_datepicker.scss new file mode 100644 index 0000000..2686873 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/override-component/_datepicker.scss @@ -0,0 +1,11 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.datepicker-overrides( + ( + calendar-container-background-color: + var(--mat-card-elevated-container-color), + calendar-container-touch-elevation-shadow: var(--mat-sys-level1), + calendar-container-elevation-shadow: var(--mat-sys-level1), + ) +); diff --git a/theme/packages/minisidebar/src/assets/scss/override-component/_expansion.scss b/theme/packages/minisidebar/src/assets/scss/override-component/_expansion.scss new file mode 100644 index 0000000..0c5f781 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/override-component/_expansion.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.expansion-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/minisidebar/src/assets/scss/override-component/_paginator.scss b/theme/packages/minisidebar/src/assets/scss/override-component/_paginator.scss new file mode 100644 index 0000000..35479e7 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/override-component/_paginator.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.paginator-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/minisidebar/src/assets/scss/override-component/_stepper.scss b/theme/packages/minisidebar/src/assets/scss/override-component/_stepper.scss new file mode 100644 index 0000000..6a21bd4 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/override-component/_stepper.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.stepper-overrides( + ( + container-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/minisidebar/src/assets/scss/override-component/_table.scss b/theme/packages/minisidebar/src/assets/scss/override-component/_table.scss new file mode 100644 index 0000000..379ddcd --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/override-component/_table.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.table-overrides( + ( + background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/minisidebar/src/assets/scss/override-component/_tree.scss b/theme/packages/minisidebar/src/assets/scss/override-component/_tree.scss new file mode 100644 index 0000000..e755adc --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/override-component/_tree.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.tree-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/minisidebar/src/assets/scss/pages/_dashboards.scss b/theme/packages/minisidebar/src/assets/scss/pages/_dashboards.scss new file mode 100644 index 0000000..796c344 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/pages/_dashboards.scss @@ -0,0 +1,126 @@ +@use "../variables" as *; + +.social-chips { + img { + margin-left: -9px; + border: 2px solid $white; + + &:first-child { + margin-left: 0; + } + } +} + +.minus-img { + margin-bottom: -65px !important; +} + +// theme select +.theme-select { + width: 145px; +} + +// dashboard 2 +.welcome-img { + margin-bottom: -82px; + margin-top: -9px; +} + +.timeline { + position: relative; + + .timeline-item { + position: relative; + height: 70px; + + .time { + padding: 6px 16px 6px 0; + min-width: 90px; + flex-shrink: 0; + } + + .desc { + padding: 6px 16px; + } + + .timline-border { + width: 1px; + height: 100%; + background-color: $borderColor; + flex-shrink: 0; + } + + .point { + flex-direction: column; + + .timeline-badge { + width: 12px; + height: 12px; + border-radius: 50px; + background-color: transparent; + flex-shrink: 0; + + &.border-primary { + border: 2px solid $primary; + } + + &.border-accent { + border: 2px solid $accent; + } + + &.border-success { + border: 2px solid $success; + } + + &.border-warning { + border: 2px solid $warning; + } + + &.border-error { + border: 2px solid $error; + } + } + + .timeline-border { + width: 1px; + height: 100%; + background-color: $borderColor; + flex-shrink: 0; + } + } + + &:last-child { + .timeline-border { + display: none !important; + } + } + } +} + +// expansion panel + +html .mat-expansion-panel:not([class*="mat-elevation-z"]) { + box-shadow: var(--mat-sys-level2); +} + +.most-visit-chart { + .apexcharts-bar-series.apexcharts-plot-series .apexcharts-series path { + clip-path: inset(0 0 5% 0 round 20px); + } +} + + +// User Profile Tab +.profileTabs { + background-color: var(--mat-sys-surface-bright); + + .mat-mdc-tab-label-container{ + border-bottom-width: 0; + } + + .mat-mdc-tab.mdc-tab-indicator--active{ + .mdc-tab__text-label{ + color: var(--mat-sys-primary) !important; + } + } +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/scss/pages/_frontend.scss b/theme/packages/minisidebar/src/assets/scss/pages/_frontend.scss new file mode 100644 index 0000000..db45c10 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/pages/_frontend.scss @@ -0,0 +1,143 @@ +.front-topbar { + &.fixed-topbar { + position: fixed; + top: 0; + width: 100%; + background-color: var(--mat-sys-background) !important; + z-index: 9; + } +} + +.back-to-top { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 999; + transition: opacity 0.3s ease; +} + +.tab-header { + + .profileTabs { + + .mat-mdc-tab { + padding: 30px 16px; + height: auto; + border-right: 1px solid var(--mat-sys-outline); + + &:last-child { + border-right: 0; + } + } + + .mat-mdc-tab-label-container { + border-top-width: 0; + } + } + +} + +.home-page .expansion-panel .mat-expansion-panel-body { + padding: 16px 0; +} + +.faq-accordion { + .mat-expansion-panel-body { + padding: 16px 24px !important; + } +} + +.mobile-sidebar { + .mdc-list { + .mdc-list-item { + .mat-mdc-button { + color: var(--mat-sys-on-background); + min-width: 100%; + justify-content: flex-start; + + &.selected { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); + transition: background-color 0.3s ease; + } + } + } + } +} + + +.spacing-top-bottom { + padding: 80px 0; +} + +.spacing-left-right { + padding: 0 80px; +} + +.spacing-left { + padding-left: 80px; +} + +.spacing-top { + padding-top: 80px; +} + +.spacing-bottom { + padding-bottom: 80px; +} + +@media (max-width: 959px) { + .section-sub-title { + font-size: 30px !important; + } + + .spacing-top-bottom { + padding: 60px 0; + } + + .spacing-left-right { + padding: 0 60px; + } + + .spacing-left { + padding-left: 60px; + } + + .spacing-top { + padding-top: 60px; + } + + .spacing-bottom { + padding-bottom: 60px; + } +} + +@media (max-width: 767px) { + .section-sub-title { + font-size: 24px !important; + } + + .spacing-top-bottom { + padding: 30px 0; + } + + .spacing-left-right { + padding: 0 30px; + } + + .spacing-left { + padding-left: 30px; + } + + .spacing-top { + padding-top: 30px; + } + + .spacing-bottom { + padding-bottom: 30px; + } + + .footer-content .left-side-content { + padding: 30px !important; + } +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/scss/style.scss b/theme/packages/minisidebar/src/assets/scss/style.scss new file mode 100644 index 0000000..177d3f7 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/style.scss @@ -0,0 +1,51 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@use "themecolors/blue_theme"; +@use "themecolors/orange_theme"; +@use "themecolors/aqua_theme"; +@use "themecolors/cyan_theme"; +@use "themecolors/green_theme"; +@use "themecolors/purple_theme"; + +@use "variables" as *; +@use "override-component"; +@use "theme-variables/default-variables"; +@use "theme-variables/light-theme-variables"; +@use "theme-variables/dark-theme-variables"; + +//container layout +@use "layouts/transitions"; +@use "helpers/color"; +@use "helpers/border-color"; +@use "helpers/icon-size"; +@use "container"; +@use "layouts/layouts"; +@use "grid/grid"; +@use "helpers/custom-flex"; +@use "helpers"; + +// horizontal +@use "horizontal/horizontal"; +@use "dark/dark"; + +// apps +@use "apps/calendar"; +@use "apps/email"; +@use "apps/blogs"; +@use "apps/chat"; +@use "apps/contact-list"; +@use "apps/kanban"; +@use "apps/courses"; +@use "apps/todo"; +@use "apps/ecommerce"; + +@use "pages/auth"; +@use "pages/dashboards"; +@use "pages/landingpage"; +@use "pages/toast"; +@use "pages/pricing"; +@use "pages/frontend"; + +// RTL Theme +@use "rtl/rtl"; \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/scss/theme-variables/_dark-theme-variables.scss b/theme/packages/minisidebar/src/assets/scss/theme-variables/_dark-theme-variables.scss new file mode 100644 index 0000000..0375fc4 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/theme-variables/_dark-theme-variables.scss @@ -0,0 +1,32 @@ +@use "@angular/material" as mat; + +html.dark-theme { + color-scheme: dark; + --mat-sys-background: #141a21; + --mat-sys-on-background: rgba(255, 255, 255, 0.9); + --mat-sys-on-primary: #fff; + --mat-sys-surface-bright: #ffffff05; + --mat-sys-surface: #141a21; + --mat-sys-surface-container: #141a21; + --mat-sys-surface-container-low: #141a21; + --mat-sys-outline-variant: #2e3f50; + --mat-sys-outline: #2e3f50; + --mat-form-field-outlined-hover-outline-color: #465670; + --mat-checkbox-unselected-hover-state-layer-color: #19212a; + --mat-menu-item-hover-state-layer-color: #19212a; + --mat-button-toggle-state-layer-color: #19212a; + --mat-option-focus-state-layer-color: #19212a; + --mat-option-hover-state-layer-color: #19212a; + --mat-slide-toggle-unselected-track-color: #19212a; + --mat-stepper-header-focus-state-layer-color: #19212a; + --mat-stepper-header-hover-state-layer-color: #19212a; + --mat-expansion-header-hover-state-layer-color: #19212a; + @include mat.card-overrides((elevated-container-color: #1c252e, + elevated-container-elevation: rgba(0, 0, 0, 0.2) 0px 0px 2px 0px, + subtitle-text-color: rgba(255, 255, 255, 0.67), + )); + @include mat.theme-overrides((level1: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level2: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level3: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + )); +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/scss/theme-variables/_default-variables.scss b/theme/packages/minisidebar/src/assets/scss/theme-variables/_default-variables.scss new file mode 100644 index 0000000..e3adeb2 --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/theme-variables/_default-variables.scss @@ -0,0 +1,12 @@ +html { + --mat-sys-error-fixed-dim: rgba(247, 68, 86, 0.15); + --mat-select-container-elevation-shadow: var(--mat-sys-level3); + --mat-list-list-item-label-text-tracking: 0; + --mat-slide-toggle-track-height: 28px; + --mat-sidenav-container-divider-color: var(--mat-sys-outline-variant); + --mat-dialog-with-actions-content-padding: 20px 24px; + --mat-form-field-container-text-tracking: unset; + --mat-slide-toggle-with-icon-handle-size: 21px; + --mat-badge-text-color: white; + --mat-slide-toggle-selected-with-icon-handle-horizontal-margin: 0 26px; +} \ No newline at end of file diff --git a/theme/packages/minisidebar/src/assets/scss/theme-variables/_light-theme-variables.scss b/theme/packages/minisidebar/src/assets/scss/theme-variables/_light-theme-variables.scss new file mode 100644 index 0000000..735309e --- /dev/null +++ b/theme/packages/minisidebar/src/assets/scss/theme-variables/_light-theme-variables.scss @@ -0,0 +1,23 @@ +html.light-theme { + color-scheme: light; + --mat-sys-corner-small: 7px; + --mat-sys-background: #fff; + --mat-sys-surface-bright: #f2f6fa; + --mat-sys-surface: #fff; + --mat-sys-surface-container: #fff; + --mat-sys-surface-container-low: #fff; + --mat-sys-on-background: #2a3547; + --mat-sys-outline: #d7dde2; + --mat-sys-outline-variant: #d7dde2; + --mat-form-field-outlined-hover-outline-color: #d7dde2; + --mat-checkbox-unselected-hover-state-layer-color: #d7dde2; + --mat-menu-item-hover-state-layer-color: #f6f9fc; + --mat-button-toggle-state-layer-color: #f6f9fc; + --mat-option-focus-state-layer-color: #f6f9fc; + --mat-option-hover-state-layer-color: #f6f9fc; + --mat-slide-toggle-unselected-track-color: #f6f9fc; + --mat-stepper-header-focus-state-layer-color: #f6f9fc; + --mat-stepper-header-hover-state-layer-color: #f6f9fc; + --mat-dialog-supporting-text-color: var(--mat-sys-on-background); + --mat-expansion-header-hover-state-layer-color: #f6f9fc; + } \ No newline at end of file diff --git a/theme/packages/minisidebar/src/index.html b/theme/packages/minisidebar/src/index.html new file mode 100644 index 0000000..344a5f2 --- /dev/null +++ b/theme/packages/minisidebar/src/index.html @@ -0,0 +1,17 @@ + + + + + Modernize Angular 20 Admin Template + + + + + + + + + + + \ No newline at end of file diff --git a/theme/packages/minisidebar/tsconfig.json b/theme/packages/minisidebar/tsconfig.json new file mode 100644 index 0000000..c3587c1 --- /dev/null +++ b/theme/packages/minisidebar/tsconfig.json @@ -0,0 +1,34 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "strictPropertyInitialization": false, + "lib": [ + "ES2022", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true, + } +} diff --git a/theme/packages/rtl/angular.json b/theme/packages/rtl/angular.json new file mode 100644 index 0000000..0f19c10 --- /dev/null +++ b/theme/packages/rtl/angular.json @@ -0,0 +1,126 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "Modernize": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "allowedCommonJsDependencies": ["apexcharts", "bezier-easing", "chance"], + "outputPath": { + "base": "dist/Modernize" + }, + "index": "src/index.html", + "polyfills": ["zone.js"], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": [ + + "src/styles.scss", + "src/assets/scss/style.scss", + "node_modules/ngx-toastr/toastr.css", + "node_modules/angular-calendar/css/angular-calendar.css", + "node_modules/highlight.js/styles/atom-one-dark.min.css" + ], + "scripts": [], + "browser": "src/main.ts" + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "12mb", + "maximumError": "12mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "12mb", + "maximumError": "12mb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "Modernize:build:production" + }, + "development": { + "buildTarget": "Modernize:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular/build:extract-i18n", + "options": { + "buildTarget": "Modernize:build" + } + }, + "test": { + "builder": "@angular/build:karma", + "options": { + "polyfills": ["zone.js", "zone.js/testing"], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], + "scripts": [] + } + } + } + } + }, + "cli": { + "analytics": false + }, + "schematics": { + "@schematics/angular:component": { + "type": "component" + }, + "@schematics/angular:directive": { + "type": "directive" + }, + "@schematics/angular:service": { + "type": "service" + }, + "@schematics/angular:guard": { + "typeSeparator": "." + }, + "@schematics/angular:interceptor": { + "typeSeparator": "." + }, + "@schematics/angular:module": { + "typeSeparator": "." + }, + "@schematics/angular:pipe": { + "typeSeparator": "." + }, + "@schematics/angular:resolver": { + "typeSeparator": "." + } + } +} diff --git a/theme/packages/rtl/package.json b/theme/packages/rtl/package.json new file mode 100644 index 0000000..51d6f74 --- /dev/null +++ b/theme/packages/rtl/package.json @@ -0,0 +1,62 @@ +{ + "name": "modernize", + "version": "3.1.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^20.0.4", + "@angular/cdk": "^20.0.3", + "@angular/common": "^20.0.4", + "@angular/compiler": "^20.0.4", + "@angular/core": "^20.0.4", + "@angular/forms": "^20.0.4", + "@angular/material": "^20.0.3", + "@angular/platform-browser": "^20.0.4", + "@angular/platform-browser-dynamic": "^20.0.4", + "@angular/router": "^20.0.4", + "@ng-matero/extensions": "^20.1.0", + "@ngx-translate/core": "^16.0.4", + "@ngx-translate/http-loader": "^16.0.1", + "angular-calendar": "^0.31.1", + "angular-tabler-icons": "^3.26.0", + "apexcharts": "^4.7.0", + "chance": "^1.1.13", + "date-fns": "^4.1.0", + "highlight.js": "^11.11.1", + "ng-apexcharts": "^1.16.0", + "ng2-search-filter": "^0.5.1", + "ngx-dropzone": "^3.1.0", + "ngx-editor": "^19.0.0-beta.1", + "ngx-highlightjs": "^14.0.1", + "ngx-owl-carousel-o": "^20.0.0", + "ngx-pagination": "^6.0.3", + "ngx-permissions": "^19.0.0", + "ngx-scrollbar": "^18.0.0", + "ngx-toastr": "^19.0.0", + "rxjs": "~7.8.2", + "sass": "^1.89.2", + "tslib": "^2.8.1", + "zone.js": "~0.15.1" + }, + "devDependencies": { + "@angular/build": "^20.0.3", + "@angular/cli": "~20.0.3", + "@angular/compiler-cli": "^20.0.4", + "@types/chance": "^1.1.6", + "@types/date-fns": "^2.6.3", + "@types/jasmine": "~5.1.8", + "jasmine-core": "~5.8.0", + "karma": "~6.4.4", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.1", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.8.3" + } +} diff --git a/theme/packages/rtl/src/app/app.routes.ts b/theme/packages/rtl/src/app/app.routes.ts new file mode 100644 index 0000000..f1bf19f --- /dev/null +++ b/theme/packages/rtl/src/app/app.routes.ts @@ -0,0 +1,107 @@ +import { Routes } from '@angular/router'; +import { BlankComponent } from './layouts/blank/blank.component'; +import { FullComponent } from './layouts/full/full.component'; + +export const routes: Routes = [ + { + path: '', + component: FullComponent, + children: [ + { + path: '', + redirectTo: '/dashboards/dashboard1', + pathMatch: 'full', + }, + { + path: 'starter', + loadChildren: () => + import('./pages/pages.routes').then((m) => m.PagesRoutes), + }, + { + path: 'dashboards', + loadChildren: () => + import('./pages/dashboards/dashboards.routes').then( + (m) => m.DashboardsRoutes + ), + }, + + { + path: 'forms', + loadChildren: () => + import('./pages/forms/forms.routes').then((m) => m.FormsRoutes), + }, + { + path: 'charts', + loadChildren: () => + import('./pages/charts/charts.routes').then((m) => m.ChartsRoutes), + }, + { + path: 'apps', + loadChildren: () => + import('./pages/apps/apps.routes').then((m) => m.AppsRoutes), + }, + { + path: 'widgets', + loadChildren: () => + import('./pages/widgets/widgets.routes').then((m) => m.WidgetsRoutes), + }, + { + path: 'tables', + loadChildren: () => + import('./pages/tables/tables.routes').then((m) => m.TablesRoutes), + }, + { + path: 'datatable', + loadChildren: () => + import('./pages/datatable/datatable.routes').then( + (m) => m.DatatablesRoutes + ), + }, + { + path: 'theme-pages', + loadChildren: () => + import('./pages/theme-pages/theme-pages.routes').then( + (m) => m.ThemePagesRoutes + ), + }, + { + path: 'ui-components', + loadChildren: () => + import('./pages/ui-components/ui-components.routes').then( + (m) => m.UiComponentsRoutes + ), + }, + ], + }, + { + path: '', + component: BlankComponent, + children: [ + { + path: 'authentication', + loadChildren: () => + import('./pages/authentication/authentication.routes').then( + (m) => m.AuthenticationRoutes + ), + }, + { + path: 'landingpage', + loadChildren: () => + import('./pages/theme-pages/landingpage/landingpage.routes').then( + (m) => m.LandingPageRoutes + ), + }, + { + path: 'front-pages', + loadChildren: () => + import('./pages/front-pages/front-pages.routes').then( + (m) => m.FrontPagesRoutes + ), + }, + ], + }, + { + path: '**', + redirectTo: 'authentication/error', + }, +]; diff --git a/theme/packages/rtl/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html b/theme/packages/rtl/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html new file mode 100644 index 0000000..fa78891 --- /dev/null +++ b/theme/packages/rtl/src/app/components/dashboard1/yearly-breakup/yearly-breakup.component.html @@ -0,0 +1,55 @@ + + + Yearly Breakup + + +
+
+

$36,358

+
+ +
+9%
+
last year
+
+ +
+
+ +
2025
+
+
+ +
2024
+
+
+
+
+ + + + +
+
+
+
diff --git a/theme/packages/rtl/src/app/config.ts b/theme/packages/rtl/src/app/config.ts new file mode 100644 index 0000000..1d67f58 --- /dev/null +++ b/theme/packages/rtl/src/app/config.ts @@ -0,0 +1,25 @@ +export interface AppSettings { + dir: 'ltr' | 'rtl'; + theme: string; + sidenavOpened: boolean; + sidenavCollapsed: boolean; + boxed: boolean; + horizontal: boolean; + activeTheme: string; + language: string; + cardBorder: boolean; + navPos: 'side' | 'top'; +} + +export const defaults: AppSettings = { + dir: 'rtl', + theme: 'light', + sidenavOpened: false, + sidenavCollapsed: false, + boxed: true, + horizontal: false, + cardBorder: false, + activeTheme: 'blue_theme', + language: 'en-us', + navPos: 'side', +}; \ No newline at end of file diff --git a/theme/packages/rtl/src/app/layouts/full/full.component.html b/theme/packages/rtl/src/app/layouts/full/full.component.html new file mode 100644 index 0000000..2ffaeb5 --- /dev/null +++ b/theme/packages/rtl/src/app/layouts/full/full.component.html @@ -0,0 +1,197 @@ + + + + + + @if (!options.horizontal) { + +
+ + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+
+ } + + + + + @if (resView) { + + + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+ } + + + + + + + + + @if (!options.horizontal) { + + } @else { + + + } @if(options.horizontal) { + + } + +
+ + + + + +
+ +
+
+ + +
+
+
+
+ @if(options.theme === 'light') { + + logo + + } @else { + + logo + + } +
+ +
+ + + + + Apps + +
+
+ @for(appdd of apps; track appdd.img) { + + } +
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+ + +
+
+
+ + +
+

Settings

+ +
+ + + +
+
+
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/layouts/full/full.component.ts b/theme/packages/rtl/src/app/layouts/full/full.component.ts new file mode 100644 index 0000000..459faac --- /dev/null +++ b/theme/packages/rtl/src/app/layouts/full/full.component.ts @@ -0,0 +1,284 @@ +import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout'; +import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { MatSidenav, MatSidenavContent } from '@angular/material/sidenav'; +import { CoreService } from 'src/app/services/core.service'; +import { AppSettings } from 'src/app/config'; +import { filter } from 'rxjs/operators'; +import { NavigationEnd, Router } from '@angular/router'; +import { navItems } from './vertical/sidebar/sidebar-data'; +import { NavService } from '../../services/nav.service'; +import { AppNavItemComponent } from './vertical/sidebar/nav-item/nav-item.component'; +import { RouterModule } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { SidebarComponent } from './vertical/sidebar/sidebar.component'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { HeaderComponent } from './vertical/header/header.component'; +import { AppHorizontalHeaderComponent } from './horizontal/header/header.component'; +import { AppHorizontalSidebarComponent } from './horizontal/sidebar/sidebar.component'; +import { AppBreadcrumbComponent } from './shared/breadcrumb/breadcrumb.component'; +import { CustomizerComponent } from './shared/customizer/customizer.component'; + +const MOBILE_VIEW = 'screen and (max-width: 768px)'; +const TABLET_VIEW = 'screen and (min-width: 769px) and (max-width: 1024px)'; +const MONITOR_VIEW = 'screen and (min-width: 1024px)'; +const BELOWMONITOR = 'screen and (max-width: 1023px)'; + +// for mobile app sidebar +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +@Component({ + selector: 'app-full', + imports: [ + RouterModule, + AppNavItemComponent, + MaterialModule, + CommonModule, + SidebarComponent, + NgScrollbarModule, + TablerIconsModule, + HeaderComponent, + AppHorizontalHeaderComponent, + AppHorizontalSidebarComponent, + AppBreadcrumbComponent, + CustomizerComponent, + ], + templateUrl: './full.component.html', + + encapsulation: ViewEncapsulation.None +}) +export class FullComponent implements OnInit { + navItems = navItems; + + + + @ViewChild('leftsidenav') + public sidenav: MatSidenav; + resView = false; + @ViewChild('content', { static: true }) content!: MatSidenavContent; + //get options from service + options = this.settings.getOptions(); + private layoutChangesSubscription = Subscription.EMPTY; + private isMobileScreen = false; + private isContentWidthFixed = true; + private isCollapsedWidthFixed = false; + private htmlElement!: HTMLHtmlElement; + + get isOver(): boolean { + return this.isMobileScreen; + } + + get isTablet(): boolean { + return this.resView; + } + + // for mobile app sidebar + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/apps/chat', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'Todo App', + subtitle: 'Completed task', + link: '/apps/todo', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/apps/invoice', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/apps/calendar', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/apps/contacts', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/apps/tickets', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/apps/email/inbox', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Courses', + subtitle: 'Create new course', + link: '/apps/courses', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/theme-pages/pricing', + }, + { + id: 2, + title: 'Authentication Design', + link: '/authentication/login', + }, + { + id: 3, + title: 'Register Now', + link: '/authentication/side-register', + }, + { + id: 4, + title: '404 Error Page', + link: '/authentication/error', + }, + { + id: 5, + title: 'Notes App', + link: '/apps/notes', + }, + { + id: 6, + title: 'Employee App', + link: '/apps/employee', + }, + { + id: 7, + title: 'Todo Application', + link: '/apps/todo', + }, + { + id: 8, + title: 'Treeview', + link: '/theme-pages/treeview', + }, + ]; + + constructor( + private settings: CoreService, + private mediaMatcher: MediaMatcher, + private router: Router, + private breakpointObserver: BreakpointObserver, + private navService: NavService, private cdr: ChangeDetectorRef + ) { + this.htmlElement = document.querySelector('html')!; + this.layoutChangesSubscription = this.breakpointObserver + .observe([MOBILE_VIEW, TABLET_VIEW, MONITOR_VIEW, BELOWMONITOR]) + .subscribe((state) => { + // SidenavOpened must be reset true when layout changes + this.options.sidenavOpened = true; + this.isMobileScreen = state.breakpoints[BELOWMONITOR]; + if (this.options.sidenavCollapsed == false) { + this.options.sidenavCollapsed = state.breakpoints[TABLET_VIEW]; + } + this.isContentWidthFixed = state.breakpoints[MONITOR_VIEW]; + this.resView = state.breakpoints[BELOWMONITOR]; + }); + + // Initialize project theme with options + this.receiveOptions(this.options); + + // This is for scroll to top + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .subscribe((e) => { + this.content.scrollTo({ top: 0 }); + }); + } + + isFilterNavOpen = false; + + toggleFilterNav() { + this.isFilterNavOpen = !this.isFilterNavOpen; + console.log('Sidebar open:', this.isFilterNavOpen); + this.cdr.detectChanges(); // Ensures Angular updates the view + } + + ngOnInit(): void {} + + ngOnDestroy() { + this.layoutChangesSubscription.unsubscribe(); + } + + toggleCollapsed() { + this.isContentWidthFixed = false; + this.options.sidenavCollapsed = !this.options.sidenavCollapsed; + this.resetCollapsedState(); + } + + resetCollapsedState(timer = 400) { + setTimeout(() => this.settings.setOptions(this.options), timer); + } + + onSidenavClosedStart() { + this.isContentWidthFixed = false; + } + + onSidenavOpenedChange(isOpened: boolean) { + this.isCollapsedWidthFixed = !this.isOver; + this.options.sidenavOpened = isOpened; + this.settings.setOptions(this.options); + } + + receiveOptions(options: AppSettings): void { + this.toggleDarkTheme(options); + this.toggleColorsTheme(options); + } + + toggleDarkTheme(options: AppSettings) { + if (options.theme === 'dark') { + this.htmlElement.classList.add('dark-theme'); + this.htmlElement.classList.remove('light-theme'); + } else { + this.htmlElement.classList.remove('dark-theme'); + this.htmlElement.classList.add('light-theme'); + } + } + + toggleColorsTheme(options: AppSettings) { + // Remove any existing theme class dynamically + this.htmlElement.classList.forEach((className) => { + if (className.endsWith('_theme')) { + this.htmlElement.classList.remove(className); + } + }); + + // Add the selected theme class + this.htmlElement.classList.add(options.activeTheme); + } +} diff --git a/theme/packages/rtl/src/app/layouts/full/horizontal/header/header.component.html b/theme/packages/rtl/src/app/layouts/full/horizontal/header/header.component.html new file mode 100644 index 0000000..f076a2c --- /dev/null +++ b/theme/packages/rtl/src/app/layouts/full/horizontal/header/header.component.html @@ -0,0 +1,296 @@ + +
+
+ +
+ + + + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/rtl/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts b/theme/packages/rtl/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts new file mode 100644 index 0000000..3bdf202 --- /dev/null +++ b/theme/packages/rtl/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts @@ -0,0 +1,633 @@ +import { NavItem } from '../../vertical/sidebar/nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Dashboards', + iconName: 'home', + route: 'dashboards', + children: [ + { + displayName: 'Analytical', + iconName: 'point', + route: 'dashboards/dashboard1', + }, + { + displayName: 'eCommerce', + iconName: 'point', + route: 'dashboards/dashboard2', + }, + ], + }, + { + displayName: 'Frontend pages', + iconName: 'app-window', + route: 'front-pages', + children: [ + { + displayName: 'Home Page', + iconName: 'point', + route: 'front-pages/homepage', + } , + { + displayName: 'About Us', + iconName: 'point', + route: 'front-pages/about', + } , + { + displayName: 'Blog', + iconName: 'point', + route: 'front-pages/blog', + } , + { + displayName: 'Blog Details', + iconName: 'point', + route: 'front-pages/blog-details', + } , + { + displayName: 'Portfolio', + iconName: 'point', + route: 'front-pages/portfolio', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'front-pages/pricing', + }, + { + displayName: 'Contact', + iconName: 'point', + route: 'front-pages/contact', + } + ] + }, + { + displayName: 'Apps', + iconName: 'apps', + route: 'apps', + ddType: '', + children: [ + { + displayName: 'Chat', + iconName: 'point', + route: 'apps/chat', + }, + { + displayName: 'Calendar', + iconName: 'point', + route: 'apps/calendar', + }, + { + displayName: 'Email', + iconName: 'point', + route: 'apps/email/inbox', + }, + { + displayName: 'Contacts', + iconName: 'point', + route: 'apps/contacts', + }, + { + displayName: 'Contact List', + iconName: 'point', + route: 'apps/contact-list', + }, + { + displayName: 'Courses', + iconName: 'point', + route: 'apps/courses', + }, + { + displayName: 'Employee', + iconName: 'point', + route: 'apps/employee', + }, + { + displayName: 'Notes', + iconName: 'point', + route: 'apps/notes', + }, + { + displayName: 'Tickets', + iconName: 'point', + route: 'apps/tickets', + }, + { + displayName: 'Invoice', + iconName: 'point', + route: 'apps/invoice', + }, + { + displayName: 'ToDo', + iconName: 'point', + route: 'apps/todo', + }, + { + displayName: 'Kanban', + iconName: 'point', + route: 'apps/kanban', + }, + { + displayName: 'Blog', + iconName: 'point', + route: 'apps/blog', + children: [ + { + displayName: 'Post', + iconName: 'point', + route: 'apps/blog/post', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + }, + ], + }, + { + displayName: 'User Profile', + iconName: 'point', + route: 'apps/profile-details', + children: [ + { + displayName: 'Profile', + iconName: 'point', + route: 'apps/profile-details/profile', + }, + { + displayName: 'Followers', + iconName: 'point', + route: 'apps/profile-details/followers', + }, + { + displayName: 'Friends', + iconName: 'point', + route: 'apps/profile-details/friends', + }, + { + displayName: 'Gellary', + iconName: 'point', + route: 'apps/profile-details/gallery', + }, + ], + }, + { + displayName: 'Ecommerce', + iconName: 'point', + route: 'apps/product', + children: [ + { + displayName: 'Product List', + iconName: 'point', + route: 'apps/product/product-list', + }, + { + displayName: 'Add Product', + iconName: 'point', + route: 'apps/product/add-product', + }, + { + displayName: 'Edit Product', + iconName: 'point', + route: 'apps/product/edit-product', + }, + { + displayName: 'Shop', + iconName: 'point', + route: 'apps/product/shop', + }, + ], + }, + ], + }, + { + displayName: 'Ui', + iconName: 'components', + route: 'ui-components', + ddType: '', + children: [ + { + displayName: 'Badge', + iconName: 'point', + route: 'ui-components/badge', + }, + { + displayName: 'Expansion Panel', + iconName: 'point', + route: 'ui-components/expansion', + }, + { + displayName: 'Chips', + iconName: 'point', + route: 'ui-components/chips', + }, + { + displayName: 'Dialog', + iconName: 'point', + route: 'ui-components/dialog', + }, + { + displayName: 'Lists', + iconName: 'point', + route: 'ui-components/lists', + }, + { + displayName: 'Divider', + iconName: 'point', + route: 'ui-components/divider', + }, + { + displayName: 'Menu', + iconName: 'point', + route: 'ui-components/menu', + }, + { + displayName: 'Paginator', + iconName: 'point', + route: 'ui-components/paginator', + }, + { + displayName: 'Progress Bar', + iconName: 'point', + route: 'ui-components/progress', + }, + { + displayName: 'Progress Spinner', + iconName: 'point', + route: 'ui-components/progress-spinner', + }, + { + displayName: 'Ripples', + iconName: 'point', + route: 'ui-components/ripples', + }, + { + displayName: 'Slide Toggle', + iconName: 'point', + route: 'ui-components/slide-toggle', + }, + { + displayName: 'Slider', + iconName: 'point', + route: 'ui-components/slider', + }, + { + displayName: 'Snackbar', + iconName: 'point', + route: 'ui-components/snackbar', + }, + { + displayName: 'Tabs', + iconName: 'point', + route: 'ui-components/tabs', + }, + { + displayName: 'Toolbar', + iconName: 'point', + route: 'ui-components/toolbar', + }, + { + displayName: 'Tooltips', + iconName: 'point', + route: 'ui-components/tooltips', + }, + ], + }, + { + displayName: 'Pages', + iconName: 'clipboard', + route: 'theme-pages', + ddType: '', + children: [ + { + displayName: 'Treeview', + iconName: 'point', + route: 'theme-pages/treeview', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'theme-pages/pricing', + }, + { + displayName: 'Account Setting', + iconName: 'point', + route: 'theme-pages/account-setting', + }, + { + displayName: 'FAQ', + iconName: 'point', + route: 'theme-pages/faq', + }, + { + displayName: 'Landingpage', + iconName: 'point', + route: 'landingpage', + }, + { + displayName: 'Widgets', + iconName: 'point', + route: 'widgets', + children: [ + { + displayName: 'Cards', + iconName: 'point', + route: 'widgets/cards', + }, + { + displayName: 'Banners', + iconName: 'point', + route: 'widgets/banners', + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'widgets/charts', + }, + ], + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'charts', + children: [ + { + displayName: 'Line', + iconName: 'point', + route: '/charts/line', + }, + { + displayName: 'Gredient', + iconName: 'point', + route: '/charts/gredient', + }, + { + displayName: 'Area', + iconName: 'point', + route: '/charts/area', + }, + { + displayName: 'Candlestick', + iconName: 'point', + route: '/charts/candlestick', + }, + { + displayName: 'Column', + iconName: 'point', + route: '/charts/column', + }, + { + displayName: 'Doughnut & Pie', + iconName: 'point', + route: '/charts/doughnut-pie', + }, + { + displayName: 'Radialbar & Radar', + iconName: 'point', + route: '/charts/radial-radar', + }, + ], + }, + { + displayName: 'Auth', + iconName: 'point', + route: '/', + children: [ + { + displayName: 'Login', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/login', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-login', + }, + ], + }, + { + displayName: 'Register', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/side-register', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-register', + }, + ], + }, + { + displayName: 'Forgot Password', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Side Forgot Password', + iconName: 'point', + route: '/authentication/side-forgot-pwd', + }, + { + displayName: 'Boxed Forgot Password', + iconName: 'point', + route: '/authentication/boxed-forgot-pwd', + }, + ], + }, + { + displayName: 'Two Steps', + iconName: 'point', + route: '/authentication', + children: [ + { + displayName: 'Side Two Steps', + iconName: 'point', + route: '/authentication/side-two-steps', + }, + { + displayName: 'Boxed Two Steps', + iconName: 'point', + route: '/authentication/boxed-two-steps', + }, + ], + }, + { + displayName: 'Error', + iconName: 'point', + route: '/authentication/error', + }, + { + displayName: 'Maintenance', + iconName: 'point', + route: '/authentication/maintenance', + }, + ], + }, + ], + }, + { + displayName: 'Forms', + iconName: 'file-description', + route: 'forms', + ddType: '', + children: [ + { + displayName: 'Form elements', + iconName: 'point', + route: 'forms/forms-elements', + children: [ + { + displayName: 'Autocomplete', + iconName: 'point', + route: 'forms/forms-elements/autocomplete', + }, + { + displayName: 'Button', + iconName: 'point', + route: 'forms/forms-elements/button', + }, + { + displayName: 'Checkbox', + iconName: 'point', + route: 'forms/forms-elements/checkbox', + }, + { + displayName: 'Radio', + iconName: 'point', + route: 'forms/forms-elements/radio', + }, + { + displayName: 'Datepicker', + iconName: 'point', + route: 'forms/forms-elements/datepicker', + }, + ], + }, + { + displayName: 'Form Layouts', + iconName: 'point', + route: '/forms/form-layouts', + }, + { + displayName: 'Form Horizontal', + iconName: 'point', + route: '/forms/form-horizontal', + }, + { + displayName: 'Form Vertical', + iconName: 'point', + route: '/forms/form-vertical', + }, + { + displayName: 'Form Wizard', + iconName: 'point', + route: '/forms/form-wizard', + }, + { + displayName: 'Toastr', + iconName: 'point', + route: '/forms/form-toastr', + }, + { + displayName: 'Editor', + iconName: 'point', + route: '/forms/form-editor', + }, + ], + }, + { + displayName: 'Tables', + iconName: 'layout', + route: 'tables', + ddType: '', + children: [ + { + displayName: 'Basic Table', + iconName: 'point', + route: 'tables/basic-table', + }, + { + displayName: 'Dynamic Table', + iconName: 'point', + route: 'tables/dynamic-table', + }, + { + displayName: 'Expand Table', + iconName: 'point', + route: 'tables/expand-table', + }, + { + displayName: 'Filterable Table', + iconName: 'point', + route: 'tables/filterable-table', + }, + { + displayName: 'Footer Row Table', + iconName: 'point', + route: 'tables/footer-row-table', + }, + { + displayName: 'HTTP Table', + iconName: 'point', + route: 'tables/http-table', + }, + { + displayName: 'Mix Table', + iconName: 'point', + route: 'tables/mix-table', + }, + { + displayName: 'Multi Header Footer', + iconName: 'point', + route: 'tables/multi-header-footer-table', + }, + { + displayName: 'Pagination Table', + iconName: 'point', + route: 'tables/pagination-table', + }, + { + displayName: 'Row Context Table', + iconName: 'point', + route: 'tables/row-context-table', + }, + { + displayName: 'Selection Table', + iconName: 'point', + route: 'tables/selection-table', + }, + { + displayName: 'Sortable Table', + iconName: 'point', + route: 'tables/sortable-table', + }, + { + displayName: 'Sticky Column', + iconName: 'point', + route: 'tables/sticky-column-table', + }, + { + displayName: 'Sticky Header Footer', + iconName: 'point', + route: 'tables/sticky-header-footer-table', + }, + { + displayName: 'Data table', + iconName: 'point', + route: '/datatable/kichen-sink', + }, + ], + }, +]; diff --git a/theme/packages/rtl/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts b/theme/packages/rtl/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts new file mode 100644 index 0000000..f0e13f5 --- /dev/null +++ b/theme/packages/rtl/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts @@ -0,0 +1,48 @@ +import { + Component, + OnInit, + Input, + ChangeDetectorRef, + OnChanges, +} from '@angular/core'; +import { navItems } from './sidebar-data'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../services/nav.service'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { AppHorizontalNavItemComponent } from './nav-item/nav-item.component'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-horizontal-sidebar', + imports: [AppHorizontalNavItemComponent, CommonModule], + templateUrl: './sidebar.component.html', +}) +export class AppHorizontalSidebarComponent implements OnInit { + navItems = navItems; + parentActive = ''; + + mobileQuery: MediaQueryList; + private _mobileQueryListener: () => void; + + constructor( + public navService: NavService, + public router: Router, + media: MediaMatcher, + changeDetectorRef: ChangeDetectorRef + ) { + this.mobileQuery = media.matchMedia('(min-width: 1100px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + this.router.events.subscribe( + () => (this.parentActive = this.router.url.split('/')[1]) + ); + } + + ngOnInit(): void { + this.parentActive = this.router.url.split('/')[1]; + + this.router.events.subscribe(() => { + this.parentActive = this.router.url.split('/')[1]; + }); + } +} diff --git a/theme/packages/rtl/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts b/theme/packages/rtl/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts new file mode 100644 index 0000000..3cf2292 --- /dev/null +++ b/theme/packages/rtl/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { Router, NavigationEnd, ActivatedRoute, Data } from '@angular/router'; +import { filter, map, mergeMap } from 'rxjs/operators'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-breadcrumb', + imports: [RouterModule, TablerIconsModule], + templateUrl: './breadcrumb.component.html', + styleUrls: [] +}) +export class AppBreadcrumbComponent { + // @Input() layout; + pageInfo: Data | any = Object.create(null); + myurl: any = this.router.url.slice(1).split('/'); + constructor( + private router: Router, + private activatedRoute: ActivatedRoute, + private titleService: Title + ) { + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .pipe(map(() => this.activatedRoute)) + .pipe( + map((route) => { + while (route.firstChild) { + route = route.firstChild; + } + return route; + }) + ) + .pipe(filter((route) => route.outlet === 'primary')) + .pipe(mergeMap((route) => route.data)) + // tslint:disable-next-line - Disables all + .subscribe((event) => { + // tslint:disable-next-line - Disables all + this.titleService.setTitle(event['title'] + ' - Angular 20'); + this.pageInfo = event; + }); + } +} diff --git a/theme/packages/rtl/src/app/layouts/full/vertical/header/header.component.html b/theme/packages/rtl/src/app/layouts/full/vertical/header/header.component.html new file mode 100644 index 0000000..3949a30 --- /dev/null +++ b/theme/packages/rtl/src/app/layouts/full/vertical/header/header.component.html @@ -0,0 +1,301 @@ + + + + @if(showToggle) { + + } + + + @if(!showToggle) { + + } + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently + Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ + @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/rtl/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts b/theme/packages/rtl/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts new file mode 100644 index 0000000..3782536 --- /dev/null +++ b/theme/packages/rtl/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts @@ -0,0 +1,103 @@ +import { + Component, + HostBinding, + Input, + OnInit, + OnChanges, + Output, + EventEmitter, +} from '@angular/core'; +import { NavItem } from './nav-item'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../../services/nav.service'; +import { + animate, + state, + style, + transition, + trigger, +} from '@angular/animations'; +import { TranslateModule } from '@ngx-translate/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-nav-item', + imports: [TranslateModule, TablerIconsModule, MaterialModule, CommonModule], + templateUrl: './nav-item.component.html', + styleUrls: [], + animations: [ + trigger('indicatorRotate', [ + state('collapsed', style({ transform: 'rotate(0deg)' })), + state('expanded', style({ transform: 'rotate(180deg)' })), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4,0.0,0.2,1)')), + ]), + ] +}) +export class AppNavItemComponent implements OnChanges { + @Output() toggleMobileLink: any = new EventEmitter(); + @Output() notify: EventEmitter = new EventEmitter(); + + expanded: any = false; + disabled: any = false; + twoLines: any = false; + @HostBinding('attr.aria-expanded') ariaExpanded = this.expanded; + @Input() item: NavItem | any; + @Input() depth: any; + + constructor(public navService: NavService, public router: Router) { + if (this.depth === undefined) { + this.depth = 0; + } + } + + ngOnChanges() { + const url = this.navService.currentUrl(); + if (this.item.route && url) { + this.expanded = url.indexOf(`/${this.item.route}`) === 0; + this.ariaExpanded = this.expanded; + } + } + + onItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + this.router.navigate([item.route]); + + } + if (item.children && item.children.length) { + this.expanded = !this.expanded; + } + //scroll + window.scroll({ + top: 0, + left: 0, + behavior: 'smooth', + }); + if (!this.expanded) { + if (window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + onSubItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + if (this.expanded && window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + isDirectlyActive(item: NavItem): boolean { + return !!item.route && this.router.isActive(item.route, true); + } + + isChildActive(item: NavItem): boolean { + if (!item.children) return false; + return item.children.some( + (child) => this.isDirectlyActive(child) || this.isChildActive(child) + ); + } + +} diff --git a/theme/packages/rtl/src/app/layouts/full/vertical/sidebar/sidebar-data.ts b/theme/packages/rtl/src/app/layouts/full/vertical/sidebar/sidebar-data.ts new file mode 100644 index 0000000..e52b956 --- /dev/null +++ b/theme/packages/rtl/src/app/layouts/full/vertical/sidebar/sidebar-data.ts @@ -0,0 +1,705 @@ +import { NavItem } from './nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Analytical', + iconName: 'aperture', + route: '/dashboards/dashboard1', + }, + { + displayName: 'eCommerce', + iconName: 'shopping-cart', + route: '/dashboards/dashboard2', + }, + { + displayName: 'Frontend pages', + iconName: 'app-window', + route: 'front-pages', + children: [ + { + displayName: 'Home Page', + iconName: 'point', + route: 'front-pages/homepage', + } , + { + displayName: 'About Us', + iconName: 'point', + route: 'front-pages/about', + } , + { + displayName: 'Blog', + iconName: 'point', + route: 'front-pages/blog', + } , + { + displayName: 'Blog Details', + iconName: 'point', + route: 'front-pages/blog-details', + } , + { + displayName: 'Portfolio', + iconName: 'point', + route: 'front-pages/portfolio', + }, + { + displayName: 'Pricing', + iconName: 'point', + route: 'front-pages/pricing', + }, + { + displayName: 'Contact', + iconName: 'point', + route: 'front-pages/contact', + } + ] + }, + { + navCap: 'Apps', + }, + { + displayName: 'Chat', + iconName: 'message-2', + route: 'apps/chat', + }, + { + displayName: 'Calendar', + iconName: 'calendar-event', + route: 'apps/calendar', + }, + { + displayName: 'Email', + iconName: 'mail', + route: 'apps/email/inbox', + }, + { + displayName: 'Kanban', + iconName: 'checklist', + route: 'apps/kanban', + }, + { + displayName: 'User Profile', + iconName: 'user-circle', + route: 'apps/profile-details', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'New', + children: [ + { + displayName: 'Profile', + iconName: 'point', + route: 'apps/profile-details/profile', + }, + { + displayName: 'Followers', + iconName: 'point', + route: 'apps/profile-details/followers', + }, + { + displayName: 'Friends', + iconName: 'point', + route: 'apps/profile-details/friends', + }, + { + displayName: 'Gellary', + iconName: 'point', + route: 'apps/profile-details/gallery', + }, + ], + }, + { + displayName: 'Ecommerce', + iconName: 'basket', + route: 'apps/product', + chip: true, + chipClass: 'border-error text-error', + chipContent: 'New', + children: [ + { + displayName: 'Product List', + iconName: 'point', + route: 'apps/product/product-list', + }, + { + displayName: 'Add Product', + iconName: 'point', + route: 'apps/product/add-product', + }, + { + displayName: 'Edit Product', + iconName: 'point', + route: 'apps/product/edit-product', + }, + { + displayName: 'Shop', + iconName: 'point', + route: 'apps/product/shop', + }, + ], + }, + { + displayName: 'Contacts', + iconName: 'phone', + route: 'apps/contacts', + }, + { + displayName: 'Courses', + iconName: 'certificate', + route: 'apps/courses', + }, + { + displayName: 'Employee', + iconName: 'brand-ctemplar', + route: 'apps/employee', + }, + { + displayName: 'Notes', + iconName: 'note', + route: 'apps/notes', + }, + { + displayName: 'Tickets', + iconName: 'ticket', + route: 'apps/tickets', + }, + { + displayName: 'Contact List', + iconName: 'phone', + route: 'apps/contact-list', + }, + { + displayName: 'Invoice', + iconName: 'file-invoice', + route: 'apps/invoice', + children: [ + { + displayName: 'List', + iconName: 'point', + route: 'apps/invoice/list', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/invoice/viewInvoice/101', + }, + { + displayName: 'Create', + iconName: 'point', + route: 'apps/invoice/addInvoice', + }, + { + displayName: 'Edit', + iconName: 'point', + route: 'apps/invoice/editinvoice/101', + }, + ], + }, + { + displayName: 'ToDo', + iconName: 'edit', + route: 'apps/todo', + }, + { + displayName: 'Blog', + iconName: 'chart-donut-3', + route: 'apps/blog', + children: [ + { + displayName: 'Post', + iconName: 'point', + route: 'apps/blog/post', + }, + { + displayName: 'Detail', + iconName: 'point', + route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops', + }, + ], + }, + { + navCap: 'Pages', + }, + { + displayName: 'Roll Base Access', + iconName: 'lock-access', + route: 'apps/permission', + }, + { + displayName: 'Treeview', + iconName: 'git-merge', + route: 'theme-pages/treeview', + }, + { + displayName: 'Pricing', + iconName: 'currency-dollar', + route: 'theme-pages/pricing', + }, + { + displayName: 'Account Setting', + iconName: 'user-circle', + route: 'theme-pages/account-setting', + }, + { + displayName: 'FAQ', + iconName: 'help', + route: 'theme-pages/faq', + }, + { + displayName: 'Landingpage', + iconName: 'app-window', + route: 'landingpage', + }, + { + displayName: 'Widgets', + iconName: 'layout', + route: 'widgets', + children: [ + { + displayName: 'Cards', + iconName: 'point', + route: 'widgets/cards', + }, + { + displayName: 'Banners', + iconName: 'point', + route: 'widgets/banners', + }, + { + displayName: 'Charts', + iconName: 'point', + route: 'widgets/charts', + }, + ], + }, + { + navCap: 'Forms', + }, + { + displayName: 'Form elements', + iconName: 'apps', + route: 'forms/forms-elements', + children: [ + { + displayName: 'Autocomplete', + iconName: 'point', + route: 'forms/forms-elements/autocomplete', + }, + { + displayName: 'Button', + iconName: 'point', + route: 'forms/forms-elements/button', + }, + { + displayName: 'Checkbox', + iconName: 'point', + route: 'forms/forms-elements/checkbox', + }, + { + displayName: 'Radio', + iconName: 'point', + route: 'forms/forms-elements/radio', + }, + { + displayName: 'Datepicker', + iconName: 'point', + route: 'forms/forms-elements/datepicker', + }, + ], + }, + { + displayName: 'Form Layouts', + iconName: 'file-description', + route: '/forms/form-layouts', + }, + { + displayName: 'Form Horizontal', + iconName: 'box-align-bottom', + route: '/forms/form-horizontal', + }, + { + displayName: 'Form Vertical', + iconName: 'box-align-left', + route: '/forms/form-vertical', + }, + { + displayName: 'Form Wizard', + iconName: 'files', + route: '/forms/form-wizard', + }, + { + displayName: 'Toastr', + iconName: 'notification', + route: '/forms/form-toastr', + }, + { + displayName: 'Editor', + iconName: 'edit', + route: '/forms/form-editor', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'New', + }, + { + navCap: 'Tables', + }, + { + displayName: 'Tables', + iconName: 'layout', + route: 'tables', + children: [ + { + displayName: 'Basic Table', + iconName: 'point', + route: 'tables/basic-table', + }, + { + displayName: 'Dynamic Table', + iconName: 'point', + route: 'tables/dynamic-table', + }, + { + displayName: 'Expand Table', + iconName: 'point', + route: 'tables/expand-table', + }, + { + displayName: 'Filterable Table', + iconName: 'point', + route: 'tables/filterable-table', + }, + { + displayName: 'Footer Row Table', + iconName: 'point', + route: 'tables/footer-row-table', + }, + { + displayName: 'HTTP Table', + iconName: 'point', + route: 'tables/http-table', + }, + { + displayName: 'Mix Table', + iconName: 'point', + route: 'tables/mix-table', + }, + { + displayName: 'Multi Header Footer', + iconName: 'point', + route: 'tables/multi-header-footer-table', + }, + { + displayName: 'Pagination Table', + iconName: 'point', + route: 'tables/pagination-table', + }, + { + displayName: 'Row Context Table', + iconName: 'point', + route: 'tables/row-context-table', + }, + { + displayName: 'Selection Table', + iconName: 'point', + route: 'tables/selection-table', + }, + { + displayName: 'Sortable Table', + iconName: 'point', + route: 'tables/sortable-table', + }, + { + displayName: 'Sticky Column', + iconName: 'point', + route: 'tables/sticky-column-table', + }, + { + displayName: 'Sticky Header Footer', + iconName: 'point', + route: 'tables/sticky-header-footer-table', + }, + ], + }, + { + displayName: 'Data table', + iconName: 'border-outer', + route: '/datatable/kichen-sink', + }, + { + navCap: 'Chart', + }, + { + displayName: 'Line', + iconName: 'chart-line', + route: '/charts/line', + }, + { + displayName: 'Gredient', + iconName: 'chart-arcs', + route: '/charts/gredient', + }, + { + displayName: 'Area', + iconName: 'chart-area', + route: '/charts/area', + }, + { + displayName: 'Candlestick', + iconName: 'chart-candle', + route: '/charts/candlestick', + }, + { + displayName: 'Column', + iconName: 'chart-dots', + route: '/charts/column', + }, + { + displayName: 'Doughnut & Pie', + iconName: 'chart-donut-3', + route: '/charts/doughnut-pie', + }, + { + displayName: 'Radialbar & Radar', + iconName: 'chart-radar', + route: '/charts/radial-radar', + }, + { + navCap: 'UI', + }, + { + displayName: 'Ui Components', + iconName: 'box', + route: 'ui-components', + children: [ + { + displayName: 'Badge', + iconName: 'point', + route: 'ui-components/badge', + }, + { + displayName: 'Expansion Panel', + iconName: 'point', + route: 'ui-components/expansion', + }, + { + displayName: 'Chips', + iconName: 'point', + route: 'ui-components/chips', + }, + { + displayName: 'Dialog', + iconName: 'point', + route: 'ui-components/dialog', + }, + { + displayName: 'Lists', + iconName: 'point', + route: 'ui-components/lists', + }, + { + displayName: 'Divider', + iconName: 'point', + route: 'ui-components/divider', + }, + { + displayName: 'Menu', + iconName: 'point', + route: 'ui-components/menu', + }, + { + displayName: 'Paginator', + iconName: 'point', + route: 'ui-components/paginator', + }, + { + displayName: 'Progress Bar', + iconName: 'point', + route: 'ui-components/progress', + }, + { + displayName: 'Progress Spinner', + iconName: 'point', + route: 'ui-components/progress-spinner', + }, + { + displayName: 'Ripples', + iconName: 'point', + route: 'ui-components/ripples', + }, + { + displayName: 'Slide Toggle', + iconName: 'point', + route: 'ui-components/slide-toggle', + }, + { + displayName: 'Slider', + iconName: 'point', + route: 'ui-components/slider', + }, + { + displayName: 'Snackbar', + iconName: 'point', + route: 'ui-components/snackbar', + }, + { + displayName: 'Tabs', + iconName: 'point', + route: 'ui-components/tabs', + }, + { + displayName: 'Toolbar', + iconName: 'point', + route: 'ui-components/toolbar', + }, + { + displayName: 'Tooltips', + iconName: 'point', + route: 'ui-components/tooltips', + }, + ], + }, + { + navCap: 'Auth', + }, + { + displayName: 'Login', + iconName: 'login', + route: '/authentication', + children: [ + { + displayName: 'Login 1', + iconName: 'point', + route: '/authentication/login', + }, + { + displayName: 'Boxed Login', + iconName: 'point', + route: '/authentication/boxed-login', + }, + ], + }, + { + displayName: 'Register', + iconName: 'user-plus', + route: '/authentication', + children: [ + { + displayName: 'Side Register', + iconName: 'point', + route: '/authentication/side-register', + }, + { + displayName: 'Boxed Register', + iconName: 'point', + route: '/authentication/boxed-register', + }, + ], + }, + { + displayName: 'Forgot Password', + iconName: 'rotate', + route: '/authentication', + children: [ + { + displayName: 'Side Forgot Password', + iconName: 'point', + route: '/authentication/side-forgot-pwd', + }, + { + displayName: 'Boxed Forgot Password', + iconName: 'point', + route: '/authentication/boxed-forgot-pwd', + }, + ], + }, + { + displayName: 'Two Steps', + iconName: 'zoom-code', + route: '/authentication', + children: [ + { + displayName: 'Side Two Steps', + iconName: 'point', + route: '/authentication/side-two-steps', + }, + { + displayName: 'Boxed Two Steps', + iconName: 'point', + route: '/authentication/boxed-two-steps', + }, + ], + }, + { + displayName: 'Error', + iconName: 'alert-circle', + route: '/authentication/error', + }, + { + displayName: 'Maintenance', + iconName: 'settings', + route: '/authentication/maintenance', + }, + { + navCap: 'Other', + }, + { + displayName: 'Menu Level', + iconName: 'box-multiple', + route: '/menu-level', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + { + displayName: 'Disabled', + iconName: 'ban', + route: '/disabled', + disabled: true, + }, + { + displayName: 'Chip', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-primary text-white', + chipContent: '9', + }, + { + displayName: 'Outlined', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-error text-white', + chipContent: 'outlined', + }, + { + displayName: 'External Link', + iconName: 'star', + route: 'https://www.google.com/', + external: true, + }, +]; diff --git a/theme/packages/rtl/src/app/material.module.ts b/theme/packages/rtl/src/app/material.module.ts new file mode 100644 index 0000000..8fd4750 --- /dev/null +++ b/theme/packages/rtl/src/app/material.module.ts @@ -0,0 +1,89 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +// Material Form Controls +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatSelectModule } from '@angular/material/select'; +import { MatSliderModule } from '@angular/material/slider'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +// Material Navigation +import { MatMenuModule } from '@angular/material/menu'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatToolbarModule } from '@angular/material/toolbar'; +// Material Layout +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatListModule } from '@angular/material/list'; +import { MatStepperModule } from '@angular/material/stepper'; +import { MatTabsModule } from '@angular/material/tabs'; +import { MatTreeModule } from '@angular/material/tree'; +// Material Buttons & Indicators +import { MatButtonModule } from '@angular/material/button'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatIconModule } from '@angular/material/icon'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +// Material Popups & Modals +import { MatBottomSheetModule } from '@angular/material/bottom-sheet'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { MatTooltipModule } from '@angular/material/tooltip'; +// Material Data tables +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatSortModule } from '@angular/material/sort'; +import { MatTableModule } from '@angular/material/table'; + +@NgModule({ + declarations: [], + imports: [ + + ], + exports: [ + MatAutocompleteModule, + MatCheckboxModule, + MatDatepickerModule, + MatFormFieldModule, + MatInputModule, + MatRadioModule, + MatSelectModule, + MatSliderModule, + MatSlideToggleModule, + MatMenuModule, + MatSidenavModule, + MatToolbarModule, + MatCardModule, + MatDividerModule, + MatExpansionModule, + MatGridListModule, + MatListModule, + MatStepperModule, + MatTabsModule, + MatTreeModule, + MatButtonModule, + MatButtonToggleModule, + MatBadgeModule, + MatChipsModule, + MatIconModule, + MatProgressSpinnerModule, + MatProgressBarModule, + MatRippleModule, + MatBottomSheetModule, + MatDialogModule, + MatSnackBarModule, + MatTooltipModule, + MatPaginatorModule, + MatSortModule, + MatTableModule, + ], + +}) +export class MaterialModule {} diff --git a/theme/packages/rtl/src/app/pages/apps/chat/chat.component.html b/theme/packages/rtl/src/app/pages/apps/chat/chat.component.html new file mode 100644 index 0000000..1530c1f --- /dev/null +++ b/theme/packages/rtl/src/app/pages/apps/chat/chat.component.html @@ -0,0 +1,123 @@ + + + + + + + +
+ +
+

Mathew Anderson

+ info@modernize.com +
+
+ +
+ + + + + + + +
+ + @if (filteredMessages() && filteredMessages().length > 0) { +
+ + @for(message of filteredMessages(); track message.from) { + + + + +

+ {{ message.from }} +

+

+ {{ message.subject }} +

+
+ } +
+
+ } @else { +
+ No messages found. +
+ } +
+
+ + + + + + +
+ +
+ {{ selectedMessage()?.from }} +
+
+ + + + + + +
+ + + + + + + @for(c of selectedMessage()?.chat; track c) { @if(c.type === 'odd') { +
+
+
+ + {{ c.msg }} +
+ + {{ c.date | date }} + +
+
+ } @else { +
+
+
+ {{ c.msg }} +
+ + {{ c.date | date }} + +
+
+ } } +
+
+ +
+ + + + +
+
+
+
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/apps/fullcalendar/fullcalendar.component.ts b/theme/packages/rtl/src/app/pages/apps/fullcalendar/fullcalendar.component.ts new file mode 100644 index 0000000..a4565ca --- /dev/null +++ b/theme/packages/rtl/src/app/pages/apps/fullcalendar/fullcalendar.component.ts @@ -0,0 +1,286 @@ +import { + Component, + ChangeDetectionStrategy, + Inject, + signal, + DOCUMENT +} from '@angular/core'; +import { CommonModule, NgSwitch } from '@angular/common'; +import { + MatDialog, + MatDialogRef, + MatDialogConfig, + MAT_DIALOG_DATA, + MatDialogModule, +} from '@angular/material/dialog'; +import { + FormsModule, + ReactiveFormsModule, + UntypedFormGroup, +} from '@angular/forms'; +import { CalendarFormDialogComponent } from './calendar-form-dialog/calendar-form-dialog.component'; +import { + startOfDay, + subDays, + addDays, + endOfMonth, + isSameDay, + isSameMonth, + addHours, + subMonths, + addMonths, +} from 'date-fns'; +import { Subject } from 'rxjs'; +import { + CalendarDateFormatter, + CalendarEvent, + CalendarEventAction, + CalendarEventTimesChangedEvent, + CalendarModule, + CalendarView, +} from 'angular-calendar'; +import { MaterialModule } from 'src/app/material.module'; +import { + MatNativeDateModule, + provideNativeDateAdapter, +} from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +const colors: any = { + red: { + primary: '#fa896b', + secondary: '#fdede8', + }, + blue: { + primary: '#5d87ff', + secondary: '#ecf2ff', + }, + yellow: { + primary: '#ffae1f', + secondary: '#fef5e5', + }, +}; + +@Component({ + selector: 'app-calendar-dialog', + templateUrl: './dialog.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + CommonModule, + MatNativeDateModule, + MatDialogModule, + MatDatepickerModule, TablerIconsModule + ], + providers: [provideNativeDateAdapter()], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CalendarDialogComponent { + options!: UntypedFormGroup; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) {} +} + +@Component({ + selector: 'app-fullcalendar', + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './fullcalendar.component.html', + imports: [ + MaterialModule, + FormsModule, + ReactiveFormsModule, + NgSwitch, + CalendarModule, + CommonModule, + MatDatepickerModule, + MatDialogModule, + MatFormFieldModule, + ], + providers: [provideNativeDateAdapter(), CalendarDateFormatter] +}) +export class AppFullcalendarComponent { + dialogRef = signal | any>(null); + dialogRef2 = signal | any>(null); + lastCloseResult = signal(''); + actionsAlignment = signal(''); + view = signal('month'); + viewDate = signal(new Date()); + activeDayIsOpen = signal(true); + + config: MatDialogConfig = { + disableClose: false, + width: '', + height: '', + position: { + top: '', + bottom: '', + left: '', + right: '', + }, + data: { + action: '', + event: [], + }, + }; + numTemplateOpens = 0; + + actions: CalendarEventAction[] = [ + { + label: ': Edit', + onClick: ({ event }: { event: CalendarEvent }): void => { + this.handleEvent('Edit', event); + }, + }, + { + label: 'Delete', + onClick: ({ event }: { event: CalendarEvent }): void => { + this.events.set( + this.events().filter((iEvent: CalendarEvent) => iEvent !== event) + ); + this.handleEvent('Deleted', event); + }, + }, + ]; + + refresh: Subject = new Subject(); + + events = signal([ + { + start: subDays(startOfDay(new Date()), 1), + end: addDays(new Date(), 1), + title: 'A 3 day event', + color: colors.red, + actions: this.actions, + }, + { + start: startOfDay(new Date()), + title: 'An event with no end date', + color: colors.blue, + actions: this.actions, + }, + { + start: subDays(endOfMonth(new Date()), 3), + end: addDays(endOfMonth(new Date()), 3), + title: 'A long event that spans 2 months', + color: colors.blue, + }, + { + start: addHours(startOfDay(new Date()), 2), + end: new Date(), + title: 'A draggable and resizable event', + color: colors.yellow, + actions: this.actions, + resizable: { + beforeStart: true, + afterEnd: true, + }, + draggable: true, + }, + ]); + + constructor(public dialog: MatDialog, @Inject(DOCUMENT) doc: any) {} + + dayClicked({ date, events }: { date: Date; events: CalendarEvent[] }): void { + if (isSameMonth(date, this.viewDate())) { + if ( + (isSameDay(this.viewDate(), date) && this.activeDayIsOpen() === true) || + events.length === 0 + ) { + this.activeDayIsOpen.set(false); + } else { + this.activeDayIsOpen.set(true); + this.viewDate.set(date); + } + } + } + + eventTimesChanged({ + event, + newStart, + newEnd, + }: CalendarEventTimesChangedEvent): void { + this.events.set( + this.events().map((iEvent: CalendarEvent) => { + if (iEvent === event) { + return { + ...event, + start: newStart, + end: newEnd, + }; + } + return iEvent; + }) + ); + + this.handleEvent('Dropped or resized', event); + } + + handleEvent(action: string, event: CalendarEvent): void { + this.config.data = { event, action }; + this.dialogRef.set(this.dialog.open(CalendarDialogComponent, this.config)); + + this.dialogRef() + .afterClosed() + .subscribe((result: string) => { + this.lastCloseResult.set(result); + this.dialogRef.set(null); + this.refresh.next(result); + }); + } + + addEvent(): void { + this.dialogRef2.set( + this.dialog.open(CalendarFormDialogComponent, { + panelClass: 'calendar-form-dialog', + autoFocus: false, + data: { + action: 'add', + date: new Date(), + }, + }) + ); + this.dialogRef2() + .afterClosed() + .subscribe((res: { action: any; event: any }) => { + if (!res) { + return; + } + const dialogAction = res.action; + const responseEvent = res.event; + responseEvent.actions = this.actions; + this.events.set([...this.events(), responseEvent]); + this.dialogRef2.set(null); + this.refresh.next(res); + }); + } + + deleteEvent(eventToDelete: CalendarEvent): void { + this.events.set( + this.events().filter( + (event: CalendarEvent) => event !== eventToDelete + ) + ); + } + + setView(view: CalendarView | any): void { + this.view.set(view); + } + + goToPreviousMonth(): void { + this.viewDate.set(subMonths(this.viewDate(), 1)); + } + + goToNextMonth(): void { + this.viewDate.set(addMonths(this.viewDate(), 1)); + } + + goToToday() { + this.viewDate.set(new Date()); + } +} diff --git a/theme/packages/rtl/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html b/theme/packages/rtl/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html new file mode 100644 index 0000000..027a82b --- /dev/null +++ b/theme/packages/rtl/src/app/pages/apps/invoice/add-invoice/add-invoice.component.html @@ -0,0 +1,156 @@ + + +
+
+
+

+ # + + {{ invoice().id }} +

+
+
+ + Cancel + + +
+
+ + + +
+
+ + Order Status: + + +
+ {{ invoice().status }} +
+
+
+
+ + Order Date + +
+ {{ invoice().orderDate | date : "dd-MM-yyyy" }} +
+
+
+
+ + + +
+
+ + Bill From + + +
+
+ + Bill To + + +
+
+ + Enter From Address + + +
+
+ + Bill From + + +
+
+
+ +
+
+ + + + + + + + + + + + + @for(row of addForm.get('rows')['controls']; track row; let index = + $index) { + + + + + + + + + + + + + + } + +
#Item NameUnit PriceUnitsUnit Total Price
+ {{ index + 1 }} + + + + + + + + + + + + + + + + + + @if(addForm.get('rows')) { + + } + + @if(index > 0) { + + } +
+
+ +
+
Sub total: {{ subTotal() }}
+
Total Vat: {{ vat() }}%
+ +

Grand Total: {{ grandTotal() }}

+
+
+
+
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html b/theme/packages/rtl/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html new file mode 100644 index 0000000..f5f0397 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.html @@ -0,0 +1,239 @@ + + + @if( invoice()) { + +
+
+
+

+ # + + {{ invoice().id }} +

+
+
+ + Cancel + + + +
+
+ + + +
+
+ Order Status: + + + Pending + Shipped + Delivered + + +
+
+
+ Order Date +
+ {{ invoice().orderDate | date : "dd-MM-yyyy" }} +
+
+
+
+ + + +
+
+ + Bill From + + +
+
+ + Bill To + + +
+
+ + Enter From Address + + +
+
+ + Bill From + + +
+
+
+
+ } + +
+
+ + + + + + + + + + + + + @for(a of addForm.get('item')['controls']; track a; let i =$index) { + + + + + + + + + + + + } +
#Item NameUnit PriceUnitsUnit Total Price
+ {{ i + 1 }} + + + + + + + + + + + + + + + + + + + + @if(addForm.get('item')?.length > 1) { + + } +
+
+ +
+
+ @if(addForm.get('rows')) { + + } + +
Sub total: {{ subTotal() }}
+
Total Vat: {{ vat() }}%
+ +

Grand Total: {{ grandTotal() }}

+
+
+
+
+
diff --git a/theme/packages/rtl/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts b/theme/packages/rtl/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts new file mode 100644 index 0000000..3e5b5b4 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/apps/invoice/edit-invoice/edit-invoice.component.ts @@ -0,0 +1,164 @@ +import { Component, signal } from '@angular/core'; +import { ActivatedRoute, Router, RouterLink } from '@angular/router'; +import { InvoiceService } from 'src/app/services/apps/invoice/invoice.service'; +import { InvoiceList, order } from '../invoice'; +import { + UntypedFormGroup, + UntypedFormArray, + UntypedFormBuilder, + Validators, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { OkDialogComponent } from './ok-dialog/ok-dialog.component'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MatSnackBar } from '@angular/material/snack-bar'; +@Component({ + selector: 'app-edit-invoice', + templateUrl: './edit-invoice.component.html', + imports: [ + MaterialModule, + CommonModule, + RouterLink, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ], +}) +export class AppEditInvoiceComponent { + id = signal(null); + subTotal = signal(0); + vat = signal(0); + grandTotal = signal(0); + addForm: UntypedFormGroup | any; + invoice = signal([]); + constructor( + activatedRouter: ActivatedRoute, + private invoiceService: InvoiceService, + private router: Router, + private fb: UntypedFormBuilder, + public dialog: MatDialog, + private snackBar: MatSnackBar + ) { + this.id.set(activatedRouter.snapshot.paramMap.get('id')); + this.loadInvoice(); // Load invoice here + this.subTotal.set(this.invoice()?.totalCost || 0); + this.vat.set(this.invoice()?.vat || 0); + this.grandTotal.set(this.invoice()?.grandTotal || 0); + this.addForm = this.fb.group({ + item: this.fb.array([this.itemControl()]), + }); + + this.fillAddControls(); + } + + loadInvoice(): void { + const invoiceData = this.invoiceService + .getInvoiceList() + .find((x) => x.id === +this.id()); + this.invoice.set(invoiceData); // Set the invoice signal + } + itemControl(): UntypedFormGroup { + return this.fb.group({ + itemName: ['', Validators.required], + itemCost: ['', Validators.required], + itemSold: ['', Validators.required], + itemTotal: [{ value: 0, disabled: true }], + }); + } + + fillAddControls(): void { + this.addForm.setControl('item', this.setItem(this.invoice()?.orders)); + } + + setItem(order: any): UntypedFormArray { + const fa = new UntypedFormArray([]); + order?.forEach((s: any) => { + fa.push( + this.fb.group({ + itemName: s.itemName, + itemCost: s.unitPrice, + itemSold: s.units, + itemTotal: s.unitTotalPrice, + }) + ); + }); + return fa; + } + + btnAddItemClick(): void { + (this.addForm.get('item')).push(this.itemControl()); + } + + btnRemoveClick(i: number): void { + const totalCostOfItem = + this.addForm.get('item')?.value[i].itemCost * + this.addForm.get('item')?.value[i].itemSold; + + this.subTotal.set(this.subTotal() - totalCostOfItem); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + + (this.addForm.get('item')).removeAt(i); + } + + itemsChanged(): void { + let total = 0; + for ( + let t = 0; + t < (this.addForm.get('item')).length; + t++ + ) { + if ( + this.addForm.get('item')?.value[t].itemCost != '' && + this.addForm.get('item')?.value[t].itemSold + ) { + total += + this.addForm.get('item')?.value[t].itemCost * + this.addForm.get('item')?.value[t].itemSold; + } + } + this.subTotal.set(total); + this.vat.set(this.subTotal() / 10); + this.grandTotal.set(this.subTotal() + this.vat()); + } + + saveDetail(event: Event): void { + event.preventDefault(); + const currentInvoice = this.invoice(); + if (currentInvoice) { + currentInvoice.grandTotal = this.grandTotal(); + currentInvoice.totalCost = this.subTotal(); + currentInvoice.vat = this.vat(); + currentInvoice.orders = []; + + for ( + let t = 0; + t < (this.addForm.get('item')).length; + t++ + ) { + const o: order = new order(); + o.itemName = this.addForm.get('item')?.value[t].itemName; + o.unitPrice = this.addForm.get('item')?.value[t].itemCost; + o.units = this.addForm.get('item')?.value[t].itemSold; + o.unitTotalPrice = o.units * o.unitPrice; + currentInvoice.orders.push(o); + } + this.dialog.open(OkDialogComponent); + this.invoiceService.updateInvoice(currentInvoice.id, currentInvoice); + this.router.navigate(['/apps/invoice/list']); + this.showSnackbar('Invoice updated successfully!'); + } + } + + showSnackbar(message: string): void { + this.snackBar.open(message, 'Close', { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } +} diff --git a/theme/packages/rtl/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html b/theme/packages/rtl/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html new file mode 100644 index 0000000..3942ba6 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/apps/invoice/invoice-list/invoice-list.component.html @@ -0,0 +1,281 @@ +
+
+ + +
+ +
+
+
Total
+
+ {{ allInvoices().length }} invoices +
+
+
+
+
+
+ + +
+ +
+
+
Shipped
+
+ {{ countInvoicesByStatus("Shipped") }} invoices +
+
+
+
+
+ +
+ + +
+ +
+
+
Delivered
+
+ {{ countInvoicesByStatus("Delivered") }} invoices +
+
+
+
+
+ +
+ + +
+ +
+
+
Pending
+
+ {{ countInvoicesByStatus("Pending") }} invoices +
+
+
+
+
+
+ + + +
+
+ + + + + + +
+ +
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + Id + + {{ element.id }} + + Bill From + + {{ element.billFrom }} + + Bill To + + {{ element.billTo }} + + Total Cost + + {{ element.totalCost }} + + Status + + + {{ element.status }} + + + Action + + + + + + + + + + + +
+ +
+
+
diff --git a/theme/packages/rtl/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html b/theme/packages/rtl/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html new file mode 100644 index 0000000..b3bbc15 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/apps/invoice/invoice-view/invoice-view.component.html @@ -0,0 +1,125 @@ + + + @if(invoiceDetail()){ + +
+
+

#{{ invoiceDetail()?.id }}

+
+ +
+ +
+
+ Order Status: +
+ {{ invoiceDetail()?.status }} +
+
+
+ Order Date: +
+ {{ invoiceDetail()?.orderDate | date : "fullDate" }} +
+
+
+ +
+
+ Bill From: +
+ {{ invoiceDetail()?.billFrom }} +
+
+ {{ invoiceDetail()?.billFromEmail }} +
+
+ {{ invoiceDetail()?.billFromAddress }} +
+
+ {{ invoiceDetail()?.billFromPhone }} +
+
+
+ Bill To: +
+ {{ invoiceDetail()?.billTo }} +
+
+ {{ invoiceDetail()?.billToEmail }} +
+
+ {{ invoiceDetail()?.billToAddress }} +
+
+ {{ invoiceDetail()?.billToPhone }} +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ Item Name + + {{ element.itemName }} + + Unit Price + + {{ element.unitPrice }} + + Unit + + {{ element.units }} + + Total Cost + + {{ element.unitTotalPrice }} +
+
+ +
+
+ Sub total: {{ invoiceDetail()?.totalCost }} +
+ Vat: 10% +

+ Grand Total: {{ invoiceDetail()?.grandTotal }} +

+
+
+ } +
+
diff --git a/theme/packages/rtl/src/app/pages/apps/tickets/ticket-dialog-content.html b/theme/packages/rtl/src/app/pages/apps/tickets/ticket-dialog-content.html new file mode 100644 index 0000000..19f96d5 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/apps/tickets/ticket-dialog-content.html @@ -0,0 +1,132 @@ +@if(action !== 'Delete') { + +
+

{{action}} Ticket

+ +
+
+
+ @if(action === 'Update') { +
+ Ticket Id + + + +
+ } + +
+ Ticket Title + + + +
+
+ Ticket Subtext + + + +
+
+ Assign User + + + @for(user of users; track trackByUser(user)) { + +
+ {{ user.name }} + {{ user.name }} +
+
+ } +
+
+
+ @if(action === 'Update'){ +
+ Status + + + +
+ } @if(action === 'Update') { +
+ + Date + + + + +
+ } +
+
+
+} @else { +
+ Sure to delete {{local_data.title}}? +
+} +
+ + +
diff --git a/theme/packages/rtl/src/app/pages/apps/tickets/tickets.component.ts b/theme/packages/rtl/src/app/pages/apps/tickets/tickets.component.ts new file mode 100644 index 0000000..f1b5f6c --- /dev/null +++ b/theme/packages/rtl/src/app/pages/apps/tickets/tickets.component.ts @@ -0,0 +1,177 @@ +import { + Component, + OnInit, + ViewChild, + AfterViewInit, + Inject, +} from '@angular/core'; +import { MatTableDataSource, MatTable } from '@angular/material/table'; +import { + MatDialog, + MatDialogRef, + MAT_DIALOG_DATA, +} from '@angular/material/dialog'; +import { MatPaginator } from '@angular/material/paginator'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TicketService } from 'src/app/services/apps/ticket/ticket.service'; +import { TicketElement } from 'src/app/pages/apps/tickets/ticket'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +@Component({ + selector: 'app-ticket-list', + templateUrl: './tickets.component.html', + imports: [MaterialModule, CommonModule, TablerIconsModule], +}) +export class AppTicketlistComponent implements OnInit, AfterViewInit { + @ViewChild(MatTable, { static: true }) table: MatTable; + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; + + searchText: string = ''; + totalCount = 0; + Closed = 0; + Inprogress = 0; + Open = 0; + + displayedColumns: string[] = [ + 'id', + 'title', + 'assignee', + 'status', + 'date', + 'action', + ]; + + dataSource = new MatTableDataSource([]); + + constructor(private ticketService: TicketService, public dialog: MatDialog) {} + + ngOnInit(): void { + this.loadTickets(); // Load the initial tickets + } + + private loadTickets(): void { + const tickets = this.ticketService.tickets$; // Get tickets from the service + this.dataSource.data = tickets; // Set the dataSource to the tickets + + // Update counts based on the current tickets + this.updateCounts(); + } + + private updateCounts(): void { + this.totalCount = this.dataSource.data.length; + this.Open = this.countTicketsByStatus('open'); + this.Closed = this.countTicketsByStatus('closed'); + this.Inprogress = this.countTicketsByStatus('inprogress'); + } + + ngAfterViewInit(): void { + this.dataSource.paginator = this.paginator; + } + + onKeyup(event: KeyboardEvent): void { + const input = event.target as HTMLInputElement; + this.applyFilter(input.value); + } + applyFilter(filterValue: string): void { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + btnCategoryClick(val: string): number { + this.dataSource.filter = val.trim().toLowerCase(); + return this.dataSource.filteredData.length; + } + + openDialog(action: string, ticket: TicketElement | any): void { + const dialogRef = this.dialog.open(TicketDialogComponent, { + data: { action, ticket }, + autoFocus: false, + }); + + dialogRef.afterClosed().subscribe(() => { + this.loadTickets(); + }); + } + + countTicketsByStatus(status: string): number { + return this.dataSource.data.filter( + (ticket) => ticket.status.toLowerCase() === status.toLowerCase() + ).length; + } +} + +@Component({ + // tslint:disable-next-line - Disables all + selector: 'app-dialog-content', + templateUrl: 'ticket-dialog-content.html', + imports: [ + MaterialModule, + CommonModule, + TablerIconsModule, + FormsModule, + ReactiveFormsModule, + TablerIconsModule, + ], +}) +export class TicketDialogComponent { + action: string; + local_data: TicketElement; + users: any[] = []; + dateControl = new FormControl(); + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + private ticketService: TicketService, + private snackBar: MatSnackBar + ) { + this.action = data.action; + this.local_data = { ...data.ticket }; + } + + ngOnInit(): void { + this.users = this.ticketService.getUsers(); // Get users from the service + + if (this.local_data.date) { + this.dateControl.setValue( + new Date(this.local_data.date).toISOString().split('T')[0] + ); // existing date + } else { + // Set to today's date if no existing date is available + this.dateControl.setValue(new Date().toISOString().split('T')[0]); + } + } + + doAction(): void { + this.local_data.date = this.dateControl.value; // Update local_data with the new date + + if (this.action === 'Update') { + this.ticketService.updateTicket(this.local_data); + this.openSnackBar('Ticket updated successfully!', 'Close'); + } else if (this.action === 'Add') { + this.ticketService.addTicket(this.local_data); + this.openSnackBar('Ticket added successfully!', 'Close'); + } else if (this.action === 'Delete') { + this.ticketService.deleteTicket(this.local_data.id); + this.openSnackBar('Ticket deleted successfully!', 'Close'); + } + this.dialogRef.close(); + } + + openSnackBar(message: string, action: string): void { + this.snackBar.open(message, action, { + duration: 3000, + horizontalPosition: 'center', + verticalPosition: 'top', + }); + } + closeDialog(): void { + this.dialogRef.close(); + } + + trackByUser(user: any): any { + return user.id; + } +} diff --git a/theme/packages/rtl/src/app/pages/forms/form-editor/form-editor.component.html b/theme/packages/rtl/src/app/pages/forms/form-editor/form-editor.component.html new file mode 100644 index 0000000..8ebd610 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/forms/form-editor/form-editor.component.html @@ -0,0 +1,8 @@ + + +
+ + +
+
+
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/forms/form-editor/form-editor.component.ts b/theme/packages/rtl/src/app/pages/forms/form-editor/form-editor.component.ts new file mode 100644 index 0000000..130e645 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/forms/form-editor/form-editor.component.ts @@ -0,0 +1,34 @@ +import { Component } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; +import { NgxEditorComponent, NgxEditorMenuComponent, Editor, Toolbar } from 'ngx-editor'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-form-editor', + imports: [MatCardModule, NgxEditorComponent, NgxEditorMenuComponent, FormsModule], + templateUrl: './form-editor.component.html' +}) +export class AppFormEditorComponent { + + html = ''; + editor: Editor; + ngOnInit(): void { + this.editor = new Editor(); + } + + ngOnDestroy(): void { + this.editor.destroy(); + } + + toolbar: Toolbar = [ + ['bold', 'italic'], + ['underline'], + ['ordered_list', 'bullet_list'], + [{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }], + ['link', 'image'], + ['text_color', 'background_color'], + ['align_left', 'align_center', 'align_right', 'align_justify'], + ]; + + constructor() { } +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.html b/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.html new file mode 100644 index 0000000..0fef605 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.html @@ -0,0 +1,169 @@ +
+ + +
+
+

+ The hassle-free setup process +

+
+ @for(topcard of setupCards; track topcard.title) { +
+ + +
+ @if(topcard.id!==2){ + users + } + +
+ {{ topcard.title }} +
+

+ {{ topcard.subtitle }} +

+ @if(topcard.id===2){ + image + } +
+
+
+
+ } +
+
+
+ + + +
+
+
+
+
+

Key metric at a glance

+

+ From the year we were founded to the impressive customer base + we've built, and the growth percentages that reflect our + continuous improvement, these numbers tell our story at a glance. + Explore the data that drives our mission and underscores our + commitment to excellence. +

+
+
+
+
+ @for (stat of stats; track stat) { +
+
+

+ {{ stat.label }} +

+

+ {{ stat.value }} +

+

{{ stat.description }}

+
+
+ } +
+
+
+
+
+ +
+ +
+ +
+
+
+ +
+
+

+ What our clients
think logo + about us? +

+

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+
+
+
+ + + Features availability + +
+
+ +
+
{{ currentUser().name }}
+
+ +

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+ + + +
+ + + {{ displayCount() }} + + +
+
+
+
+
+
+
+ + + +
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.scss b/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.scss new file mode 100644 index 0000000..e5e27d5 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.scss @@ -0,0 +1,23 @@ +.contact-page { + + .setup-process { + + mat-card-content { + padding: 0px !important; + padding: 30px 16px !important; + } + } + + .key-metric { + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + } + + .features { + + .cardWithShadow { + mat-card-content { + padding: 0px !important; + } + } + } +} \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.spec.ts new file mode 100644 index 0000000..0d075ce --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AboutUsComponent } from './about-us.component'; + +describe('AboutUsComponent', () => { + let component: AboutUsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AboutUsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AboutUsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.ts b/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.ts new file mode 100644 index 0000000..497b22d --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/about-us/about-us.component.ts @@ -0,0 +1,48 @@ +import { Component, computed, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { ImageSliderComponent } from '../image-slider/image-slider.component'; +import { FooterComponent } from '../footer/footer.component'; +//import { PagePricingComponent } from '../page-pricing/page-pricing.component'; +import { + setupCards, + stats, + users, +} from '../front-pagesData'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-about-us', + imports: [IconModule,MaterialModule ,CommonModule,ImageSliderComponent,FooterComponent, + //PagePricingComponent + ], + templateUrl: './about-us.component.html', + styleUrl: './about-us.component.scss' +}) +export class AboutUsComponent { + setupCards=setupCards; + stats = stats; + currentIndex = signal(0); // Starting from 0 + users = users; + // Computed values to auto-update template + currentUser = computed(() => this.users[this.currentIndex()]); + displayCount = computed( + () => `${this.currentIndex() + 1}/${this.users.length}` + ); + goPrev() { + if (this.currentIndex() > 0) { + this.currentIndex.update((i) => i - 1); + } + } + + goNext() { + if (this.currentIndex() < this.users.length - 1) { + this.currentIndex.update((i) => i + 1); + } + + + } + + + +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.html b/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.html new file mode 100644 index 0000000..020f82c --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.html @@ -0,0 +1,116 @@ + + +
+
+ + + + @if(blogDetail()) { + + Photo of a Shiba Inu +
+ 2 mins Read +
+ +
+
+ +
+ {{ + blogDetail()?.category }} +
+ + {{ + blogDetail()?.title }} + +
+
+ {{ + blogDetail()?.views }} + 4 +
+ + + {{ blogDetail()?.date }} + +
+
+ +

Main Heading & Points

+

+ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the + industry's standard dummy text ever since + the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It + has survived not only five centuries, + but also the leap into electronic typesetting, + remaining essentially unchanged. It was popularised in the +

+
    +
  • Vivamus eu lacus scelerisque, placerat commodo lectus.
  • +
  • Etiam et ante at ex porta fringilla.
  • +
  • Nullam dignissim sem eu magna aliquet, sit amet volutpat tellus
  • +
+

+ Unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not + only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was + popularised in the +

+ +

+ We are a dedicated team of passionate product managers, developers, UX/UI designers, QA engineers experts + helping businesses from new startups +

+ +

+ There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in + some form, by injected humour, or randomised words which don't look even slightly believable making this the + first true generator on the Internet. It uses a dictionary +

+ +

Tags

+
    +
  • Trends
  • +
  • Design
  • +
  • Research
  • +
+ + +

Share

+ + + +

Join our newsletter

+

Email address : Subscribe

+
+
+ } + + + + + + @if (!blogDetail() || blogDetail().length === 0) { + + +

No blog post available.

+
+
+ } +
+
+ + \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.scss b/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts new file mode 100644 index 0000000..241ed7b --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlogDetailsComponent } from './blog-details.component'; + +describe('BlogDetailsComponent', () => { + let component: BlogDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BlogDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BlogDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.ts b/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.ts new file mode 100644 index 0000000..9633085 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/blog-details/blog-details.component.ts @@ -0,0 +1,40 @@ +import { CommonModule } from '@angular/common'; +import { Component, inject, OnInit, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; +import { FrontEndService } from 'src/app/services/apps/front-pages/front-end.service'; + +@Component({ + selector: 'app-blog-details', + imports: [IconModule, MaterialModule, CommonModule, + FooterComponent + ], + templateUrl: './blog-details.component.html', + styleUrl: './blog-details.component.scss' +}) +export class BlogDetailsComponent implements OnInit { + blogDetail = signal(null); + private frontendService = inject(FrontEndService); + ngOnInit(): void { + const selected = this.frontendService.getBlog()(); + + if (selected) { + this.blogDetail.set(selected); + } else { + // Fallback if accessed directly (e.g., from sidebar or refresh) + const defaultBlog = { + id: 1, + time: "2 mins Read", + imgSrc: "/assets/images/blog/blog-img1.jpg", + user: "/assets/images/profile/user-1.jpg", + title: "As yen tumbles, gadget-loving Japan goes for secondhand iPhones", + views: "9,125", + category: "Social", + comments: 3, + date: "Mon, Dec 23" + }; + this.blogDetail.set(defaultBlog); + } + } +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.html b/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.html new file mode 100644 index 0000000..e30ba7c --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.html @@ -0,0 +1,55 @@ + + +
+
+
+ @for(cardimg of cardimgs; track cardimg.imgSrc) { +
+ + Photo of a Shiba Inu +
+ {{ + cardimg.time + }} +
+ + +
+
+ +
+ {{ + cardimg.category + }} +
+ {{ cardimg.title }} +
+
+ {{ cardimg.views }} + {{ cardimg.comments }} +
+ + + {{ cardimg.date }} + +
+
+
+
+ } +
+
+
+ + \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.scss b/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.scss new file mode 100644 index 0000000..e5dce08 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.scss @@ -0,0 +1,24 @@ + + +.social-btns { + margin-top: 20px; + + .btn-icon { + width: 25px !important; + height: 25px !important; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + + tabler-icon { + width: 16px !important; + height: 16px !important; + } + } + + .btn-add-story { + font-size: 0.75rem; + padding: 0.35rem 0.75rem; + } +} \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.spec.ts new file mode 100644 index 0000000..7998b08 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BlogComponent } from './blog.component'; + +describe('BlogComponent', () => { + let component: BlogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BlogComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BlogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.ts b/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.ts new file mode 100644 index 0000000..d25328e --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/blog/blog.component.ts @@ -0,0 +1,32 @@ +import { Component, inject, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { cardimgs } from '../front-pagesData'; +import { FooterComponent } from '../footer/footer.component'; +import { Router } from '@angular/router'; +import { FrontEndService } from 'src/app/services/apps/front-pages/front-end.service'; + +@Component({ + selector: 'app-blog', + imports: [IconModule, MaterialModule, FooterComponent,], + templateUrl: './blog.component.html', + styleUrl: './blog.component.scss' +}) +export class BlogComponent implements OnInit { + + private router = inject(Router); + private frontendService = inject(FrontEndService); + cardimgs = cardimgs; + + ngOnInit() { + console.log(cardimgs, 'cardimgs'); + } + + getNavigate(cardimg: any) { + console.log('cardimg--->', cardimg); + this.frontendService.setBlog(cardimg); + this.router.navigate(['front-pages/blog-details']) + + } + +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.html b/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.html new file mode 100644 index 0000000..f2cfc62 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.html @@ -0,0 +1,103 @@ +
+ + + +
+
+
+ +
+ +
+
+
+
+
+
+ + First Name* + + + + + Phone Number* + + + +
+
+ + Last Name* + + + + + Email* + + + +
+
+ +
+
+ Enquire related to* + + + + General Enquiry + General Enquiry 2 + + +
+
+
+
+ Message + + + +
+
+ +
+
+ + +
+
Reach Out Today
+

+ Have questions or need assistance? We're just a message + away. +

+
+ +
+
Our Location
+

+ Visit us in person or find our contact details to connect + with us directly. +

+
+
+
+
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.scss b/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.scss new file mode 100644 index 0000000..572fa27 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.scss @@ -0,0 +1,3 @@ +.map-container{ + margin-top: -200px; +} \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.spec.ts new file mode 100644 index 0000000..dae8ee6 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ContactComponent } from './contact.component'; + +describe('ContactComponent', () => { + let component: ContactComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ContactComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ContactComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.ts b/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.ts new file mode 100644 index 0000000..556ed9a --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/contact/contact.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; + +@Component({ + selector: 'app-contact', + imports: [MaterialModule,IconModule,FooterComponent], + templateUrl: './contact.component.html', + styleUrl: './contact.component.scss' +}) +export class ContactComponent { + +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.html b/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.html new file mode 100644 index 0000000..0177911 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.html @@ -0,0 +1,94 @@ + \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.scss b/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.scss new file mode 100644 index 0000000..6a425bb --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.scss @@ -0,0 +1,13 @@ + +.footer-content{ + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } +} + +.imgStyleDash { + position: absolute; +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.spec.ts new file mode 100644 index 0000000..3f93915 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FooterComponent } from './footer.component'; + +describe('FooterComponent', () => { + let component: FooterComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FooterComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FooterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.ts b/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.ts new file mode 100644 index 0000000..7864854 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/footer/footer.component.ts @@ -0,0 +1,95 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { RouterLink } from '@angular/router'; + +@Component({ + selector: 'app-footer', + imports: [MaterialModule, IconModule, RouterLink], + templateUrl: './footer.component.html', + styleUrl: './footer.component.scss' +}) +export class FooterComponent { + applicationsItems = [ + { + title: 'Kanban', + href: "/apps/kanban" + }, + { + title: 'Invoice List', + href: "/apps/invoice/list" + }, + { + title: 'eCommerce', + href: "/apps/product/shop" + }, + { + title: 'Chats', + href: "/apps/chat" + }, + { + title: 'Tickets', + href: "/apps/tickets" + }, + { + title: 'Blog', + href: "/apps/blog/post" + }, + ]; + + formsItems = [ + { + title: 'Form Layout', + href: "/forms/form-layouts" + }, + { + title: 'Form Horizontal', + href: "/forms/form-horizontal" + }, + { + title: 'Form Wizard', + href: "/forms/form-wizard" + }, + { + title: 'Form Vertical', + href: "/forms/form-vertical" + }, + { + title: 'Form Toastr', + href: "/forms/form-toastr" + }, + ]; + + tablesItems = [ + { + title: 'Basic Table', + href: "/tables/basic-table" + }, + { + title: 'Multi Header Footer Table', + href: "/tables/multi-header-footer-table" + }, + { + title: 'Pagination Table', + href: "/tables/pagination-table" + }, + { + title: 'Dynamic Table', + href: "/tables/dynamic-table" + }, + { + title: 'HTTP Table', + href: "/tables/http-table" + }, + { + title: 'Sortable Table', + href: "/tables/sortable-table" + }, + ]; + + socialIcons = [ + { src: 'assets/images/front-pages/icon-facebook.svg', tooltip: 'Facebook' }, + { src: 'assets/images/front-pages/icon-twitter.svg', tooltip: 'Twitter' }, + { src: 'assets/images/front-pages/icon-instagram.svg', tooltip: 'Instagram' }, + ]; +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/front-pages.routes.ts b/theme/packages/rtl/src/app/pages/front-pages/front-pages.routes.ts new file mode 100644 index 0000000..bf9375c --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/front-pages.routes.ts @@ -0,0 +1,28 @@ +import { Routes } from '@angular/router'; +import { HomepageComponent } from './homepage/homepage.component'; +import { AboutUsComponent } from './about-us/about-us.component'; +import { HomepageDetailsComponent } from './homepage-details/homepage-details.component'; +import { BlogComponent } from './blog/blog.component'; +import { PortfolioComponent } from './portfolio/portfolio.component'; +import { PricingComponent } from './pricing/pricing.component'; +import { ContactComponent } from './contact/contact.component'; +import { BlogDetailsComponent } from './blog-details/blog-details.component'; + + +export const FrontPagesRoutes: Routes = [ + + { + path: '', + component: HomepageComponent, // acts as layout shell + children: [ + { path: '', redirectTo: 'homepage', pathMatch: 'full' }, + { path: 'homepage', component: HomepageDetailsComponent }, // real homepage content + { path: 'about', component: AboutUsComponent }, + {path:'blog',component:BlogComponent }, + { path: 'portfolio', component: PortfolioComponent }, + { path: 'pricing', component: PricingComponent }, + { path: 'contact', component: ContactComponent }, + { path: 'blog-details', component: BlogDetailsComponent }, + ], + }, +]; \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/front-pagesData.ts b/theme/packages/rtl/src/app/pages/front-pages/front-pagesData.ts new file mode 100644 index 0000000..0e870f4 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/front-pagesData.ts @@ -0,0 +1,768 @@ +interface cardimgs { + id: number; + time: string; + imgSrc: string; + user: string; + title: string; + views: string; + category: string; + comments: number; + date: string; +} + +interface productcards { + id: number; + imgSrc: string; + title: string; + price: string; + rprice: string; + date: string; +} + +interface Framework { + src: string; + alt: string; + tooltip: string; +} + +interface followercards { + id: number; + imgSrc: string; + title: string; +} + +interface setupCards { + id: number; + img: string; + color: string; + title: string; + subtitle: string; + imgMain?:string; +} + +export const cardimgs: cardimgs[] = [ + { + id: 1, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img1.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 2, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img2.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 3, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img3.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + { + id: 4, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img4.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 5, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img5.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 6, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img6.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, + { + id: 7, + time: '2 mins Read', + imgSrc: '/assets/images/blog/blog-img10.jpg', + user: '/assets/images/profile/user-1.jpg', + title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones', + views: '9,125', + category: 'Social', + comments: 3, + date: 'Mon, Dec 23', + }, + { + id: 8, + time: '3 mins Read', + imgSrc: '/assets/images/blog/blog-img8.jpg', + user: '/assets/images/profile/user-2.jpg', + title: + 'Intel loses bid to revive antitrust case against patent foe Fortress', + views: '9,125', + category: 'Gadget', + comments: 3, + date: 'Sun, Dec 23', + }, + { + id: 9, + time: '4 mins Read', + imgSrc: '/assets/images/blog/blog-img9.jpg', + user: '/assets/images/profile/user-3.jpg', + title: 'COVID outbreak deepens as more lockdowns loom in China', + views: '9,125', + category: 'Health', + comments: 12, + date: 'Sat, Dec 23', + }, +]; + +export const productcards: productcards[] = [ + { + id: 1, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Headphone', + price: '285', + rprice: '375', + date: 'Tue, Apr 03, 2025', + }, + { + id: 2, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Air Pro', + price: '285', + rprice: '375', + date: 'Tue, Apr 10, 2025', + }, + { + id: 3, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Red Velvet Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 15, 2025', + }, + { + id: 4, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Soft Plush Teddy', + price: '285', + rprice: '375', + date: 'Tue, Apr 12, 2025', + }, + { + id: 5, + imgSrc: 'assets/images/products/s2.jpg', + title: 'Boat Bass Booster', + price: '285', + rprice: '375', + date: 'Tue, Apr 14, 2025', + }, + { + id: 6, + imgSrc: 'assets/images/products/s6.jpg', + title: 'MacBook Ultra Slim', + price: '285', + rprice: '375', + date: 'Tue, Apr 18, 2025', + }, + { + id: 7, + imgSrc: 'assets/images/products/s8.jpg', + title: 'Crimson Party Dress', + price: '285', + rprice: '375', + date: 'Tue, Apr 20, 2025', + }, + { + id: 8, + imgSrc: 'assets/images/products/s12.jpg', + title: 'Cuddly Teddy Gift', + price: '285', + rprice: '375', + date: 'Tue, Apr 22, 2025', + }, + { + id: 9, + imgSrc: 'assets/images/products/s4.jpg', + title: 'Boat Sonic Headset', + price: '285', + rprice: '375', + date: 'Tue, Apr 25, 2025', + }, + { + id: 10, + imgSrc: 'assets/images/products/s5.jpg', + title: 'MacBook Pro 2025', + price: '285', + rprice: '375', + date: 'Tue, Apr 27, 2025', + }, + { + id: 11, + imgSrc: 'assets/images/products/s7.jpg', + title: 'Evening Gown - Red', + price: '285', + rprice: '375', + date: 'Tue, Apr 29, 2025', + }, + { + id: 12, + imgSrc: 'assets/images/products/s11.jpg', + title: 'Fluffy Bear Surprise', + price: '285', + rprice: '375', + date: 'Tue, Apr 30, 2025', + }, +]; + +export const frameworks: Framework[] = [ + { + src: 'assets/images/landingpage/frameworks/angular.svg', + alt: 'Angular', + tooltip: 'Angular', + }, + { + src: 'assets/images/landingpage/frameworks/material.svg', + alt: 'Angular Material', + tooltip: 'Angular Material', + }, + { + src: 'assets/images/landingpage/frameworks/logo-ts.svg', + alt: 'Typescript', + tooltip: 'Typescript', + }, + { + src: 'assets/images/landingpage/frameworks/icon-tabler.svg', + alt: 'Tabler Icon', + tooltip: 'Tabler Icon', + }, +]; + +export const tiles = [ + { + id: 1, + text: 'Light & Dark Color Schemes', + cols: 1, + rows: 1, + color: '#FFF6E5', + icon: 'svgs/icon-briefcase.svg', + subtitle: 'Choose your preferred visual style effortlessly.', + }, + { + id: 2, + text: 'New Demos', + cols: 2, + rows: 2, + color: '#E9F1FF', + icon: 'logos/logoIcon.svg', + img: 'landingpage/background/screen1.png', + subtitle: + 'Brand new demos to help you build the perfect dashboard:
Dark and Right-to-Left.', + }, + { + id: 3, + text: 'Code Improvements', + cols: 1, + rows: 1, + color: '#E7FFF2', + icon: 'logos/icon-speech-bubble.svg', + subtitle: 'Benefit from continuous improvements and optimizations.', + }, + { + id: 4, + text: '12+ Ready to Use Application Designs', + cols: 1, + rows: 1, + color: '#E4F4FF', + icon: 'icon-layer.svg', + img: 'landingpage/background/feature-apps.png', + subtitle: 'Instantly deployable designs for your applications.', + }, + { + id: 5, + text: '50+ UI Components', + cols: 1, + rows: 1, + color: '#FFECEC', + icon: 'logos/icon-favorites.svg', + subtitle: 'A rich collection for seamless user experiences.', + }, +]; + +export const users = [ + { name: 'Jenny Wilson', img: '/assets/images/profile/user-1.jpg' }, + { name: 'Robert Fox', img: '/assets/images/profile/user-2.jpg' }, + { name: 'Kristin Watson', img: '/assets/images/profile/user-3.jpg' }, + { name: 'Darlene Robertson', img: '/assets/images/profile/user-4.jpg' }, + { name: 'Jacob Jones', img: '/assets/images/profile/user-5.jpg' }, +]; + +export const plans = [ + { + title: 'Single Use', + description: + 'Use for single end product which end users can’t be charged for.', + price: 49, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: false }, + { text: 'One Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Multiple Use', + description: + 'Use for unlimited end products end users can’t be charged for.', + price: 89, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: false }, + { text: 'Unlimited Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Extended Use', + description: + 'Use for single end product which end users can be charged for.', + price: 299, + period: 'one time pay', + popular: true, + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: true }, + { text: 'One Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, + { + title: 'Unlimited Use', + description: + 'Use in unlimited end products end users can be charged for.', + price: 499, + period: 'one time pay', + features: [ + { text: 'Full source code', included: true }, + { text: 'Documentation', included: true }, + { text: 'Use in SaaS app', included: true }, + { text: 'Unlimited Project', included: true, bold: true }, + { text: 'One Year Technical Support', included: true }, + { text: 'One Year Free Updates', included: true }, + ], + }, +]; + +export const paymentLogos = [ + { src: 'assets/images/front-pages/icon-visa.svg', alt: 'visa', tooltip: 'Visa' }, + { + src: 'assets/images/front-pages/icon-mastercard.svg', + alt: 'mastercard', + tooltip: 'Master Card', + }, + { + src: 'assets/images/front-pages/icon-american-express.svg', + alt: 'american express', + tooltip: 'American Express', + }, + { + src: 'assets/images/front-pages/icon-discover.svg', + alt: 'discover', + tooltip: 'Discover', + }, + { + src: 'assets/images/front-pages/icon-paypal.svg', + alt: 'paypal', + tooltip: 'Paypal', + }, + { + src: 'assets/images/front-pages/icon-masetro.svg', + alt: 'maestro', + tooltip: 'Maestro', + }, + { src: 'assets/images/front-pages/icon-jcb.svg', alt: 'jcb', tooltip: 'JCB' }, + { + src: 'assets/images/front-pages/icon-diners.svg', + alt: 'diners', + tooltip: 'Diners', + }, +]; + +export const faqList = [ + { + question: 'What is included with my purchase?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Are there any recurring fees?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Can i use template on multiple projects? ', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: + 'Can i use customize the admin dashboard template to match my brand?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'Are any restrictions on using the template?', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, + { + question: 'How can i get support after purchase? ', + answer: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.', + }, +]; + +export const followercardsFirst: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-color.svg', + title: '6 Themes Colors', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-sidebar.svg', + title: 'Dard & Light Sidebar', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-components.svg', + title: '50+ UI Components', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-pages.svg', + title: '65+ pages Templates', + }, +]; + +export const followercardSecond: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Material UI', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: '3400+ icons', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Fully responsive', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Sassbase css', + }, +]; +export const followercardThird: followercards[] = [ + { + id: 1, + imgSrc: '/assets/images/front-pages/icon-customize.svg', + title: 'Easy to Customize', + }, + { + id: 2, + imgSrc: '/assets/images/front-pages/icon-chart.svg', + title: 'Lots of Chart Options', + }, + { + id: 3, + imgSrc: '/assets/images/front-pages/icon-table.svg', + title: 'Lots of Table Examples', + }, + { + id: 4, + imgSrc: '/assets/images/front-pages/icon-update.svg', + title: 'Regular Updates', + }, + { + id: 5, + imgSrc: '/assets/images/front-pages/icon-support.svg', + title: 'Dedicated Support', + }, + { + id: 6, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Easy to Customize', + }, + { + id: 7, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: 'Lots of Chart Options', + }, + { + id: 8, + imgSrc: '/assets/images/front-pages/icon-responsive.svg', + title: 'Lots of Table Examples', + }, + { + id: 9, + imgSrc: '/assets/images/front-pages/icon-sass.svg', + title: 'Regular Updates', + }, + { + id: 10, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Dedicated Support', + }, + { + id: 11, + imgSrc: '/assets/images/front-pages/icon-framework.svg', + title: 'Easy to Customize', + }, + { + id: 12, + imgSrc: '/assets/images/front-pages/icon-icons.svg', + title: 'Lots of Chart Options', + }, + +]; + +export const topcardsGrid = [ + { title: 'Light & Dark Color Schemes', subtitle: 'Choose your preferred visual style effortlessly.', + img: '/assets/images/svgs/icon-briefcase.svg', color: 'warning' }, + { title: '12+ Ready to Use Application Designs', subtitle: 'Instantly deployable designs for your applications.', + img: 'assets/icons/icon2.png', color: 'secondary',imgMain: '/assets/images/landingpage/background/feature-apps.png', }, + { title: 'New Demos', subtitle: 'Brand new demos to help you build the perfect dashboard: Dark and Right-to-Left.', + img: '/assets/images/front-pages/logoIcon.svg', color: 'primary',imgMain: '/assets/images/landingpage/background/screen1.png' }, + { title: 'Code Improvements', subtitle: 'Benefit from continuous improvements and optimizations.', + img: '/assets/images/front-pages/icon-speech-bubble.svg', color: 'success' }, + { title: '50+ UI Components', subtitle: 'A rich collection for seamless user experiences.', + img: '/assets/images/front-pages/icon-favorites.svg', color: 'error' }, +]; + +export const setupCards:setupCards[] = [ + { + id: 1, + color: 'warning', + img: '/assets/images/svgs/icon-briefcase.svg', + title: 'Light & Dark Color Schemes', + subtitle: 'Choose your preferred visual style effortlessly.', + }, + { + id: 2, + color: 'secondary', + img: '/assets/images/svgs/icon-connect.svg', + title: '12+ Ready to Use Application Designs', + subtitle: 'Instantly deployable designs for your applications.', + imgMain: '/assets/images/landingpage/background/feature-apps.png' + }, + + { + id: 3, + color: 'success', + img: '/assets/images/svgs/icon-speech-bubble.svg', + title: 'Code Improvements', + subtitle: 'Benefit from continuous improvements and optimizations.', + }, + { + id: 4, + color: 'error', + img: '/assets/images/svgs/icon-favorites.svg', + title: '50+ UI Components', + subtitle: 'A rich collection for seamless user experiences.', + }, + +]; + +export const stats = [ + { + label: 'Founded', + value: '2019', + description: 'When we founded Modernize', + }, + { + label: 'Growth', + value: '1,400%', + description: 'Revenue growth in 2024', + }, + { + label: 'Customers', + value: '300k+', + description: 'Customers on Modernize', + }, + { + label: 'Dashboards', + value: '25k+', + description: 'Dashboards built using Modernize', + }, +]; + +export const team = [ + {id: 1, + name: 'Alex Martinez', + position: 'CEO & Co-Founder', + image: 'assets/images/front-pages/user1.jpg' + }, + { + id: 2, + name: 'Jordan Nguyen', + position: 'CTO & Co-Founder', + image: 'assets/images/front-pages/user2.jpg' + }, + { + id: 3, + name: 'Taylor Roberts', + position: 'Product Manager', + image: 'assets/images/front-pages/user3.jpg' + }, + {id: 4, + name: 'Morgan Patel', + position: 'Lead Developer', + image: 'assets/images/front-pages/user4.jpg' + }, + { + id: 5, + name: 'Andrew Grant', + position: 'Product Manager', + image: 'assets/images/front-pages/user5.jpg' + }, + { + id: 6, + name: 'Leo Pratt', + position: 'Lead Developer', + image: 'assets/images/front-pages/user3.jpg' + }, + { + id: 7, + name: 'C. A. Nunez', + position: 'CEO & Co-Founder', + image: 'assets/images/front-pages/user2.jpg' + }, + { + id: 8, + name: 'Leo Maxwell', + position: 'Lead Developer', + image: 'assets/images/front-pages/user1.jpg' + } +]; \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.html b/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.html new file mode 100644 index 0000000..b50b52c --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.html @@ -0,0 +1,603 @@ +
+
+
+
+
+

+ Most powerful & + developer friendly + dashboard +

+
+
+
+ @if(!isMobileView){ + +
+ banner-top-left +
+ } + +
+
+
+ +
+ 52,589+ developers & agencies using our templates +
+
+
+
+ Login +
+ + See how it works +
+
+
+ @for (framework of frameworks; track framework.tooltip) { + + + + } +
+
+ @if(!isMobileView){ +
+ banner-top-right +
+ + } +
+ @if (!isMobileView) { +
+
+ bottom-part +
+
+ } +
+
+ +
+
+
+
+

+ Introducing Modernize's Light & Dark Skins, Exceptional Dashboards, + and Dynamic Pages - Stay Updated on What's New! +

+
+
+ + + + + @if (!isMobileView) { +
+ +
+
+ @for (topcard of topcards; track topcard.title) { + @if (topcard.title === 'Light & Dark Color Schemes' || topcard.title.includes('12+')) { + + + @if (topcard.title === 'Light & Dark Color Schemes') { + icon + } +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+ @if (topcard.title.includes('12+')) { + image + } +
+
+ } + } +
+
+
+
+ @for (topcard of topcards; track topcard.title) + { + @if + (topcard.title.includes('New Demos')) { + + + icon +

{{ topcard.title }}

+

+ demo +
+
+ } } +
+
+ + +
+
+ @for (topcard of topcards; track topcard.title) { + @if (topcard.title.includes('Code Improvements') || topcard.title.includes('UI Components')) { + + + icon +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+
+
+ } + } +
+
+ +
+ } + + + @else { +
+ @for (topcard of topcards; track topcard.title) { + @if (!topcard.title.includes('New Demos')) { + + + @if (!topcard.title.includes('12+')) { + icon + } +
{{ topcard.title }}
+

{{ topcard.subtitle }}

+ + @if (topcard.title.includes('12+')) { + image + } +
+
+ } + } +
+ + +
+ @for (topcard of topcards; track topcard.title) + { + @if + (topcard.title.includes('New Demos')) { + + + icon +
{{ topcard.title }}
+

+ demo +
+
+ } } +
+ } + + +
+
+ +
+ +
+ + + + + Team Scheduling + + + + + + Payments + + + + + + Embedding + + + + + + Workflows + + + + + + +
+
+
+ slider-group +
+
+ +
+
+

Defend your focus

+
+ + + + +
+ Factor in outside colleagues + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+ + + + +
+ Combine teammate schedules + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+ + + + +
+ Round robin pooling + +
+
+
+

+ Factor in availability for required attendees, and skip + checking for conflicts for optional attendees. +

+
+
+
+
+ + Learn More +
+ + +
+
+
+
+ +
+ +
+ +
+
+
+ + + Save valuable time and effort spent searching for a solution. + Contact us now + +
+
+
+ +
+
+
+
+

+ Discover Powerful Dozens of
Purpose-Fit Templates +

+
+
+
+
+ + slide + +
+
+
+
+ + slide + +
+
+
+
+ + slide + +
+
+
+
+ slide +
+
+
+
+ + slide + +
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+ slide +
+
+
+
+
+
+

High Customizability

+

+ Tailor the dashboard to your exact needs. Customize layouts, color + schemes, and widgets effortlessly for a personalized user + experience. +

+
+
+

Powerful Data Analytics

+

+ Unlock the true potential of your data with our advanced analytics + tools. Gain valuable insights and make data-driven decisions with + ease. +

+
+ +
+

Interactive Charts

+

+ Visualize complex data sets beautifully with our interactive + graphs and charts. Quickly grasp trends and patterns for smarter + analysis. +

+
+
+
+
+
+
+ +
+
+
+ +
+
+

+ What our clients
think logo + about us? +

+

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+
+
+
+ + + Features availability + +
+
+ +
+
{{ currentUser().name }}
+
+ +

+ Our users' feedback is a testament to our commitment to quality + and user satisfaction. Read what they have to say about their + journey with us. +

+ + + +
+ + + {{ displayCount() }} + + +
+
+
+
+
+
+
+ +
+
+
+
+
+

+ Enjoy unparalleled features & exceptional flexibility. +

+
+
+ +
+
+
+ @for (followercard of followercardsfirst; track followercard.title) + { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+ @for (followercard of followercardsecond; track followercard.title) + { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+ @for (followercard of followercardthird; track followercard.title) { +
+ + +
+ icon +
+ {{ followercard.title }} +
+
+
+
+
+ } +
+
+
+
+
+
+ +
+
+

Frequently Asked Questions

+
+
+ + @for (item of faqList; track item) { + + + {{ + item.question + }} + + + + + +

{{ item.answer }}

+
+ } +
+
+
+
+
+ Still have a question? + Ask on discord + or + Submit a ticket +
+
+
+
+ + + +
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.scss b/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.scss new file mode 100644 index 0000000..e6e0f4b --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.scss @@ -0,0 +1,189 @@ +.home-page { + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } + + .home-page-header { + + .header-container-content { + + .cardPosition { + .float-image { + animation: floatUpDown 6s ease-in-out infinite; + } + } + + .cardPositionTwo { + + .float-image { + animation: floatUpDown 6s ease-in-out infinite; + } + } + + .loginBtn { + .play-button { + background-color: transparent; + border: 2px solid var(--mat-sys-primary); // or use your theme color + color: var(--mat-sys-primary); + box-shadow: none; + } + + .textSee { + cursor: pointer; + + &:hover { + color: var(--mat-sys-primary); + } + } + } + } + } + + .dashboardCards { + + .card-container { + + mat-card-content { + padding: 0px !important; + } + } + } + + .tab-header { + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + + .profileTabs { + background-color: var(--mdc-elevated-card-container-color) !important; + + .mat-mdc-tab.mdc-tab-indicator--active { + .mdc-tab__text-label { + color: var(--mat-sys-primary); + } + } + } + + } + + .template-slider { + .template-slider-content { + .demo-slider { + .demo-slide { + animation: slide3d 15s linear infinite; + } + } + } + } + + .features { + + .cardWithShadow { + mat-card-content { + padding: 0px !important; + } + } + } + + .exceptional { + .exceptional-content { + .demo-slider { + .demo-slide { + animation: slide3d 20s linear infinite; + } + + .demo-slide-two { + animation: slide3dTwo 20s linear infinite; + } + } + } + } + + .expansion-panel { + box-shadow: none; + background: transparent; + border-radius: 0 !important; + border-bottom: 1px solid var(--mat-sys-outline); + + .mat-expansion-panel-header { + padding: 18px 0 !important; + height: auto; + } + } + + .sliderImg { + max-width: 380px; + height: 300px; + } + + .img-border { + border: 2px solid var(--mat-sys-secondary); + /* Blue border, change color as needed */ + cursor: pointer; + } + + .img-border:hover { + border-color: var(--mat-sys-secondary); + } + + .border-dash { + border: 1px dashed var(--mat-sys-outline); // Initial border color (Bootstrap primary) + transition: border-color 0.3s ease; + flex-wrap: wrap; + + &:hover { + border-color: var(--mat-sys-primary); // Use your Angular Material primary variable or a custom color + } + } + + .faq-accordion { + .mat-expansion-panel { + border-radius: 8px !important; + + .mat-expansion-panel-header { + padding: 20px 21px !important; + } + } + } +} + +@keyframes floatUpDown { + + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(-6px); // smaller bounce + } +} + +@keyframes slide3d { + from { + transform: translate3d(0, 0, 0); + } + + to { + transform: translate3d(-2028px, 0, 0); // adjust based on actual slide width + } +} + +@keyframes slide3dTwo { + from { + transform: translate3d(-2028px, 0, 0); // Rightward (starts left) + } + + to { + transform: translate3d(0, 0, 0); + } +} + + + +@media (max-width: 1199px) { + .home-page-header { + padding-bottom: 48px; + } +} \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts new file mode 100644 index 0000000..52b6227 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HomepageDetailsComponent } from './homepage-details.component'; + +describe('HomepageDetailsComponent', () => { + let component: HomepageDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HomepageDetailsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HomepageDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.ts b/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.ts new file mode 100644 index 0000000..46f68e1 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/homepage-details/homepage-details.component.ts @@ -0,0 +1,131 @@ +import { Component, computed, DestroyRef, inject, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { + faqList, + followercardsFirst, + followercardSecond, + followercardThird, + frameworks, + tiles, + users, + topcardsGrid, +} from '../front-pagesData'; +import { CommonModule } from '@angular/common'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { ImageSliderComponent } from '../image-slider/image-slider.component'; +import { FooterComponent } from '../footer/footer.component'; +import { MatDialog } from '@angular/material/dialog'; +import { TemplateVideoComponent } from '../template-video/template-video.component'; +import { Router, RouterModule } from '@angular/router'; + + +@Component({ + selector: 'app-homepage-details', + imports: [ + MaterialModule, + IconModule, + CommonModule, + ImageSliderComponent, + FooterComponent, + RouterModule + ], + templateUrl: './homepage-details.component.html', + styleUrl: './homepage-details.component.scss', +}) +export class HomepageDetailsComponent { + + topcards=topcardsGrid; + + + centered = false; + disabled = false; + unbounded = false; + radius: number; + color: string; + showBackground: boolean = false; + frameworks = frameworks; + selectedIndex = 1; + + readonly dialog = inject(MatDialog); + private router = inject(Router); + private destroyRef = inject(DestroyRef); // ✅ For automatic cleanup + private mediaMatcher = inject(MediaMatcher); // ✅ Proper MediaMatcher injection + + mobileQuery: MediaQueryList; + isMobileView = false; + + readonly panelOpenState = signal(false); + tiles = tiles; + hideCloserBtn: boolean = true; + users = users; + expandedIndex: number | null = null; + currentIndex = signal(0); // Starting from 0 + faqList = faqList; + selectedPath: string | null = null; + clicked = false; + + followercardsfirst = followercardsFirst; + followercardsecond = followercardSecond; + followercardthird = followercardThird; + + currentUser = computed(() => this.users[this.currentIndex()]); + displayCount = computed(() => `${this.currentIndex() + 1}/${this.users.length}`); + + constructor() { + const isSmallScreen = this.mediaMatcher.matchMedia('(max-width: 599px)'); + // ✅ Setup media query for max-width: 1199px + this.mobileQuery = this.mediaMatcher.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + const listener = (e: MediaQueryListEvent) => { + this.isMobileView = e.matches; + }; + + // ✅ Listen to viewport changes + this.mobileQuery.addEventListener('change', listener); + + // ✅ Clean up listener on component destroy + this.destroyRef.onDestroy(() => { + this.mobileQuery.removeEventListener('change', listener); + }); + } + isOver(): boolean { + return this.mediaMatcher.matchMedia('(max-width: 1199px)').matches; + } + + goPrev() { + if (this.currentIndex() > 0) { + this.currentIndex.update((i) => i - 1); + } + } + + goNext() { + if (this.currentIndex() < this.users.length - 1) { + this.currentIndex.update((i) => i + 1); + } + } + openDialog(showBackground:boolean){ + this.showBackground = showBackground; + + const dialogRef = this.dialog.open(TemplateVideoComponent, { + data: {}, + width: '1000px', + }); + + dialogRef.afterClosed().subscribe((result) => { + if (result === false) { + this.showBackground = false; // Reset or take any action + } + }); + } + + + onImageClick(path: string) { + this.selectedPath = path; + + setTimeout(() => { + this.router.navigate([path]); + }, 100); // brief delay to show border + } +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/homepage/homepage.component.html b/theme/packages/rtl/src/app/pages/front-pages/homepage/homepage.component.html new file mode 100644 index 0000000..532acf0 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/homepage/homepage.component.html @@ -0,0 +1,137 @@ +
+ + + @if(hideCloserBtn){ + + + + +
+ New + Frontend Pages Included! +
+ + + + +
+ + } + +
+
+
+ +
+ + @if(!isMobileView){ +
+ + + + + + + + +
+ Login + } @if(isMobileView){ + + } +
+
+
+ +
+ +
+
+ + + +
+
+ +
+
+ + + + + + + + + + + + + + + + + Get + Started + +
+
+
+
+ @if(showBackToTop){ +
+ +
+ } +
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/homepage/homepage.component.scss b/theme/packages/rtl/src/app/pages/front-pages/homepage/homepage.component.scss new file mode 100644 index 0000000..3cee318 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/homepage/homepage.component.scss @@ -0,0 +1,32 @@ +.landing-page { + .custom-container { + max-width: 1400px; + margin: 0 auto; + width: 100%; + padding: 0 15px; + } + + .heightToolbar { + height: 46px; + background-size: cover; + background-repeat: no-repeat; + background-image: url(../../../../assets/images/front-pages/topbar-bg.png); + } + + .toolBarContent { + .nav-item { + &.selected { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); // optional for visibility + transition: background-color 0.3s ease; + } + + &:hover { + color: var(--mat-sys-primary); + transition: color 0.3s ease; + } + } + + } + +} \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/homepage/homepage.component.ts b/theme/packages/rtl/src/app/pages/front-pages/homepage/homepage.component.ts new file mode 100644 index 0000000..ca1a34a --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/homepage/homepage.component.ts @@ -0,0 +1,65 @@ +import { MediaMatcher } from '@angular/cdk/layout'; +import { CommonModule } from '@angular/common'; +import { Component, HostListener, inject, ViewChild } from '@angular/core'; +import { MatSidenav } from '@angular/material/sidenav'; +import { ActivatedRoute, Router, RouterLink, RouterOutlet } from '@angular/router'; +import { IconModule } from 'src/app/icon/icon.module'; +import { BrandingComponent } from 'src/app/layouts/full/vertical/sidebar/branding.component'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-homepage', + imports: [MaterialModule, BrandingComponent, RouterLink, + IconModule, RouterOutlet, CommonModule], + templateUrl: './homepage.component.html', + styleUrl: './homepage.component.scss' +}) +export class HomepageComponent { + @ViewChild('customizerRight') customizerRight!: MatSidenav; + selected: string = ''; // default selected + mobileQuery: MediaQueryList; + isMobileView = false; + hideCloserBtn: boolean = true; + private router = inject(Router) + private mediaMatcher: MediaQueryList = matchMedia(`(max-width: 1199px)`); + showBackToTop: boolean; + isTopbarFixed: boolean; + constructor(private route: ActivatedRoute) { + const media = inject(MediaMatcher); + this.mobileQuery = media.matchMedia('(max-width: 1199px)'); + this.isMobileView = this.mobileQuery.matches; + + this.mobileQuery.addEventListener('change', (e) => { + + this.isMobileView = e.matches; + this.closeSidenavIfNeeded(); + }); + } + closeSidenavIfNeeded() { + if (!this.isMobileView && this.customizerRight?.opened) { + this.customizerRight.close(); + } + } + isOver(): boolean { + return this.mediaMatcher.matches; + } + + isActiveRoute(route: string): boolean { + return this.router.url.includes(`/front-pages/${route}`); + } + hideCloser() { + this.hideCloserBtn = false; + } + getNavigate() { + this.router.navigate(['/dashboards/dashboard1']) + } + + scrollToTop(): void { + window.scrollTo({ top: 0, behavior: 'smooth' }); + } + @HostListener('window:scroll', []) + onWindowScroll() { + this.showBackToTop = window.scrollY > 300; + this.isTopbarFixed = scrollY > 45; + } +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.html b/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.html new file mode 100644 index 0000000..f4c4b31 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.html @@ -0,0 +1,44 @@ +
+
+
+
+
+

Our leadership

+
+

+ Our robust analytics offer rich insights into the information + buyers want, informing where teams +

+
+
+ +
+
+ + +
+
+
+ +
+ @for (member of visibleTeamMembers(); track member.id){ +
+ + + imgSrc + + +

{{ member.name }}

+

{{ member.position }}

+
+
+
+ } +
+
+
+
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.scss b/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.scss new file mode 100644 index 0000000..0832285 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.scss @@ -0,0 +1,22 @@ +.img-slider-content { + .img-slider { + + .mat-mdc-card { + margin-bottom: 0px !important; + } + + .productcard { + position: relative; + + .info-card { + bottom: 42px; // controls overlap depth + left: 50%; + transform: translateX(-50%); + width: 90%; + box-shadow: 0px 6px 12px rgba(127, 145, 156, 0.12); + z-index: 2; + } + } + + } +} \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts new file mode 100644 index 0000000..c933f20 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ImageSliderComponent } from './image-slider.component'; + +describe('ImageSliderComponent', () => { + let component: ImageSliderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ImageSliderComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ImageSliderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.ts b/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.ts new file mode 100644 index 0000000..d5db5ee --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/image-slider/image-slider.component.ts @@ -0,0 +1,39 @@ +import { Component, computed, signal } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { team } from '../front-pagesData'; + +@Component({ + selector: 'app-image-slider', + imports: [MaterialModule,IconModule], + templateUrl: './image-slider.component.html', + styleUrl: './image-slider.component.scss' +}) +export class ImageSliderComponent { + team = team; + // Signals + currentPage = signal(0); + pageSize = 4; + + visibleTeamMembers = computed(() => { + const start = this.currentPage() * this.pageSize; + const end = start + this.pageSize; + return this.team.slice(start, end); + }); + + next() { + console.log('next--->',this.visibleTeamMembers().map(m => m.id)); + const totalPages = Math.ceil(this.team.length / this.pageSize); + if (this.currentPage() < totalPages - 1) { + this.currentPage.update((p) => p + 1); + } + } + + prev() { + console.log(this.visibleTeamMembers().map(m => m.id)); + if (this.currentPage() > 0) { + this.currentPage.update((p) => p - 1); + } + } + +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.html b/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.html new file mode 100644 index 0000000..32bdd60 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.html @@ -0,0 +1,68 @@ +
+
+

+ 111,476+ Trusted developers & many tech giants as well +

+
+
+
+ @for(plan of plans;track plan){ +
+ + + +
+
+ {{ plan.title }} + @if (plan.popular) { + + Popular + + } +
+
+

{{ plan.description }}

+ + +
+ ${{ plan.price }} + /{{ plan.period }} +
+
+ @for(feature of plan.features; track feature) { +
+ icon-facebook-dark + + + {{ feature.text }} + +
+ } +
+ + +
+
+ +
+ } + + +
+
+

Secured payment with PayPal & Razorpay

+
+ @for( logo of paymentLogos;track logo){ + + } +
+
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.scss b/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts new file mode 100644 index 0000000..fb0a9c8 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PagePricingComponent } from './page-pricing.component'; + +describe('PagePricingComponent', () => { + let component: PagePricingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PagePricingComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PagePricingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.ts b/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.ts new file mode 100644 index 0000000..7a435ae --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/page-pricing/page-pricing.component.ts @@ -0,0 +1,17 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { paymentLogos, plans } from '../front-pagesData'; + +@Component({ + selector: 'app-page-pricing', + imports: [MaterialModule, IconModule, CommonModule], + templateUrl: './page-pricing.component.html', + styleUrl: './page-pricing.component.scss', +}) +export class PagePricingComponent { + plans = plans; + + paymentLogos = paymentLogos; +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.html b/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.html new file mode 100644 index 0000000..f64670b --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.html @@ -0,0 +1,57 @@ + + +
+
+
+
+
Portfolio
+
+
{{ filteredCount }}
+
+
+ + + + search + + +
+
+ @for(productcard of filteredCardImgs; track productcard.id) { +
+ + + imgSrc + + + +
+ +
+
{{ productcard.title }}
+

{{ productcard.date }}

+
+ + + +
+
+
+
+
+ } +
+
+
+ \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.scss b/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts new file mode 100644 index 0000000..073ce35 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PortfolioComponent } from './portfolio.component'; + +describe('PortfolioComponent', () => { + let component: PortfolioComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PortfolioComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PortfolioComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.ts b/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.ts new file mode 100644 index 0000000..702ebee --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/portfolio/portfolio.component.ts @@ -0,0 +1,37 @@ + + +import { Component, OnInit } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { productcards } from '../front-pagesData'; +import { FooterComponent } from '../footer/footer.component'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-portfolio', + imports: [MaterialModule, IconModule, FooterComponent, CommonModule, FormsModule], + templateUrl: './portfolio.component.html', + styleUrl: './portfolio.component.scss' +}) +export class PortfolioComponent implements OnInit { + + filteredCards = productcards; + + searchText: string = ''; + + filteredCardImgs = [...this.filteredCards]; // Initialize with full data + filteredCount: number = this.filteredCardImgs.length; + ngOnInit(): void { + console.log('filteredCards', this.filteredCards) + } + onSearchChange() { + const query = this.searchText.toLowerCase().trim(); + this.filteredCardImgs = this.filteredCards.filter(item => + item.title.toLowerCase().includes(query) || + item.date.toLowerCase().includes(query) + ); + this.filteredCount = this.filteredCardImgs.length; // ✅ update the count here + } +} + diff --git a/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.html b/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.html new file mode 100644 index 0000000..6c42e4a --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.html @@ -0,0 +1,18 @@ + + +
+
+ +
+
+ + \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.scss b/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.spec.ts new file mode 100644 index 0000000..147f94e --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PricingComponent } from './pricing.component'; + +describe('PricingComponent', () => { + let component: PricingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PricingComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PricingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.ts b/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.ts new file mode 100644 index 0000000..0684d59 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/pricing/pricing.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { FooterComponent } from '../footer/footer.component'; +import { PagePricingComponent } from '../page-pricing/page-pricing.component'; + +@Component({ + selector: 'app-pricing', + imports: [MaterialModule,IconModule,FooterComponent,PagePricingComponent], + templateUrl: './pricing.component.html', + styleUrl: './pricing.component.scss' +}) +export class PricingComponent { + +} diff --git a/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.html b/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.html new file mode 100644 index 0000000..9b7d777 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.html @@ -0,0 +1,11 @@ + + + +
+ + +
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.scss b/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.spec.ts b/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.spec.ts new file mode 100644 index 0000000..46d7589 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TemplateVideoComponent } from './template-video.component'; + +describe('TemplateVideoComponent', () => { + let component: TemplateVideoComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TemplateVideoComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TemplateVideoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.ts b/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.ts new file mode 100644 index 0000000..b239adb --- /dev/null +++ b/theme/packages/rtl/src/app/pages/front-pages/template-video/template-video.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; +import { IconModule } from 'src/app/icon/icon.module'; +import { MaterialModule } from 'src/app/material.module'; +import { MatDialogRef } from '@angular/material/dialog'; +@Component({ + selector: 'app-template-video', + imports: [MaterialModule, + IconModule,], + templateUrl: './template-video.component.html', + styleUrl: './template-video.component.scss' +}) +export class TemplateVideoComponent { +constructor(private dialogRef: MatDialogRef){ + +} +closeDialog(): void { + this.dialogRef.close(false); // Pass false back to parent +} +} diff --git a/theme/packages/rtl/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts b/theme/packages/rtl/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts new file mode 100644 index 0000000..de7ba0c --- /dev/null +++ b/theme/packages/rtl/src/app/pages/ui-components/slide-toggle/code/slide-toggle-ts-snippet.ts @@ -0,0 +1,69 @@ +export const BASIC_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + + /** + * @title slide-toggle + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatSlideToggleModule], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + } +`; + +export const FORM_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component, inject} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {FormBuilder, FormGroup, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; + import {MatButtonModule} from '@angular/material/button'; + import { MatSlideToggleModule} from '@angular/material/slide-toggle'; + + /** + * @title Slide-toggle with forms + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatSlideToggleModule, FormsModule, MatButtonModule, ReactiveFormsModule,], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + + private _formBuilder = inject(FormBuilder); + + isChecked = true; + formGroup = this._formBuilder.group({ + enableWifi: '', + acceptTerms: ['', Validators.requiredTrue], + }); + + alertFormValues(formGroup: FormGroup) { + alert(JSON.stringify(formGroup.value, null, 2)); + } + } +`; + +export const CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET = ` import {Component} from '@angular/core'; + import {MatSlideToggleModule} from '@angular/material/slide-toggle'; + import {MatCheckboxModule} from '@angular/material/checkbox'; + import {FormsModule} from '@angular/forms'; + import {MatRadioModule} from '@angular/material/radio'; + import {MatCardModule} from '@angular/material/card'; + + /** + * @title Configurable slide-toggle + */ + @Component({ + selector: 'app-slide-toggle', + imports: [MatCardModule, MatRadioModule, FormsModule, MatCheckboxModule, MatSlideToggleModule], + templateUrl: './slide-toggle.component.html' + }) + export class AppSlideToggleComponent { + constructor() {} + + checked = false; + disabled = false; + } +`; \ No newline at end of file diff --git a/theme/packages/rtl/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts b/theme/packages/rtl/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts new file mode 100644 index 0000000..804e79f --- /dev/null +++ b/theme/packages/rtl/src/app/pages/ui-components/slide-toggle/slide-toggle.component.ts @@ -0,0 +1,63 @@ +import { Component, OnInit, inject } from '@angular/core'; +import {FormBuilder, FormGroup, Validators, ReactiveFormsModule} from '@angular/forms'; +import { + MatSlideToggleModule, + // _MatSlideToggleRequiredValidatorModule, +} from '@angular/material/slide-toggle'; +import {MatCheckboxModule} from '@angular/material/checkbox'; +import {FormsModule} from '@angular/forms'; +import {MatRadioModule} from '@angular/material/radio'; +import {MatCardModule} from '@angular/material/card'; +import {MatButtonModule} from '@angular/material/button'; +import { AppCodeViewComponent } from 'src/app/components/code-view/code-view.component'; + +// snippets +import { BASIC_SLIDE_TOGGLE_HTML_SNIPPET, CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET, FORM_SLIDE_TOGGLE_HTML_SNIPPET } from './code/slide-toggle-html-snippet'; +import { BASIC_SLIDE_TOGGLE_TS_SNIPPET, CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET, FORM_SLIDE_TOGGLE_TS_SNIPPET } from './code/slide-toggle-ts-snippet'; + +import { Highlight, HighlightAuto } from 'ngx-highlightjs'; +import { HighlightLineNumbers } from 'ngx-highlightjs/line-numbers'; + +@Component({ + selector: 'app-slide-toggle', + imports: [MatCardModule, MatRadioModule, FormsModule, MatCheckboxModule, MatSlideToggleModule, ReactiveFormsModule, MatButtonModule, + // _MatSlideToggleRequiredValidatorModule + Highlight, + HighlightAuto, + HighlightLineNumbers, + AppCodeViewComponent, + ], + templateUrl: './slide-toggle.component.html' +}) +export class AppSlideToggleComponent implements OnInit { + + // 1 [Basic with Slide Toggle] + codeForSlideToggleBasic = BASIC_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleBasicTs = BASIC_SLIDE_TOGGLE_TS_SNIPPET; + + // 2 [Form with Slide Toggle] + codeForSlideToggleForm = FORM_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleFormTs = FORM_SLIDE_TOGGLE_TS_SNIPPET; + + // 3 [Configuration with Slide Toggle] + codeForSlideToggleConfiguration = CONFIGURATION_SLIDE_TOGGLE_HTML_SNIPPET; + codeForSlideToggleConfigurationTs = CONFIGURATION_SLIDE_TOGGLE_TS_SNIPPET; + + // configuration + checked = false; + disabled = false; + + private _formBuilder = inject(FormBuilder); + + isChecked = true; + formGroup = this._formBuilder.group({ + enableWifi: '', + acceptTerms: ['', Validators.requiredTrue], + }); + + alertFormValues(formGroup: FormGroup) { + alert(JSON.stringify(formGroup.value, null, 2)); + } + + ngOnInit(): void {} +} diff --git a/theme/packages/rtl/src/app/pages/widgets/cards/cards.component.html b/theme/packages/rtl/src/app/pages/widgets/cards/cards.component.html new file mode 100644 index 0000000..051c1c9 --- /dev/null +++ b/theme/packages/rtl/src/app/pages/widgets/cards/cards.component.html @@ -0,0 +1,348 @@ + + + + +
+ @for(topcard of topcards; track topcard) { +
+ + + users +

+ {{ topcard.title }} +

+
+ {{ topcard.subtitle }} +
+
+
+
+ } +
+ + + + +
+ @for(cardimg of cardimgs; track cardimg.imgSrc) { +
+ + Photo of a Shiba Inu +
+ {{ + cardimg.time + }} +
+ + +
+
+ +
+ {{ + cardimg.category + }} +
+ {{ cardimg.title }} +
+
+ {{ cardimg.views }} + {{ cardimg.comments }} +
+ + + {{ cardimg.date }} + +
+
+
+
+ } +
+ + + + +
+ @for(productcard of productcards; track productcard.title) { +
+ + + imgSrc + + + + {{ + productcard.title + }} +
+
+
${{ productcard.price }}
+ ${{ productcard.rprice }} +
+
+ + + + + +
+
+
+
+
+ } +
+ + + + +
+ @for(musiccard of musiccards; track musiccard.title) { +
+ +
+
+
{{ musiccard.title }}
+ {{ musiccard.subtext }} + +
+ + + +
+
+
+ blog +
+
+
+
+ } +
+ + + + +
+ @for(followercard of followercards; track followercard.title) { +
+ + +
+
+ user +
+
{{ followercard.title }}
+ {{ followercard.subtext }} +
+
+ +
+
+
+
+ } +
+ + + + +
+ @for(friendcard of friendcards; track friendcard.title) { +
+ + + user + {{ friendcard.title }} +
+
+ user + user + user +
+ 3 mutual friends +
+ + +
+
+
+ } +
+ + + + +
+ @for(socialcard of socialcards; track socialcard.username) { +
+ + + + {{ + socialcard.username + }} + {{ + socialcard.post + }} + +
+ + + + +
+
+
+ } +
+ + + + +
+ @for(giftcard of giftcards; track giftcard.username) { +
+ + +
+ {{ + giftcard.username + }} + +
+ + user + + +
+
+
+ } +
+ +
+ +
+ + + Payment Gateways + Platform For Income + + @for(stat of stats; track stat.title) { +
+
+ + icon + + +
+
{{ stat.title }}
+ {{ stat.subtitle }} +
+ +${{ stat.percent }} +
+
+ } + + +
+
+
+ + +
+ + + Upcoming Activity + In New year + + @for(activity of activities; track activity.title) { +
+
+ + + + +
+
{{ activity.title }}
+ {{ activity.subtitle }} +
+ {{ activity.time }} +
+
+ } +
+
+
+ + +
+ + + Recent Transactions + +
+ @for(stat of stats2; track stat.subtext) { +
+
{{ stat.time }}
+
+ + +
+
+ @if(stat.subtext) { + {{ stat.subtext }} + } + + @if(stat.title) { + {{ + stat.title + }} + } + + @if(stat.link) { + #ML-3467 + } +
+
+ } +
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/rtl/src/app/services/apps/front-pages/front-end.service.spec.ts b/theme/packages/rtl/src/app/services/apps/front-pages/front-end.service.spec.ts new file mode 100644 index 0000000..950ecc8 --- /dev/null +++ b/theme/packages/rtl/src/app/services/apps/front-pages/front-end.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { FrontEndService } from './front-end.service'; + +describe('FrontEndService', () => { + let service: FrontEndService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(FrontEndService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/theme/packages/rtl/src/app/services/apps/front-pages/front-end.service.ts b/theme/packages/rtl/src/app/services/apps/front-pages/front-end.service.ts new file mode 100644 index 0000000..a736e66 --- /dev/null +++ b/theme/packages/rtl/src/app/services/apps/front-pages/front-end.service.ts @@ -0,0 +1,21 @@ +import { Injectable, signal } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class FrontEndService { + + private blog = signal(null); + + constructor() { } + + + + setBlog(blogData: any) { + this.blog.set(blogData); + } + + getBlog() { + return this.blog; + } +} diff --git a/theme/packages/rtl/src/assets/images/front-pages/app-chat.jpg b/theme/packages/rtl/src/assets/images/front-pages/app-chat.jpg new file mode 100644 index 0000000..cffde47 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/app-chat.jpg differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/app-email.jpg b/theme/packages/rtl/src/assets/images/front-pages/app-email.jpg new file mode 100644 index 0000000..5da2d90 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/app-email.jpg differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/banner-top-left.svg b/theme/packages/rtl/src/assets/images/front-pages/banner-top-left.svg new file mode 100644 index 0000000..0b5d123 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/banner-top-left.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/banner-top-right.svg b/theme/packages/rtl/src/assets/images/front-pages/banner-top-right.svg new file mode 100644 index 0000000..ce2deff --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/banner-top-right.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/bottom-part.svg b/theme/packages/rtl/src/assets/images/front-pages/bottom-part.svg new file mode 100644 index 0000000..0a9f8f9 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/bottom-part.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/demo-dark.jpg b/theme/packages/rtl/src/assets/images/front-pages/demo-dark.jpg new file mode 100644 index 0000000..1181c96 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/demo-dark.jpg differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/demo-horizontal.jpg b/theme/packages/rtl/src/assets/images/front-pages/demo-horizontal.jpg new file mode 100644 index 0000000..a384d56 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/demo-horizontal.jpg differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/demo-main.jpg b/theme/packages/rtl/src/assets/images/front-pages/demo-main.jpg new file mode 100644 index 0000000..895551e Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/demo-main.jpg differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/demo-rtl.jpg b/theme/packages/rtl/src/assets/images/front-pages/demo-rtl.jpg new file mode 100644 index 0000000..a8011a3 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/demo-rtl.jpg differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/design-collection.png b/theme/packages/rtl/src/assets/images/front-pages/design-collection.png new file mode 100644 index 0000000..08a4a50 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/design-collection.png differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-american-express.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-american-express.svg new file mode 100644 index 0000000..0cc1e3c --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-american-express.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-chart.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-chart.svg new file mode 100644 index 0000000..fa45961 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-chart.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-circle-check.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-circle-check.svg new file mode 100644 index 0000000..458ffdb --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-circle-check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-circle-x.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-circle-x.svg new file mode 100644 index 0000000..41b5593 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-circle-x.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-color.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-color.svg new file mode 100644 index 0000000..14d5f1a --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-color.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-components.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-components.svg new file mode 100644 index 0000000..a14b4e4 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-components.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-customize.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-customize.svg new file mode 100644 index 0000000..300ee35 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-customize.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-diners.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-diners.svg new file mode 100644 index 0000000..4ea5609 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-diners.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-discover.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-discover.svg new file mode 100644 index 0000000..12eebd5 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-discover.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-facebook.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-facebook.svg new file mode 100644 index 0000000..d0cfd8a --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-facebook.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-favorites.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-favorites.svg new file mode 100644 index 0000000..84fedaa --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-favorites.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-framework.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-framework.svg new file mode 100644 index 0000000..2718d0c --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-framework.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-icons.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-icons.svg new file mode 100644 index 0000000..87d1ae4 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-icons.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-instagram.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-instagram.svg new file mode 100644 index 0000000..6a73bf9 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-instagram.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-jcb.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-jcb.svg new file mode 100644 index 0000000..b71e935 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-jcb.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-masetro.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-masetro.svg new file mode 100644 index 0000000..5a84358 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-masetro.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-mastercard.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-mastercard.svg new file mode 100644 index 0000000..da591ae --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-mastercard.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-pages.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-pages.svg new file mode 100644 index 0000000..ac7ca4b --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-pages.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-paypal.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-paypal.svg new file mode 100644 index 0000000..7f8de85 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-paypal.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-responsive.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-responsive.svg new file mode 100644 index 0000000..fc57366 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-responsive.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-sass.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-sass.svg new file mode 100644 index 0000000..5751e1a --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-sass.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-sidebar.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-sidebar.svg new file mode 100644 index 0000000..1a0ca63 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-sidebar.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-speech-bubble.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-speech-bubble.svg new file mode 100644 index 0000000..2e1f2bd --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-speech-bubble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-support.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-support.svg new file mode 100644 index 0000000..6aa77a3 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-support.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-table.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-table.svg new file mode 100644 index 0000000..3fd98d7 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-table.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-twitter.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-twitter.svg new file mode 100644 index 0000000..e0b7780 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-twitter.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-update.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-update.svg new file mode 100644 index 0000000..94b5ed9 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-update.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/icon-visa.svg b/theme/packages/rtl/src/assets/images/front-pages/icon-visa.svg new file mode 100644 index 0000000..7a06b63 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/icon-visa.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/front-pages/logoIcon.svg b/theme/packages/rtl/src/assets/images/front-pages/logoIcon.svg new file mode 100644 index 0000000..90fdce0 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/front-pages/logoIcon.svg @@ -0,0 +1,11 @@ + + logoIcon + + + + + + \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/images/front-pages/topbar-bg.png b/theme/packages/rtl/src/assets/images/front-pages/topbar-bg.png new file mode 100644 index 0000000..e11b4a5 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/topbar-bg.png differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/user1.jpg b/theme/packages/rtl/src/assets/images/front-pages/user1.jpg new file mode 100644 index 0000000..eb505b5 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/user1.jpg differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/user2.jpg b/theme/packages/rtl/src/assets/images/front-pages/user2.jpg new file mode 100644 index 0000000..f8aa6af Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/user2.jpg differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/user3.jpg b/theme/packages/rtl/src/assets/images/front-pages/user3.jpg new file mode 100644 index 0000000..6478013 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/user3.jpg differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/user4.jpg b/theme/packages/rtl/src/assets/images/front-pages/user4.jpg new file mode 100644 index 0000000..e599b2a Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/user4.jpg differ diff --git a/theme/packages/rtl/src/assets/images/front-pages/user5.jpg b/theme/packages/rtl/src/assets/images/front-pages/user5.jpg new file mode 100644 index 0000000..494e402 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/front-pages/user5.jpg differ diff --git a/theme/packages/rtl/src/assets/images/landingpage/background/accordian1.jpg b/theme/packages/rtl/src/assets/images/landingpage/background/accordian1.jpg new file mode 100644 index 0000000..d13def2 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/landingpage/background/accordian1.jpg differ diff --git a/theme/packages/rtl/src/assets/images/landingpage/background/design-collection.png b/theme/packages/rtl/src/assets/images/landingpage/background/design-collection.png new file mode 100644 index 0000000..2886a14 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/landingpage/background/design-collection.png differ diff --git a/theme/packages/rtl/src/assets/images/landingpage/background/feature-apps.png b/theme/packages/rtl/src/assets/images/landingpage/background/feature-apps.png new file mode 100644 index 0000000..fef18c5 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/landingpage/background/feature-apps.png differ diff --git a/theme/packages/rtl/src/assets/images/landingpage/background/screen1.png b/theme/packages/rtl/src/assets/images/landingpage/background/screen1.png new file mode 100644 index 0000000..afd642a Binary files /dev/null and b/theme/packages/rtl/src/assets/images/landingpage/background/screen1.png differ diff --git a/theme/packages/rtl/src/assets/images/landingpage/frameworks/angular.svg b/theme/packages/rtl/src/assets/images/landingpage/frameworks/angular.svg new file mode 100644 index 0000000..bf081ac --- /dev/null +++ b/theme/packages/rtl/src/assets/images/landingpage/frameworks/angular.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/theme/packages/rtl/src/assets/images/landingpage/frameworks/icon-tabler.svg b/theme/packages/rtl/src/assets/images/landingpage/frameworks/icon-tabler.svg new file mode 100644 index 0000000..6e6810e --- /dev/null +++ b/theme/packages/rtl/src/assets/images/landingpage/frameworks/icon-tabler.svg @@ -0,0 +1,3 @@ + + + diff --git a/theme/packages/rtl/src/assets/images/landingpage/frameworks/material.svg b/theme/packages/rtl/src/assets/images/landingpage/frameworks/material.svg new file mode 100644 index 0000000..9ac2836 --- /dev/null +++ b/theme/packages/rtl/src/assets/images/landingpage/frameworks/material.svg @@ -0,0 +1 @@ +material \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/images/profile/user-11.jpg b/theme/packages/rtl/src/assets/images/profile/user-11.jpg new file mode 100644 index 0000000..8d54dc0 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/profile/user-11.jpg differ diff --git a/theme/packages/rtl/src/assets/images/profile/user-12.jpg b/theme/packages/rtl/src/assets/images/profile/user-12.jpg new file mode 100644 index 0000000..adbbde4 Binary files /dev/null and b/theme/packages/rtl/src/assets/images/profile/user-12.jpg differ diff --git a/theme/packages/rtl/src/assets/scss/_container.scss b/theme/packages/rtl/src/assets/scss/_container.scss new file mode 100644 index 0000000..730c06f --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/_container.scss @@ -0,0 +1,154 @@ +@use "variables" as *; + +*, +:after, +:before { + box-sizing: border-box; +} + +body { + font-family: $font-family; + line-height: 1.334rem; + overflow-x: hidden; + color: var(--mat-sys-on-background); +} + +.mainWrapper { + display: flex; + min-height: 100vh; + width: 100%; + flex: 1; + height: 100%; +} + +.container { + max-width: 1200px; + padding-left: 24px; + padding-right: 24px; + margin: 0 auto; + + &.full-width { + display: flex; + align-items: center; + width: 100%; + } +} + +.pageWrapper { + padding: 24px; + min-height: calc(100vh - 70px); + + margin: 0 auto; + + &.maxWidth { + max-width: $boxedWidth; + } +} + +.w-100 { + width: 100%; +} + +.h-100 { + height: 100%; +} + +.shadow-none { + box-shadow: none !important; +} + +.rounded { + border-radius: $border-radius !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 25px !important; +} + +.overflow-hidden { + overflow: hidden; +} + +.text-decoration-none { + text-decoration: none; +} + +.position-relative { + position: relative; +} + +.table-responsive { + overflow-x: auto; + + td, + mat-cell { + white-space: nowrap; + padding: 16px; + } +} + +.op-5 { + opacity: 0.5; +} + +.cursor-pointer { + cursor: pointer; +} + +.avatar-group { + img { + border: 2px solid $white; + margin-right: -5px; + + &:last-child { + margin-right: 0; + } + } +} + +a { + color: var(--mat-sys-on-background); + + &:hover { + color: $primary; + } +} + +.filter-sidebar { + width: 290px; + position: fixed; + right: -290px; + top: 0; + z-index: 10; + height: 100%; + transition: all 0.3s ease-in-out; + box-shadow: var(--mat-sys-level3); + background-color: var(--mat-sys-background); + + &.open { + right: 0; + } +} + +pre { + margin: 0; + white-space: nowrap; +} + +td.hljs-ln-line.hljs-ln-numbers { + padding-right: 10px; +} + +@media (min-width: 768px) { + html .flex-sm-row { + flex-direction: row !important; + } +} + +.mat-drawer[style*="visibility: hidden"] { + display: none; +} \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/scss/apps/_contact-list.scss b/theme/packages/rtl/src/assets/scss/apps/_contact-list.scss new file mode 100644 index 0000000..9cf1b85 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/apps/_contact-list.scss @@ -0,0 +1,59 @@ +@use "../variables" as *; + +@media (max-width: 1279px) { + .detail-part.movetodetail { + display: block; + position: absolute; + z-index: 9; + left: 0; + background: var(--mat-card-elevated-container-color); + } +} + +@media (max-width: 1279px) { + .welcome-app { + display: none; + } +} + +@media (max-width: 959px) { + .contact-detail-part { + display: none; + } + + .contact-detail-part.activeContact { + position: absolute !important; + top: 0; + left: 0; + display: block; + width: 100%; + height: 100%; + z-index: 999; + background-color: var(--mat-card-elevated-container-color); + } +} + +// contact app +.uploader { + .upload-image { + width: 100px; + height: auto; + cursor: pointer; + } + + input[type="file"] { + position: absolute; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + } +} + +.contact-listing { + .mdc-list-item__primary-text { + margin-bottom: -11px !important; + margin-top: 10px !important; + } +} diff --git a/theme/packages/rtl/src/assets/scss/apps/_ecommerce.scss b/theme/packages/rtl/src/assets/scss/apps/_ecommerce.scss new file mode 100644 index 0000000..467169d --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/apps/_ecommerce.scss @@ -0,0 +1,94 @@ +body { + + // Add Product + + .NgxEditor__Wrapper { + border: 1px solid var(--mat-sys-outline-variant); + } + + .NgxEditor__Seperator { + border-left: 1px solid var(--mat-sys-outline-variant); + } + + .NgxEditor__MenuBar { + background-color: var(--mat-card-elevated-container-color); + border-bottom: 1px solid var(--mat-sys-outline-variant) !important; + } + + .NgxEditor { + background: var(--mat-card-elevated-container-color); + color: var(--mat-sys-on-background); + } + + .NgxEditor__MenuItem .NgxEditor__MenuItem--Icon:hover { + background-color: var(--mat-sys-primary); + color: var(--mat-sys-background); + } + + .NgxEditor__Dropdown:hover { + background-color: var(--mat-sys-primary); + + .NgxEditor__Dropdown--Text { + color: var(--mat-sys-background); + } + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--Selected, + .NgxEditor__Dropdown .NgxEditor__Dropdown--Open { + color: var(--mat-sys-background); + background-color: var(--mat-sys-primary); + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--Item:hover { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); + } + + .NgxEditor__Dropdown .NgxEditor__Dropdown--DropdownMenu { + background-color: var(--mat-card-elevated-container-color); + } + + + .dropzone-box { + border: 1px dashed var(--mat-sys-primary); + background-color: var(--mat-sys-primary-fixed-dim); + + .dropzone-content { + .preview-image { + width: 100px; + height: 70px; + object-fit: cover; + border-radius: 6px; + margin-bottom: 0.5rem; + } + } + + .headline { + margin: 0; + } + } + + .cards-circle { + width: 15px; + height: 15px; + border-radius: var(--mat-sys-corner-full); + display: flex; + align-items: center; + justify-content: center; + background-color: var(--mat-sys-primary); + + .theme-icon { + display: none; + } + + &.selected { + .theme-icon { + display: block; + color: white; + width: 18px; + height: 25px; + } + } + } + +} \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/scss/helpers/_custom-flex.scss b/theme/packages/rtl/src/assets/scss/helpers/_custom-flex.scss new file mode 100644 index 0000000..fb36a29 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/helpers/_custom-flex.scss @@ -0,0 +1,59 @@ +@media (min-width: 1200px) { + body { + .d-lg-flex { + display: flex !important; + } + + .d-lg-none { + display: none !important; + } + + .d-lg-block { + display: block !important; + } + + .align-items-lg-center { + align-items: center !important; + } + } +} + +@media (min-width: 960px) { + .d-md-none { + display: none !important; + } +} + +@media (min-width: 768px) { + body { + .d-sm-flex { + display: flex !important; + } + } +} + +@media (max-width: 767px) { + .p-xs-6 { + padding: 0 6px !important; + } +} + +.flex-shrink-0 { + flex-shrink: 0; +} + +.flex-1-auto { + flex: 1 1 0%; +} + +.hstack { + display: flex; + flex-direction: row; + gap: 20px; +} + +@media (max-width: 767px) { + .hstack { + flex-direction: column; + } +} \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/scss/helpers/_icon-size.scss b/theme/packages/rtl/src/assets/scss/helpers/_icon-size.scss new file mode 100644 index 0000000..ac526ef --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/helpers/_icon-size.scss @@ -0,0 +1,15 @@ +@use "sass:meta"; + +$columns: 54; + +@mixin icon_size { + @for $i from 1 through $columns { + .icon-#{$i} { + height: #{$i}px !important; + width: #{$i}px !important; + line-height: #{$i + 8}px !important; + } + } +} + +@include icon_size; diff --git a/theme/packages/rtl/src/assets/scss/helpers/_text.scss b/theme/packages/rtl/src/assets/scss/helpers/_text.scss new file mode 100644 index 0000000..1c2636e --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/helpers/_text.scss @@ -0,0 +1,84 @@ +@use "sass:map"; +@use "variables"; + +$utilities: ( + "font-size": ( + property: font-size, + class: f-s, + values: variables.$font-sizes, + ), + "font-weight": ( + property: font-weight, + class: f-w, + values: variables.$font-wieghts, + ), + "font-style": ( + property: font-style, + class: font, + values: italic normal, + ), + "text-align": ( + property: text-align, + class: text, + values: center right left, + ), + "text-decoration": ( + property: text-decoration, + class: text, + values: none underline line-through, + ), + "text-transform": ( + property: text-transform, + class: text, + values: capitalize uppercase lowercase, + ), + "white-space": ( + property: white-space, + class: text, + values: ( + wrap: normal, + nowrap: nowrap, + ), + ), + "word-wrap": ( + property: word-wrap word-break, + class: text, + values: ( + break: break-word, + ), + ), + "text-overflow": ( + property: text-overflow, + class: text, + values: ellipsis, + ), + "text-color": ( + property: color, + class: text, + values: ( + reset: inherit, + current: currentColor, + ), + ), +); + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0px; +} + +.lh-lg { + line-height: 36px !important; +} + +.lh-sm { + line-height: 20px !important; +} + +.lh-normal { + line-height: normal !important; +} \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/scss/helpers/_variables.scss b/theme/packages/rtl/src/assets/scss/helpers/_variables.scss new file mode 100644 index 0000000..844ddf4 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/helpers/_variables.scss @@ -0,0 +1,102 @@ +@use "functions" as *; + +// Utility Map + +$utilities: () !default; + +// Spacing + +$spacer: 16px !default; +$spacers: ( + 0: 0, + 2: $spacer * 0.125, + 4: $spacer * 0.25, + 5: 5px, + 6: 7px, + 8: $spacer * 0.5, + 10: 10px, + 12: $spacer * 0.75, + 14: 14px, + 15: 15px, + 16: $spacer, + 20: 20px, + 24: $spacer * 1.5, + 30: 30px, + 32: $spacer * 2, + 44: 44px, + 48: $spacer * 3, + 60: 60px, + 66: 66px, + 80: 80px, +) !default; +$negative-spacers: negativify-map($spacers) !default; + +// Border + +$border-color: var(--mat-sys-outline-variant) !default; +$borders: ( + 0: 0, + 1: 1px solid $border-color, + 2: 2px solid $border-color, + 4: 4px solid $border-color, + 8: 8px solid $border-color, +) !default; + +// Border radius + +$radius-base: 7px !default; +$radius: ( + 0: 0, + 7: $radius-base, + 8: $radius-base * 2, + 12: $radius-base * 3, + 16: $radius-base * 4, + full: 9999px, +) !default; + +// Text + +$font-wieghts: ( + 100: 100, + 200: 200, + 300: 300, + 400: 400, + 500: 500, + 600: 600, + 700: 700, + 800: 800, + 900: 900, +) !default; + +$font-sizes: ( + 0: 0, + 10: 10px, + 12: 12px, + 14: 14px, + 15: 15px, + 16: 16px, + 18: 18px, + 20: 20px, + 21: 21px, + 24: 24px, + 28: 28px, + 30: 30px, + 36: 36px, + 40: 40px, + 48: 48px, +) !default; + +// Sizing + +$sizes: ( + 0: 0, + 20: 20%, + 25: 25%, + 40: 40%, + 50: 50%, + 60: 60%, + 75: 75%, + 80: 80%, + full: 100%, + auto: auto, +) !default; diff --git a/theme/packages/rtl/src/assets/scss/layouts/_header.scss b/theme/packages/rtl/src/assets/scss/layouts/_header.scss new file mode 100644 index 0000000..d24e1f8 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/layouts/_header.scss @@ -0,0 +1,64 @@ +@use "../variables" as *; + +html .topbar { + position: sticky; + top: 0; + z-index: 9; + height: $header-height; + + .notification-badge{ + .mat-badge-content{ + left: 80%; + bottom: 85%; + width: 16px; + height: 16px; + } + } +} + +.topbar-dd { + min-width: 360px !important; +} + +.apps-dd { + min-width: 830px !important; + overflow: unset !important; + + .mat-mdc-menu-content { + padding: 0; + } +} + +.text-hover-primary:hover { + .hover-text { + color: $primary; + } +} + +.upgrade-bg { + position: absolute; + top: 0px; + right: 0px; + height: 100%; +} + +.object-cover { + object-fit: cover; +} + +.profile-dd { + margin-top: -5px; + margin-left: -5px; +} + +.dark-theme { + .topbar { + .mat-mdc-icon-button { + color: $dark-text-secondary !important; + } + + .mdc-button { + --mat-button-text-label-text-color: $dark-text-secondary !important; + } + } +} \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/scss/override-component/_checkbox.scss b/theme/packages/rtl/src/assets/scss/override-component/_checkbox.scss new file mode 100644 index 0000000..eba7679 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/override-component/_checkbox.scss @@ -0,0 +1,23 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.checkbox-overrides( + ( + unselected-focus-icon-color: + var(--mat-checkbox-unselected-hover-state-layer-color), + ) +); + +// styles +html { + .mdc-checkbox__background { + border-radius: 4px; + width: 21px; + height: 21px; + border: 1px solid var(--mat-sys-outline); + } + + .mdc-checkbox .mdc-checkbox__native-control:focus ~ .mdc-checkbox__ripple { + background-color: var(--mat-checkbox-unselected-hover-state-layer-color); + } +} diff --git a/theme/packages/rtl/src/assets/scss/override-component/_datepicker.scss b/theme/packages/rtl/src/assets/scss/override-component/_datepicker.scss new file mode 100644 index 0000000..2686873 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/override-component/_datepicker.scss @@ -0,0 +1,11 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.datepicker-overrides( + ( + calendar-container-background-color: + var(--mat-card-elevated-container-color), + calendar-container-touch-elevation-shadow: var(--mat-sys-level1), + calendar-container-elevation-shadow: var(--mat-sys-level1), + ) +); diff --git a/theme/packages/rtl/src/assets/scss/override-component/_expansion.scss b/theme/packages/rtl/src/assets/scss/override-component/_expansion.scss new file mode 100644 index 0000000..0c5f781 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/override-component/_expansion.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.expansion-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/rtl/src/assets/scss/override-component/_paginator.scss b/theme/packages/rtl/src/assets/scss/override-component/_paginator.scss new file mode 100644 index 0000000..35479e7 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/override-component/_paginator.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.paginator-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/rtl/src/assets/scss/override-component/_stepper.scss b/theme/packages/rtl/src/assets/scss/override-component/_stepper.scss new file mode 100644 index 0000000..6a21bd4 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/override-component/_stepper.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.stepper-overrides( + ( + container-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/rtl/src/assets/scss/override-component/_table.scss b/theme/packages/rtl/src/assets/scss/override-component/_table.scss new file mode 100644 index 0000000..379ddcd --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/override-component/_table.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.table-overrides( + ( + background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/rtl/src/assets/scss/override-component/_tree.scss b/theme/packages/rtl/src/assets/scss/override-component/_tree.scss new file mode 100644 index 0000000..e755adc --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/override-component/_tree.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.tree-overrides( + ( + container-background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/rtl/src/assets/scss/pages/_frontend.scss b/theme/packages/rtl/src/assets/scss/pages/_frontend.scss new file mode 100644 index 0000000..db45c10 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/pages/_frontend.scss @@ -0,0 +1,143 @@ +.front-topbar { + &.fixed-topbar { + position: fixed; + top: 0; + width: 100%; + background-color: var(--mat-sys-background) !important; + z-index: 9; + } +} + +.back-to-top { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 999; + transition: opacity 0.3s ease; +} + +.tab-header { + + .profileTabs { + + .mat-mdc-tab { + padding: 30px 16px; + height: auto; + border-right: 1px solid var(--mat-sys-outline); + + &:last-child { + border-right: 0; + } + } + + .mat-mdc-tab-label-container { + border-top-width: 0; + } + } + +} + +.home-page .expansion-panel .mat-expansion-panel-body { + padding: 16px 0; +} + +.faq-accordion { + .mat-expansion-panel-body { + padding: 16px 24px !important; + } +} + +.mobile-sidebar { + .mdc-list { + .mdc-list-item { + .mat-mdc-button { + color: var(--mat-sys-on-background); + min-width: 100%; + justify-content: flex-start; + + &.selected { + background-color: var(--mat-sys-primary-fixed-dim); + color: var(--mat-sys-primary); + transition: background-color 0.3s ease; + } + } + } + } +} + + +.spacing-top-bottom { + padding: 80px 0; +} + +.spacing-left-right { + padding: 0 80px; +} + +.spacing-left { + padding-left: 80px; +} + +.spacing-top { + padding-top: 80px; +} + +.spacing-bottom { + padding-bottom: 80px; +} + +@media (max-width: 959px) { + .section-sub-title { + font-size: 30px !important; + } + + .spacing-top-bottom { + padding: 60px 0; + } + + .spacing-left-right { + padding: 0 60px; + } + + .spacing-left { + padding-left: 60px; + } + + .spacing-top { + padding-top: 60px; + } + + .spacing-bottom { + padding-bottom: 60px; + } +} + +@media (max-width: 767px) { + .section-sub-title { + font-size: 24px !important; + } + + .spacing-top-bottom { + padding: 30px 0; + } + + .spacing-left-right { + padding: 0 30px; + } + + .spacing-left { + padding-left: 30px; + } + + .spacing-top { + padding-top: 30px; + } + + .spacing-bottom { + padding-bottom: 30px; + } + + .footer-content .left-side-content { + padding: 30px !important; + } +} \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/scss/style.scss b/theme/packages/rtl/src/assets/scss/style.scss new file mode 100644 index 0000000..177d3f7 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/style.scss @@ -0,0 +1,51 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@use "themecolors/blue_theme"; +@use "themecolors/orange_theme"; +@use "themecolors/aqua_theme"; +@use "themecolors/cyan_theme"; +@use "themecolors/green_theme"; +@use "themecolors/purple_theme"; + +@use "variables" as *; +@use "override-component"; +@use "theme-variables/default-variables"; +@use "theme-variables/light-theme-variables"; +@use "theme-variables/dark-theme-variables"; + +//container layout +@use "layouts/transitions"; +@use "helpers/color"; +@use "helpers/border-color"; +@use "helpers/icon-size"; +@use "container"; +@use "layouts/layouts"; +@use "grid/grid"; +@use "helpers/custom-flex"; +@use "helpers"; + +// horizontal +@use "horizontal/horizontal"; +@use "dark/dark"; + +// apps +@use "apps/calendar"; +@use "apps/email"; +@use "apps/blogs"; +@use "apps/chat"; +@use "apps/contact-list"; +@use "apps/kanban"; +@use "apps/courses"; +@use "apps/todo"; +@use "apps/ecommerce"; + +@use "pages/auth"; +@use "pages/dashboards"; +@use "pages/landingpage"; +@use "pages/toast"; +@use "pages/pricing"; +@use "pages/frontend"; + +// RTL Theme +@use "rtl/rtl"; \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/scss/theme-variables/_dark-theme-variables.scss b/theme/packages/rtl/src/assets/scss/theme-variables/_dark-theme-variables.scss new file mode 100644 index 0000000..0375fc4 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/theme-variables/_dark-theme-variables.scss @@ -0,0 +1,32 @@ +@use "@angular/material" as mat; + +html.dark-theme { + color-scheme: dark; + --mat-sys-background: #141a21; + --mat-sys-on-background: rgba(255, 255, 255, 0.9); + --mat-sys-on-primary: #fff; + --mat-sys-surface-bright: #ffffff05; + --mat-sys-surface: #141a21; + --mat-sys-surface-container: #141a21; + --mat-sys-surface-container-low: #141a21; + --mat-sys-outline-variant: #2e3f50; + --mat-sys-outline: #2e3f50; + --mat-form-field-outlined-hover-outline-color: #465670; + --mat-checkbox-unselected-hover-state-layer-color: #19212a; + --mat-menu-item-hover-state-layer-color: #19212a; + --mat-button-toggle-state-layer-color: #19212a; + --mat-option-focus-state-layer-color: #19212a; + --mat-option-hover-state-layer-color: #19212a; + --mat-slide-toggle-unselected-track-color: #19212a; + --mat-stepper-header-focus-state-layer-color: #19212a; + --mat-stepper-header-hover-state-layer-color: #19212a; + --mat-expansion-header-hover-state-layer-color: #19212a; + @include mat.card-overrides((elevated-container-color: #1c252e, + elevated-container-elevation: rgba(0, 0, 0, 0.2) 0px 0px 2px 0px, + subtitle-text-color: rgba(255, 255, 255, 0.67), + )); + @include mat.theme-overrides((level1: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level2: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level3: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + )); +} \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/scss/theme-variables/_default-variables.scss b/theme/packages/rtl/src/assets/scss/theme-variables/_default-variables.scss new file mode 100644 index 0000000..e3adeb2 --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/theme-variables/_default-variables.scss @@ -0,0 +1,12 @@ +html { + --mat-sys-error-fixed-dim: rgba(247, 68, 86, 0.15); + --mat-select-container-elevation-shadow: var(--mat-sys-level3); + --mat-list-list-item-label-text-tracking: 0; + --mat-slide-toggle-track-height: 28px; + --mat-sidenav-container-divider-color: var(--mat-sys-outline-variant); + --mat-dialog-with-actions-content-padding: 20px 24px; + --mat-form-field-container-text-tracking: unset; + --mat-slide-toggle-with-icon-handle-size: 21px; + --mat-badge-text-color: white; + --mat-slide-toggle-selected-with-icon-handle-horizontal-margin: 0 26px; +} \ No newline at end of file diff --git a/theme/packages/rtl/src/assets/scss/theme-variables/_light-theme-variables.scss b/theme/packages/rtl/src/assets/scss/theme-variables/_light-theme-variables.scss new file mode 100644 index 0000000..735309e --- /dev/null +++ b/theme/packages/rtl/src/assets/scss/theme-variables/_light-theme-variables.scss @@ -0,0 +1,23 @@ +html.light-theme { + color-scheme: light; + --mat-sys-corner-small: 7px; + --mat-sys-background: #fff; + --mat-sys-surface-bright: #f2f6fa; + --mat-sys-surface: #fff; + --mat-sys-surface-container: #fff; + --mat-sys-surface-container-low: #fff; + --mat-sys-on-background: #2a3547; + --mat-sys-outline: #d7dde2; + --mat-sys-outline-variant: #d7dde2; + --mat-form-field-outlined-hover-outline-color: #d7dde2; + --mat-checkbox-unselected-hover-state-layer-color: #d7dde2; + --mat-menu-item-hover-state-layer-color: #f6f9fc; + --mat-button-toggle-state-layer-color: #f6f9fc; + --mat-option-focus-state-layer-color: #f6f9fc; + --mat-option-hover-state-layer-color: #f6f9fc; + --mat-slide-toggle-unselected-track-color: #f6f9fc; + --mat-stepper-header-focus-state-layer-color: #f6f9fc; + --mat-stepper-header-hover-state-layer-color: #f6f9fc; + --mat-dialog-supporting-text-color: var(--mat-sys-on-background); + --mat-expansion-header-hover-state-layer-color: #f6f9fc; + } \ No newline at end of file diff --git a/theme/packages/rtl/src/index.html b/theme/packages/rtl/src/index.html new file mode 100644 index 0000000..344a5f2 --- /dev/null +++ b/theme/packages/rtl/src/index.html @@ -0,0 +1,17 @@ + + + + + Modernize Angular 20 Admin Template + + + + + + + + + + + \ No newline at end of file diff --git a/theme/packages/rtl/tsconfig.json b/theme/packages/rtl/tsconfig.json new file mode 100644 index 0000000..c3587c1 --- /dev/null +++ b/theme/packages/rtl/tsconfig.json @@ -0,0 +1,34 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "strictPropertyInitialization": false, + "lib": [ + "ES2022", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true, + } +} diff --git a/theme/packages/starterkit/.editorconfig b/theme/packages/starterkit/.editorconfig new file mode 100644 index 0000000..59d9a3a --- /dev/null +++ b/theme/packages/starterkit/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/theme/packages/starterkit/.gitignore b/theme/packages/starterkit/.gitignore new file mode 100644 index 0000000..0711527 --- /dev/null +++ b/theme/packages/starterkit/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/theme/packages/starterkit/.npmrc b/theme/packages/starterkit/.npmrc new file mode 100644 index 0000000..e9ee3cb --- /dev/null +++ b/theme/packages/starterkit/.npmrc @@ -0,0 +1 @@ +legacy-peer-deps=true \ No newline at end of file diff --git a/theme/packages/starterkit/README.md b/theme/packages/starterkit/README.md new file mode 100644 index 0000000..4e00817 --- /dev/null +++ b/theme/packages/starterkit/README.md @@ -0,0 +1,2 @@ +# Modernize-Angular-pro +Modernize Angular Admin Dashboard diff --git a/theme/packages/starterkit/angular.json b/theme/packages/starterkit/angular.json new file mode 100644 index 0000000..6ff9209 --- /dev/null +++ b/theme/packages/starterkit/angular.json @@ -0,0 +1,122 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "Modernize": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "allowedCommonJsDependencies": ["bezier-easing"], + "outputPath": "dist/Modernize", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss", "src/assets/scss/style.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "12mb", + "maximumError": "12mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "12mb", + "maximumError": "12mb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "Modernize:build:production" + }, + "hmr": { + "hmr": true + }, + "development": { + "buildTarget": "Modernize:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "Modernize:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": ["zone.js", "zone.js/testing"], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], + "scripts": [] + } + } + } + } + }, + "cli": { + "analytics": false + }, + "schematics": { + "@schematics/angular:component": { + "type": "component" + }, + "@schematics/angular:directive": { + "type": "directive" + }, + "@schematics/angular:service": { + "type": "service" + }, + "@schematics/angular:guard": { + "typeSeparator": "." + }, + "@schematics/angular:interceptor": { + "typeSeparator": "." + }, + "@schematics/angular:module": { + "typeSeparator": "." + }, + "@schematics/angular:pipe": { + "typeSeparator": "." + }, + "@schematics/angular:resolver": { + "typeSeparator": "." + } + } +} diff --git a/theme/packages/starterkit/netlify.toml b/theme/packages/starterkit/netlify.toml new file mode 100644 index 0000000..ff1c050 --- /dev/null +++ b/theme/packages/starterkit/netlify.toml @@ -0,0 +1,4 @@ +[[redirects]] + from = "/*" + to = "/index.html" + status = 200 \ No newline at end of file diff --git a/theme/packages/starterkit/package-lock.json b/theme/packages/starterkit/package-lock.json new file mode 100644 index 0000000..1563ed9 --- /dev/null +++ b/theme/packages/starterkit/package-lock.json @@ -0,0 +1,14374 @@ +{ + "name": "modernize", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "modernize", + "version": "0.0.0", + "dependencies": { + "@angular/animations": "^20.0.4", + "@angular/cdk": "^20.0.3", + "@angular/common": "^20.0.4", + "@angular/compiler": "^20.0.4", + "@angular/core": "^20.0.4", + "@angular/forms": "^20.0.4", + "@angular/material": "^20.0.3", + "@angular/platform-browser": "^20.0.4", + "@angular/platform-browser-dynamic": "^20.0.4", + "@angular/router": "^20.0.4", + "@ngx-translate/core": "^14.0.0", + "@ngx-translate/http-loader": "^7.0.0", + "angular-tabler-icons": "^3.26.0", + "ngx-scrollbar": "^18.0.0", + "rxjs": "~7.8.2", + "sass": "^1.89.2", + "tslib": "^2.8.1", + "zone.js": "~0.15.1" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^20.0.3", + "@angular/cli": "~20.0.3", + "@angular/compiler-cli": "^20.0.4", + "@types/date-fns": "^2.6.3", + "@types/jasmine": "~5.1.8", + "jasmine-core": "~5.8.0", + "karma": "~6.4.4", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.1", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.8.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.2000.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2000.3.tgz", + "integrity": "sha512-37S4dzlwB3C8gnBlwxjjvNUqwSeKnDe2j1XWg7sj94kbg/jLJV0Db/Dvb7zJjKher6Ed1Bnj3pMOM206ALJW2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.0.3", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.0.3.tgz", + "integrity": "sha512-KJjSoJv3tjx8PaZ6NW12fBjYM4QMjlpZ+ep6Jc6Y6k0brUpVX8bC5+ZBvKB7VzNi2REB61JM573foY2Uvi0fQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.2000.3", + "@angular-devkit/build-webpack": "0.2000.3", + "@angular-devkit/core": "20.0.3", + "@angular/build": "20.0.3", + "@babel/core": "7.27.1", + "@babel/generator": "7.27.1", + "@babel/helper-annotate-as-pure": "7.27.1", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.27.1", + "@babel/plugin-transform-async-to-generator": "7.27.1", + "@babel/plugin-transform-runtime": "7.27.1", + "@babel/preset-env": "7.27.2", + "@babel/runtime": "7.27.1", + "@discoveryjs/json-ext": "0.6.3", + "@ngtools/webpack": "20.0.3", + "@vitejs/plugin-basic-ssl": "2.0.0", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.21", + "babel-loader": "10.0.0", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "13.0.0", + "css-loader": "7.1.2", + "esbuild-wasm": "0.25.5", + "fast-glob": "3.3.3", + "http-proxy-middleware": "3.0.5", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.3.0", + "less-loader": "12.3.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "mini-css-extract-plugin": "2.9.2", + "open": "10.1.2", + "ora": "8.2.0", + "picomatch": "4.0.2", + "piscina": "5.0.0", + "postcss": "8.5.3", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.2", + "sass": "1.88.0", + "sass-loader": "16.0.5", + "semver": "7.7.2", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.39.1", + "tree-kill": "1.2.2", + "tslib": "2.8.1", + "webpack": "5.99.8", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.2.1", + "webpack-merge": "6.0.1", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.25.5" + }, + "peerDependencies": { + "@angular/compiler-cli": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/localize": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "@angular/platform-server": "^20.0.0", + "@angular/service-worker": "^20.0.0", + "@angular/ssr": "^20.0.3", + "@web/test-runner": "^0.20.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^20.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "typescript": ">=5.8 <5.9" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, + "@angular/localize": { + "optional": true + }, + "@angular/platform-browser": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@babel/core": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz", + "integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.1", + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helpers": "^7.27.1", + "@babel/parser": "^7.27.1", + "@babel/template": "^7.27.1", + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular-devkit/build-angular/node_modules/sass": { + "version": "1.88.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.88.0.tgz", + "integrity": "sha512-sF6TWQqjFvr4JILXzG4ucGOLELkESHL+I5QJhh7CNaE+Yge0SI+ehCatsXhJ7ymU1hAFcIS3/PBpjdIbXoyVbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.2000.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2000.3.tgz", + "integrity": "sha512-6ZpShG/avZDDuY/LzRxHrSqDE25QsniLYs4Gf+32NFsoPM6hCSgpUpQRX2NtL592X3gDMykUj30TZoGf62zX2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2000.3", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/core": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.0.3.tgz", + "integrity": "sha512-XgEIbIky0pMtJSomHRaf16BT1jzJNQCm2geNZ642n3cj8fYLm4jHJX/r738kIfbHWoWXT/hlTmVgIH9TdQPicA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.2", + "source-map": "0.7.4" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.0.3.tgz", + "integrity": "sha512-T679AQXenG6e4fdC/HXrps0Dqy1EYKb4pFNLQqZHR9mfyeq/vxFWs3ga/yMiqvqMPUK5W5FucEpFZJQQmc7M+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.0.3", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "8.2.0", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/animations": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.0.4.tgz", + "integrity": "sha512-s0kRcEply2A1ThvFmb0+o+hEpAbPn08lpK8xjWZryM4cMrwjgsUE0OZHZPBANP4I1xT7Z82l+fmQbH+vX48EyA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.0.4", + "@angular/core": "20.0.4" + } + }, + "node_modules/@angular/build": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.0.3.tgz", + "integrity": "sha512-xA5eTGop85SI/+hfiOSJR/xI1w1NK3qylpEZ277YRaw8Ikh7r1DKPJOMGBfXNd8QsZYBSWGHA8SXvCmOh/hvLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.2000.3", + "@babel/core": "7.27.1", + "@babel/helper-annotate-as-pure": "7.27.1", + "@babel/helper-split-export-declaration": "7.24.7", + "@inquirer/confirm": "5.1.10", + "@vitejs/plugin-basic-ssl": "2.0.0", + "beasties": "0.3.4", + "browserslist": "^4.23.0", + "esbuild": "0.25.5", + "https-proxy-agent": "7.0.6", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "listr2": "8.3.3", + "magic-string": "0.30.17", + "mrmime": "2.0.1", + "parse5-html-rewriting-stream": "7.1.0", + "picomatch": "4.0.2", + "piscina": "5.0.0", + "rollup": "4.40.2", + "sass": "1.88.0", + "semver": "7.7.2", + "source-map-support": "0.5.21", + "tinyglobby": "0.2.13", + "vite": "6.3.5", + "watchpack": "2.4.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.3.0" + }, + "peerDependencies": { + "@angular/compiler": "^20.0.0", + "@angular/compiler-cli": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/localize": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "@angular/platform-server": "^20.0.0", + "@angular/service-worker": "^20.0.0", + "@angular/ssr": "^20.0.3", + "karma": "^6.4.0", + "less": "^4.2.0", + "ng-packagr": "^20.0.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "tslib": "^2.3.0", + "typescript": ">=5.8 <5.9", + "vitest": "^3.1.1" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, + "@angular/localize": { + "optional": true + }, + "@angular/platform-browser": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "karma": { + "optional": true + }, + "less": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/@babel/core": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz", + "integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.1", + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helpers": "^7.27.1", + "@babel/parser": "^7.27.1", + "@babel/template": "^7.27.1", + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@angular/build/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@angular/build/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular/build/node_modules/sass": { + "version": "1.88.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.88.0.tgz", + "integrity": "sha512-sF6TWQqjFvr4JILXzG4ucGOLELkESHL+I5QJhh7CNaE+Yge0SI+ehCatsXhJ7ymU1hAFcIS3/PBpjdIbXoyVbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/@angular/build/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/cdk": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-20.0.3.tgz", + "integrity": "sha512-70KG8GpK4aV9j5hUkpDZJQ6oMgCuaCRY6JX1axPxkNtQaiK6PAmTfQLiGqF2cYhbQneeq3uGvTorAjRfvp8NPQ==", + "license": "MIT", + "dependencies": { + "parse5": "^7.1.2", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^20.0.0 || ^21.0.0", + "@angular/core": "^20.0.0 || ^21.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.0.3.tgz", + "integrity": "sha512-tDYcUrxq8Y9wK6EqwJ6Gn+4IF+VpPVikmpuqzqrUtYzqvRTqYtkyhJsAu3Ec6d6941mL2U3ZnMm3sjOxPPNkjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2000.3", + "@angular-devkit/core": "20.0.3", + "@angular-devkit/schematics": "20.0.3", + "@inquirer/prompts": "7.5.1", + "@listr2/prompt-adapter-inquirer": "2.0.22", + "@schematics/angular": "20.0.3", + "@yarnpkg/lockfile": "1.1.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "8.3.3", + "npm-package-arg": "12.0.2", + "npm-pick-manifest": "10.0.0", + "pacote": "21.0.0", + "resolve": "1.22.10", + "semver": "7.7.2", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/common": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.0.4.tgz", + "integrity": "sha512-fWgxe2rgSKgI36ummBYnBN4YUrmp4CHbfEG3RMeJho/vhHKguk2/o6BgL9zvnKybvbWmuaqbkHogi+y0LeJ8Ww==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/core": "20.0.4", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.0.4.tgz", + "integrity": "sha512-1bP3P8Ll/KUYMPiE6TDjkMXkqCDVgSUAUsVCgzAxz4mcMuc9PnlbhQazpWHCkCDIjGFZ5XIAsS49V7tfaTbLDw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@angular/compiler-cli": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.0.4.tgz", + "integrity": "sha512-2FP1WMRexAMcDPNE3YO3zB++sCgND9O/qJC5rgKbAebpbmOrCDMUBRlftkwiLT+UhTM9PjhTtAGtK7C+2iwx1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "7.27.4", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^4.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^18.0.0" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/compiler": "20.0.4", + "typescript": ">=5.8 <5.9" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@angular/compiler-cli/node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@angular/compiler-cli/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@angular/compiler-cli/node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/@angular/compiler-cli/node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/@angular/core": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.0.4.tgz", + "integrity": "sha512-JhSl3B6CrJ9kegLffgWVFGF4D4bWLV/9r8R0+h78vU+ppdPFPWDha7WnirF31cPIg3pBzy6wn103Kcy9Ri5M5w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/compiler": "20.0.4", + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0" + }, + "peerDependenciesMeta": { + "@angular/compiler": { + "optional": true + }, + "zone.js": { + "optional": true + } + } + }, + "node_modules/@angular/forms": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.0.4.tgz", + "integrity": "sha512-bFTMgJSHiLr80ELymRykZW6o5QroDlk+g5AFFiY9yxM8I0DV5YpCNBefv8GiuWubE+Lw6LkQ/HMYeXYJMTue3A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.0.4", + "@angular/core": "20.0.4", + "@angular/platform-browser": "20.0.4", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/material": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-20.0.3.tgz", + "integrity": "sha512-kd5Mi6gVxcjDs1nfm8GG2rId59SXWQjkiBMqrYuhy2Trpb+zG0vrLClrpoe3JdWqoX4GJagxGwl3VRDBIoP/cw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/cdk": "20.0.3", + "@angular/common": "^20.0.0 || ^21.0.0", + "@angular/core": "^20.0.0 || ^21.0.0", + "@angular/forms": "^20.0.0 || ^21.0.0", + "@angular/platform-browser": "^20.0.0 || ^21.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.0.4.tgz", + "integrity": "sha512-hMJYvtZlNPh4Tt6JrnK+vmBmHWok04EkuJwyPcPhlle1u6/LihuCj4suELLqCanX9EzyNgvyKnws0i6JE/qh8Q==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/animations": "20.0.4", + "@angular/common": "20.0.4", + "@angular/core": "20.0.4" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.0.4.tgz", + "integrity": "sha512-MTjnSd/nuurpBT5FosgPSGsuH5xF9czmZOSvjBRPKDwAKBCBxISYx/Qb7ktqxI8Fp2ER2wbyxrypwcZHpDyysg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.0.4", + "@angular/compiler": "20.0.4", + "@angular/core": "20.0.4", + "@angular/platform-browser": "20.0.4" + } + }, + "node_modules/@angular/router": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.0.4.tgz", + "integrity": "sha512-t02ukwKh+YDZutR09ZYJVLaC+OPyDxu6ll7A2MFK0BNLPpD9oQc0lDwJZSrqfAhlXU0arWUjmwkNvFdh21/Z5Q==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.0.4", + "@angular/core": "20.0.4", + "@angular/platform-browser": "20.0.4", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz", + "integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.27.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz", + "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.4", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.4", + "@babel/types": "^7.27.3", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/@babel/generator": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz", + "integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.1", + "@babel/types": "^7.27.1", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.1.tgz", + "integrity": "sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", + "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.27.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", + "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", + "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz", + "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.1", + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", + "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", + "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", + "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.27.1.tgz", + "integrity": "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.27.1.tgz", + "integrity": "sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.5.tgz", + "integrity": "sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.27.1.tgz", + "integrity": "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.27.1.tgz", + "integrity": "sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.27.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.3.tgz", + "integrity": "sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", + "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", + "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", + "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.27.3.tgz", + "integrity": "sha512-7ZZtznF9g4l2JCImCo5LNKFHB5eXnN39lLtLY5Tg+VkR0jwOt7TBciMckuiQIOIW7L5tkQOCh3bVGYeXgMx52Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.27.3", + "@babel/plugin-transform-parameters": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", + "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.1.tgz", + "integrity": "sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.5.tgz", + "integrity": "sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.27.1.tgz", + "integrity": "sha512-TqGF3desVsTcp3WrJGj4HfKokfCXCLcHpt4PJF0D8/iT6LPd9RS82Upw3KPeyr6B22Lfd3DO8MVrmp0oRkUDdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.11.0", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.27.2.tgz", + "integrity": "sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.27.1", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.27.1", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.27.1", + "@babel/plugin-transform-classes": "^7.27.1", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.27.1", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-exponentiation-operator": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.27.2", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1", + "@babel/plugin-transform-parameters": "^7.27.1", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.27.1", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.11.0", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.40.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz", + "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", + "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", + "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.8.tgz", + "integrity": "sha512-d/QAsnwuHX2OPolxvYcgSj7A9DO9H6gVOy2DvBTx+P2LH2iRTo/RSGV3iwCzW024nP9hw98KIuDmdyhZQj1UQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.10", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.10.tgz", + "integrity": "sha512-FxbQ9giWxUWKUk2O5XZ6PduVnH2CZ/fmMKMBkH71MHJvWr7WL5AHKevhzF1L5uYWB2P548o1RzVxrNd3dpmk6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.11", + "@inquirer/type": "^3.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.13", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.13.tgz", + "integrity": "sha512-1viSxebkYN2nJULlzCxES6G9/stgHSepZ9LqqfdIGPHj5OHhiBUXVS0a6R0bEC2A+VL4D9w6QB66ebCr6HGllA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.13", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.13.tgz", + "integrity": "sha512-WbicD9SUQt/K8O5Vyk9iC2ojq5RHoCLK6itpp2fHsWe44VxxcA9z3GTWlvjSTGmMQpZr+lbVmrxdHcumJoLbMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.15.tgz", + "integrity": "sha512-4Y+pbr/U9Qcvf+N/goHzPEXiHH8680lM3Dr3Y9h9FFw4gHS+zVpbj8LfbKWIb/jayIB4aSO4pWiBTrBYWkvi5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.12.tgz", + "integrity": "sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.12.tgz", + "integrity": "sha512-xJ6PFZpDjC+tC1P8ImGprgcsrzQRsUh9aH3IZixm1lAZFK49UGHxM3ltFfuInN2kPYNfyoPRh+tU4ftsjPLKqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.15.tgz", + "integrity": "sha512-xWg+iYfqdhRiM55MvqiTCleHzszpoigUpN5+t1OMcRkJrUrw7va3AzXaxvS+Ak7Gny0j2mFSTv2JJj8sMtbV2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.15.tgz", + "integrity": "sha512-75CT2p43DGEnfGTaqFpbDC2p2EEMrq0S+IRrf9iJvYreMy5mAWj087+mdKyLHapUEPLjN10mNvABpGbk8Wdraw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.5.1.tgz", + "integrity": "sha512-5AOrZPf2/GxZ+SDRZ5WFplCA2TAQgK3OYrXCYmJL5NaTu4ECcoWFlfUZuw7Es++6Njv7iu/8vpYJhuzxUH76Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.1.6", + "@inquirer/confirm": "^5.1.10", + "@inquirer/editor": "^4.2.11", + "@inquirer/expand": "^4.0.13", + "@inquirer/input": "^4.1.10", + "@inquirer/number": "^3.0.13", + "@inquirer/password": "^4.0.13", + "@inquirer/rawlist": "^4.1.1", + "@inquirer/search": "^3.0.13", + "@inquirer/select": "^4.2.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.3.tgz", + "integrity": "sha512-7XrV//6kwYumNDSsvJIPeAqa8+p7GJh7H5kRuxirct2cgOcSWwwNGoXDRgpNFbY/MG2vQ4ccIWCi8+IXXyFMZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.15.tgz", + "integrity": "sha512-YBMwPxYBrADqyvP4nNItpwkBnGGglAvCLVW8u4pRmmvOsHUtCAUIMbUrLX5B3tFL1/WsLGdQ2HNzkqswMs5Uaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.2.3.tgz", + "integrity": "sha512-OAGhXU0Cvh0PhLz9xTF/kx6g6x+sP+PcyTiLvCrewI99P3BBeexD+VbuwkNDvqGkk3y2h5ZiWLeRP7BFlhkUDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.7.tgz", + "integrity": "sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.2.0.tgz", + "integrity": "sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.6.0.tgz", + "integrity": "sha512-sw/RMbehRhN68WRtcKCpQOPfnH6lLP4GJfqzi3iYej8tnzpZUDr6UkZYJjcjjC0FWEJOJbyM3PTIwxucUmDG2A==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.22.tgz", + "integrity": "sha512-hV36ZoY+xKL6pYOt1nPNnkciFkn89KZwqLhAFzJvYysAvL5uBQdiADZx/8bIDXIukzzwG0QlPYolgMzQUtKgpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/type": "^1.5.5" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.3.0.tgz", + "integrity": "sha512-LipbQobyEfQtu8WixasaFUZZ+JCGlho4OWwWIQ5ol0rB1RKkcZvypu7sS1CBvofBGVAa3vbOh8IOGQMrbmL5dg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.3.0.tgz", + "integrity": "sha512-yA+9P+ZeA3vg76BLXWeUomIAjxfmSmR2eg8fueHXDg5Xe1Xmkl9JCKuHXUhtJ+mMVcH12d5k4kJBLbyXTadfGQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.3.0.tgz", + "integrity": "sha512-EDYrW9kle+8wI19JCj/PhRnGoCN9bked5cdOPdo1wdgH/HzjgoLPFTn9DHlZccgTEVhp3O+bpWXdN/rWySVvjw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.3.0.tgz", + "integrity": "sha512-OeWvSgjXXZ/zmtLqqL78I3910F6UYpUubmsUU+iBHo6nTtjkpXms95rJtGrjkWQqwswKBD7xSMplbYC4LEsiPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.3.0.tgz", + "integrity": "sha512-wDd02mt5ScX4+xd6g78zKBr6ojpgCJCTrllCAabjgap5FzuETqOqaQfKhO+tJuGWv/J5q+GIds6uY7rNFueOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-arm64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.3.0.tgz", + "integrity": "sha512-COotWhHJgzXULLiEjOgWQwqig6PoA+6ji6W+sDl6M1HhMXWIymEVHGs0edsVSNtsNSCAWMxJgR3asv6FNX/2EA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.3.0.tgz", + "integrity": "sha512-kqUgQH+l8HDbkAapx+aoko7Ez4X4DqkIraOqY/k0QY5EN/iialVlFpBUXh4wFXzirdmEVjbIUMrceUh0Kh8LeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz", + "integrity": "sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.0.1", + "@napi-rs/nice-android-arm64": "1.0.1", + "@napi-rs/nice-darwin-arm64": "1.0.1", + "@napi-rs/nice-darwin-x64": "1.0.1", + "@napi-rs/nice-freebsd-x64": "1.0.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.0.1", + "@napi-rs/nice-linux-arm64-gnu": "1.0.1", + "@napi-rs/nice-linux-arm64-musl": "1.0.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.0.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.0.1", + "@napi-rs/nice-linux-s390x-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-musl": "1.0.1", + "@napi-rs/nice-win32-arm64-msvc": "1.0.1", + "@napi-rs/nice-win32-ia32-msvc": "1.0.1", + "@napi-rs/nice-win32-x64-msvc": "1.0.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz", + "integrity": "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz", + "integrity": "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", + "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz", + "integrity": "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz", + "integrity": "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz", + "integrity": "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz", + "integrity": "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz", + "integrity": "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz", + "integrity": "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz", + "integrity": "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz", + "integrity": "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz", + "integrity": "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz", + "integrity": "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz", + "integrity": "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz", + "integrity": "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ngtools/webpack": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.0.3.tgz", + "integrity": "sha512-LVI3N45iBqrXxZgRpYOyGzOxssXnCckKEOSeqmvus1IJ1rN6nz+q4Pq428lDrb0KQOkRIt7iR/jQLD1RpcTHRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^20.0.0", + "typescript": ">=5.8 <5.9", + "webpack": "^5.54.0" + } + }, + "node_modules/@ngx-translate/core": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-14.0.0.tgz", + "integrity": "sha512-UevdwNCXMRCdJv//0kC8h2eSfmi02r29xeE8E9gJ1Al4D4jEJ7eiLPdjslTMc21oJNGguqqWeEVjf64SFtvw2w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/core": ">=13.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@ngx-translate/http-loader": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-7.0.0.tgz", + "integrity": "sha512-j+NpXXlcGVdyUNyY/qsJrqqeAdJdizCd+GKh3usXExSqy1aE9866jlAIL+xrfDU4w+LiMoma5pgE4emvFebZmA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": ">=13.0.0", + "@ngx-translate/core": ">=14.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.3.tgz", + "integrity": "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.2.0.tgz", + "integrity": "sha512-rCNLSB/JzNvot0SEyXqWZ7tX2B5dD2a1br2Dp0vSYVo5jh8Z0EZ7lS9TsZ1UtziddB1UfNUaMCc538/HztnJGA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.2.tgz", + "integrity": "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.2.2.tgz", + "integrity": "sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.1.0.tgz", + "integrity": "sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT", + "optional": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.2.tgz", + "integrity": "sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.2.tgz", + "integrity": "sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.2.tgz", + "integrity": "sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.2.tgz", + "integrity": "sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.2.tgz", + "integrity": "sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.2.tgz", + "integrity": "sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.2.tgz", + "integrity": "sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.2.tgz", + "integrity": "sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.2.tgz", + "integrity": "sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.2.tgz", + "integrity": "sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.2.tgz", + "integrity": "sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.2.tgz", + "integrity": "sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.2.tgz", + "integrity": "sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.2.tgz", + "integrity": "sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.2.tgz", + "integrity": "sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.2.tgz", + "integrity": "sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.2.tgz", + "integrity": "sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.2.tgz", + "integrity": "sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.2.tgz", + "integrity": "sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.2.tgz", + "integrity": "sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@schematics/angular": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.0.3.tgz", + "integrity": "sha512-oWj5UU1gR12KDxQwOUpxweaaF8PPF7t5ymTa/px/nl4YYWd9s5e1skoDNcGHHl0MPHklJzNLxP7O89BORie5vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.0.3", + "@angular-devkit/schematics": "20.0.3", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@sigstore/bundle": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz", + "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.4.3.tgz", + "integrity": "sha512-fk2zjD9117RL9BjqEwF7fwv7Q/P9yGsMV4MUJZ/DocaQJ6+3pKr+syBq1owU5Q5qGw5CUbXzm+4yJ2JVRDQeSA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.1.0.tgz", + "integrity": "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.1.1.tgz", + "integrity": "sha512-eFFvlcBIoGwVkkwmTi/vEQFSva3xs5Ot3WmBcjgjVdiaoelBLQaQ/ZBfhlG0MnG0cmTYScPpk7eDdGDWUcFUmg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.1", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.1.1.tgz", + "integrity": "sha512-hVJD77oT67aowHxwT4+M6PGOp+E2LtLdTK3+FC0lBO9T7sYwItDMXZ7Z07IDCvR1M717a4axbIWckrW67KMP/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", + "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/date-fns": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@types/date-fns/-/date-fns-2.6.3.tgz", + "integrity": "sha512-Ke1lw2Ni1t/wMUoLtKFmSNCLozcTBd6vmMqFP4hRzXn6qzkNt97bPAX0x5Y/c15DP43kKvwW1ycStD5+43jVQA==", + "deprecated": "This is a stub types definition. date-fns provides its own type definitions, so you do not need this installed.", + "dev": true, + "license": "MIT", + "dependencies": { + "date-fns": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.16", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz", + "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.8.tgz", + "integrity": "sha512-u7/CnvRdh6AaaIzYjCgUuVbREFgulhX05Qtf6ZtW+aOcjCKKVvKgpkPYJBFTZSHtFBYimzU4zP0V2vrEsq9Wcg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.3.tgz", + "integrity": "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.0.0.tgz", + "integrity": "sha512-gc9Tjg8bUxBVSTzeWT3Njc0Cl3PakHFKdNfABnZWiUgbxqmHDEn7uECv3fHVylxoYgNzAcmU7ZrILz+BwSo3sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "vite": "^6.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/abbrev": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", + "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/angular-tabler-icons": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/angular-tabler-icons/-/angular-tabler-icons-3.26.0.tgz", + "integrity": "sha512-gOvELHvz9TgOXAVq1YDqPQ8Z+0kII4IETzKn95x//zdZ5//3RekpeAJE2go3zczXaxoy44frmea7i7mr40BDTw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + }, + "peerDependencies": { + "@angular/common": "17 - 19", + "@angular/core": "17 - 19" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz", + "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": "^18.20.0 || ^20.10.0 || >=22.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5.61.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz", + "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.4", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", + "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz", + "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.4" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/beasties": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.3.4.tgz", + "integrity": "sha512-NmzN1zN1cvGccXFyZ73335+ASXwBlVWcUPssiUDIlFdfyatHPRRufjCd5w8oPaQPvVnf9ELklaCGb1gi9FBwIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^10.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-media-query-parser": "^0.2.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", + "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001718", + "electron-to-chromium": "^1.5.160", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", + "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001724", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001724.tgz", + "integrity": "sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz", + "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.0.tgz", + "integrity": "sha512-FgR/h5a6hzJqATDGd9YG41SeDViH+0bkHn6WNXCi5zKAZkeESeSxLySSsFLHqLEVCh0E+rITmCf0dusXWYukeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-parent": "^6.0.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2", + "tinyglobby": "^0.2.12" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.43.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.43.0.tgz", + "integrity": "sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.173", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.173.tgz", + "integrity": "sha512-2bFhXP2zqSfQHugjqJIDFVwa+qIxyNApenmXTp9EjaKtdPrES5Qcn9/aSFy/NaP2E+fWG/zxKu/LBvY36p5VNQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", + "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", + "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "punycode": "^1.4.1", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.5.tgz", + "integrity": "sha512-V/rbdOws2gDcnCAECfPrajhuafI0WY4WumUgc8ZHwOLnvmM0doLQ+dqvVFI2qkVxQsvo6880aC9IjpyDqcwwTw==", + "dev": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", + "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.1", + "entities": "^6.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", + "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz", + "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jasmine-core": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.8.0.tgz", + "integrity": "sha512-Q9dqmpUAfptwyueW3+HqBOkSuYd9I/clZSSfN97wXE/Nr2ROFNCwIBEC1F6kb3QXS9Fcz0LjFYSDQT+BiwjuhA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-coverage/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma-coverage/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", + "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", + "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", + "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/karma/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/karma/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.10.0.tgz", + "integrity": "sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/less": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/less/-/less-4.3.0.tgz", + "integrity": "sha512-X9RyH9fvemArzfdP8Pi3irr7lor2Ok4rOttDXBhlwDg+wKQsXOXgHWduAJE1EsF7JJx0w0bcO6BC6tCKKYnXKA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.3.0.tgz", + "integrity": "sha512-0M6+uYulvYIWs52y0LqN4+QM9TqWAohYSNTo4htE8Z7Cn3G/qQMEmktfHmyJT23k+20kU9zHH2wrfFXkxNLtVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "dev": true, + "license": "ISC", + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.3.tgz", + "integrity": "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.3.0.tgz", + "integrity": "sha512-MgJocUI6QEiSXQBFWLeyo1R7eQj8Rke5dlPxX0KFwli8/bsCxpM/KbXO5y0qmV/5llQ3wpneDWcTYxa+4vn8iQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.3.0", + "@lmdb/lmdb-darwin-x64": "3.3.0", + "@lmdb/lmdb-linux-arm": "3.3.0", + "@lmdb/lmdb-linux-arm64": "3.3.0", + "@lmdb/lmdb-linux-x64": "3.3.0", + "@lmdb/lmdb-win32-arm64": "3.3.0", + "@lmdb/lmdb-win32-x64": "3.3.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz", + "integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.1.tgz", + "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.4.tgz", + "integrity": "sha512-uaff7RG9VIC4jacFW9xzL3jc0iM32DNHe4jYVycBcjUePT/Klnfj7pqtWJt9khvDFizmjN2TlYniYmSS2LIaZg==", + "dev": true, + "license": "MIT", + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ngx-scrollbar": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/ngx-scrollbar/-/ngx-scrollbar-18.0.0.tgz", + "integrity": "sha512-+ykmY491x+nzXvnecJvZHvDz0YWuX1r7SYMxNG4RVHXm5Z68P/8kd/3ryLD6DXdNWmJawd4NGvqq2ZkUKb/g3A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/cdk": ">=19.0.0", + "@angular/common": ">=19.0.0", + "@angular/core": ">=19.0.0", + "rxjs": ">=7.0.0" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.2.0.tgz", + "integrity": "sha512-T0S1zqskVUSxcsSTkAsLc7xCycrRYmtDHadDinzocrThjyQCn5kMlEBSj6H4qDbgsIOSLmmlRIeb0lZXj+UArA==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "tinyglobby": "^0.2.12", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.1.tgz", + "integrity": "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz", + "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-packlist": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.0.tgz", + "integrity": "sha512-rht9U6nS8WOBDc53eipZNPo5qkAV4X2rhKE2Oj1DYUQ3DieXfj0mKkVmjnf3iuNdtMd8WfLdi2L6ASkD/8a+Kg==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", + "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", + "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ordered-binary": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pacote": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.0.0.tgz", + "integrity": "sha512-lcqexq73AMv6QNLo7SOpz0JJoaGdS3rBFgF122NZVl1bApo2mfu+XzUBU/X/XsiJu+iUmKpekRayqQYAs+PhkA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^10.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.1.0.tgz", + "integrity": "sha512-2ifK6Jb+ONoqOy5f+cYHsqvx1obHQdvIk13Jmt/5ezxP0U9p+fqd+R6O73KblGswyuzBYfetmsfK9ThMgnuPPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.0.0.tgz", + "integrity": "sha512-R+arufwL7sZvGjAhSMK3TfH55YdGOqhpKXkcwQJr432AAnJX/xxX19PA4QisrmJ+BTTfZVggaz6HexbkQq1l1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.x" + }, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.1" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.1.tgz", + "integrity": "sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.2.tgz", + "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.7" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.40.2", + "@rollup/rollup-android-arm64": "4.40.2", + "@rollup/rollup-darwin-arm64": "4.40.2", + "@rollup/rollup-darwin-x64": "4.40.2", + "@rollup/rollup-freebsd-arm64": "4.40.2", + "@rollup/rollup-freebsd-x64": "4.40.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.40.2", + "@rollup/rollup-linux-arm-musleabihf": "4.40.2", + "@rollup/rollup-linux-arm64-gnu": "4.40.2", + "@rollup/rollup-linux-arm64-musl": "4.40.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.40.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.40.2", + "@rollup/rollup-linux-riscv64-gnu": "4.40.2", + "@rollup/rollup-linux-riscv64-musl": "4.40.2", + "@rollup/rollup-linux-s390x-gnu": "4.40.2", + "@rollup/rollup-linux-x64-gnu": "4.40.2", + "@rollup/rollup-linux-x64-musl": "4.40.2", + "@rollup/rollup-win32-arm64-msvc": "4.40.2", + "@rollup/rollup-win32-ia32-msvc": "4.40.2", + "@rollup/rollup-win32-x64-msvc": "4.40.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.89.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz", + "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.5", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz", + "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "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": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true, + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.1.0.tgz", + "integrity": "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "@sigstore/sign": "^3.1.0", + "@sigstore/tuf": "^3.1.0", + "@sigstore/verify": "^2.1.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.17.1" + } + }, + "node_modules/socket.io-adapter/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", + "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", + "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/terser": { + "version": "5.39.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.1.tgz", + "integrity": "sha512-Mm6+uad0ZuDtcV8/4uOZQDQ8RuiC5Pu+iZRedJtF7yA/27sPL7d++In/AJKpWZlU3SYMPPkVfwetn6sgZ66pUA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-dump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.3.tgz", + "integrity": "sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tuf-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.0.1.tgz", + "integrity": "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.40", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz", + "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", + "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.1.tgz", + "integrity": "sha512-OaI//3H0J7ZkR1OqlhGA8cA+Cbk/2xFOQpJOt5+s27/ta9eZwpeervh4Mxh4w0im/kdgktowaqVNR7QOrUd7Yg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack": { + "version": "5.99.8", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.8.tgz", + "integrity": "sha512-lQ3CPiSTpfOnrEGeXDwoq5hIGzSjmwD72GdfVzF7CQAI7t47rJG9eDWvcEkEn3CUQymAElVvDg3YNTlCYj+qUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@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.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.1.tgz", + "integrity": "sha512-ml/0HIj9NLpVKOMq+SuBPLHcmbG+TGIjXRHsYfZwocUBIqEvws8NnS/V9AFQ5FKP+tgn5adwVwRrTEpGL33QFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.21.2", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.7", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", + "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", + "license": "MIT" + } + } +} diff --git a/theme/packages/starterkit/package.json b/theme/packages/starterkit/package.json new file mode 100644 index 0000000..22a8a1c --- /dev/null +++ b/theme/packages/starterkit/package.json @@ -0,0 +1,46 @@ +{ + "name": "modernize", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^20.0.4", + "@angular/cdk": "^20.0.3", + "@angular/common": "^20.0.4", + "@angular/compiler": "^20.0.4", + "@angular/core": "^20.0.4", + "@angular/forms": "^20.0.4", + "@angular/material": "^20.0.3", + "@angular/platform-browser": "^20.0.4", + "@angular/platform-browser-dynamic": "^20.0.4", + "@angular/router": "^20.0.4", + "@ngx-translate/core": "^14.0.0", + "@ngx-translate/http-loader": "^7.0.0", + "angular-tabler-icons": "^3.26.0", + "ngx-scrollbar": "^18.0.0", + "rxjs": "~7.8.2", + "sass": "^1.89.2", + "tslib": "^2.8.1", + "zone.js": "~0.15.1" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^20.0.3", + "@angular/cli": "~20.0.3", + "@angular/compiler-cli": "^20.0.4", + "@types/date-fns": "^2.6.3", + "@types/jasmine": "~5.1.8", + "jasmine-core": "~5.8.0", + "karma": "~6.4.4", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.1", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.8.3" + } +} diff --git a/theme/packages/starterkit/src/app/app.component.html b/theme/packages/starterkit/src/app/app.component.html new file mode 100644 index 0000000..0680b43 --- /dev/null +++ b/theme/packages/starterkit/src/app/app.component.html @@ -0,0 +1 @@ + diff --git a/theme/packages/starterkit/src/app/app.component.spec.ts b/theme/packages/starterkit/src/app/app.component.spec.ts new file mode 100644 index 0000000..05e3099 --- /dev/null +++ b/theme/packages/starterkit/src/app/app.component.spec.ts @@ -0,0 +1,35 @@ +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + RouterTestingModule + ], + declarations: [ + AppComponent + ], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title 'Angular20'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('Angular20'); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('.content span')?.textContent).toContain('Angular20 app is running!'); + }); +}); diff --git a/theme/packages/starterkit/src/app/app.component.ts b/theme/packages/starterkit/src/app/app.component.ts new file mode 100644 index 0000000..f9e13b0 --- /dev/null +++ b/theme/packages/starterkit/src/app/app.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + selector: 'app-root', + imports: [RouterOutlet], + templateUrl: './app.component.html' +}) +export class AppComponent { + title = 'Modernize Angular Admin Template'; +} diff --git a/theme/packages/starterkit/src/app/app.config.ts b/theme/packages/starterkit/src/app/app.config.ts new file mode 100644 index 0000000..ef9c2b6 --- /dev/null +++ b/theme/packages/starterkit/src/app/app.config.ts @@ -0,0 +1,66 @@ +import { + ApplicationConfig, + provideZoneChangeDetection, + importProvidersFrom, +} from '@angular/core'; +import { + HttpClient, + provideHttpClient, + withInterceptorsFromDi, +} from '@angular/common/http'; +import { routes } from './app.routes'; +import { + provideRouter, + withComponentInputBinding, + withInMemoryScrolling, +} from '@angular/router'; +import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; +import { provideClientHydration } from '@angular/platform-browser'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateHttpLoader } from '@ngx-translate/http-loader'; + +// icons +import { TablerIconsModule } from 'angular-tabler-icons'; +import * as TablerIcons from 'angular-tabler-icons/icons'; + +// perfect scrollbar +import { NgScrollbarModule } from 'ngx-scrollbar'; + +//Import all material modules +import { MaterialModule } from './material.module'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + +export function HttpLoaderFactory(http: HttpClient): any { + return new TranslateHttpLoader(http, './assets/i18n/', '.json'); +} + +export const appConfig: ApplicationConfig = { + providers: [ + provideZoneChangeDetection({ eventCoalescing: true }), + provideRouter( + routes, + withInMemoryScrolling({ + scrollPositionRestoration: 'enabled', + anchorScrolling: 'enabled', + }), + withComponentInputBinding() + ), + provideHttpClient(withInterceptorsFromDi()), + provideClientHydration(), + provideAnimationsAsync(), + importProvidersFrom( + FormsModule, + ReactiveFormsModule, + MaterialModule, + TablerIconsModule.pick(TablerIcons), + NgScrollbarModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: HttpLoaderFactory, + deps: [HttpClient], + }, + }) + ), + ], +}; diff --git a/theme/packages/starterkit/src/app/app.routes.ts b/theme/packages/starterkit/src/app/app.routes.ts new file mode 100644 index 0000000..32e46a2 --- /dev/null +++ b/theme/packages/starterkit/src/app/app.routes.ts @@ -0,0 +1,44 @@ +import { Routes } from '@angular/router'; +import { BlankComponent } from './layouts/blank/blank.component'; +import { FullComponent } from './layouts/full/full.component'; + +export const routes: Routes = [ + { + path: '', + component: FullComponent, + children: [ + { + path: '', + redirectTo: '/starter', + pathMatch: 'full', + }, + { + path: 'starter', + loadChildren: () => + import('./pages/pages.routes').then((m) => m.PagesRoutes), + }, + { + path: 'sample-page', + loadChildren: () => + import('./pages/pages.routes').then((m) => m.PagesRoutes), + }, + ], + }, + { + path: '', + component: BlankComponent, + children: [ + { + path: 'authentication', + loadChildren: () => + import('./pages/authentication/authentication.routes').then( + (m) => m.AuthenticationRoutes + ), + }, + ], + }, + { + path: '**', + redirectTo: 'authentication/error', + }, +]; diff --git a/theme/packages/starterkit/src/app/config.ts b/theme/packages/starterkit/src/app/config.ts new file mode 100644 index 0000000..d1bbdbd --- /dev/null +++ b/theme/packages/starterkit/src/app/config.ts @@ -0,0 +1,25 @@ +export interface AppSettings { + dir: 'ltr' | 'rtl'; + theme: string; + sidenavOpened: boolean; + sidenavCollapsed: boolean; + boxed: boolean; + horizontal: boolean; + activeTheme: string; + language: string; + cardBorder: boolean; + navPos: 'side' | 'top'; +} + +export const defaults: AppSettings = { + dir: 'ltr', + theme: 'light', + sidenavOpened: false, + sidenavCollapsed: false, + boxed: true, + horizontal: false, + cardBorder: false, + activeTheme: 'blue_theme', + language: 'en-us', + navPos: 'side', +}; diff --git a/theme/packages/starterkit/src/app/layouts/blank/blank.component.html b/theme/packages/starterkit/src/app/layouts/blank/blank.component.html new file mode 100644 index 0000000..4dd0d8a --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/blank/blank.component.html @@ -0,0 +1,11 @@ + + + + + + diff --git a/theme/packages/starterkit/src/app/layouts/blank/blank.component.ts b/theme/packages/starterkit/src/app/layouts/blank/blank.component.ts new file mode 100644 index 0000000..b9291c1 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/blank/blank.component.ts @@ -0,0 +1,51 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { AppSettings } from 'src/app/config'; +import { CommonModule } from '@angular/common'; +import { RouterOutlet } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-blank', + templateUrl: './blank.component.html', + styleUrls: [], + imports: [RouterOutlet, MaterialModule, CommonModule], +}) +export class BlankComponent { + private htmlElement!: HTMLHtmlElement; + + options = this.settings.getOptions(); + + constructor(private settings: CoreService) { + this.htmlElement = document.querySelector('html')!; + // Initialize project theme with options + this.receiveOptions(this.options); + } + + receiveOptions(options: AppSettings): void { + this.toggleDarkTheme(options); + this.toggleColorsTheme(options); + } + + toggleDarkTheme(options: AppSettings) { + if (options.theme === 'dark') { + this.htmlElement.classList.add('dark-theme'); + this.htmlElement.classList.remove('light-theme'); + } else { + this.htmlElement.classList.remove('dark-theme'); + this.htmlElement.classList.add('light-theme'); + } + } + + toggleColorsTheme(options: AppSettings) { + // Remove any existing theme class dynamically + this.htmlElement.classList.forEach((className) => { + if (className.endsWith('_theme')) { + this.htmlElement.classList.remove(className); + } + }); + + // Add the selected theme class + this.htmlElement.classList.add(options.activeTheme); + } +} diff --git a/theme/packages/starterkit/src/app/layouts/full/full.component.html b/theme/packages/starterkit/src/app/layouts/full/full.component.html new file mode 100644 index 0000000..7f9ad4e --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/full.component.html @@ -0,0 +1,190 @@ + + + + + @if (!options.horizontal) { + +
+ + + + @for(item of navItems; track item) { + + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+
+ } + + + + + @if (resView) { + + + + + @for(item of navItems; track item) { + + } + + +
+
+ +
+

Mathew

+ Designer +
+
+ + + +
+
+
+
+ } + + + + + + + + + @if (!options.horizontal) { + + } @else { + + + } @if(options.horizontal) { + + } + +
+ + + + + +
+ +
+
+ + +
+
+
+
+ @if(options.theme === 'light') { + + logo + + } @else { + + logo + + } +
+ +
+ + + + + Apps + +
+
+ @for(appdd of apps; track appdd.img) { + + } +
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+ + +
+
+
+ + +
+

Settings

+ + + close + +
+ + +
+
\ No newline at end of file diff --git a/theme/packages/starterkit/src/app/layouts/full/full.component.ts b/theme/packages/starterkit/src/app/layouts/full/full.component.ts new file mode 100644 index 0000000..c259460 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/full.component.ts @@ -0,0 +1,283 @@ +import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout'; +import { Component, OnInit, ViewChild, ViewEncapsulation, ChangeDetectorRef } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { MatSidenav, MatSidenavContent } from '@angular/material/sidenav'; +import { CoreService } from 'src/app/services/core.service'; +import { AppSettings } from 'src/app/config'; +import { filter } from 'rxjs/operators'; +import { NavigationEnd, Router } from '@angular/router'; +import { navItems } from './vertical/sidebar/sidebar-data'; +import { NavService } from '../../services/nav.service'; +import { AppNavItemComponent } from './vertical/sidebar/nav-item/nav-item.component'; +import { RouterModule } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; +import { SidebarComponent } from './vertical/sidebar/sidebar.component'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { HeaderComponent } from './vertical/header/header.component'; +import { AppHorizontalHeaderComponent } from './horizontal/header/header.component'; +import { AppHorizontalSidebarComponent } from './horizontal/sidebar/sidebar.component'; +import { AppBreadcrumbComponent } from './shared/breadcrumb/breadcrumb.component'; +import { CustomizerComponent } from './shared/customizer/customizer.component'; + +const MOBILE_VIEW = 'screen and (max-width: 768px)'; +const TABLET_VIEW = 'screen and (min-width: 769px) and (max-width: 1024px)'; +const MONITOR_VIEW = 'screen and (min-width: 1024px)'; +const BELOWMONITOR = 'screen and (max-width: 1023px)'; + +// for mobile app sidebar +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +@Component({ + selector: 'app-full', + imports: [ + RouterModule, + AppNavItemComponent, + MaterialModule, + CommonModule, + SidebarComponent, + NgScrollbarModule, + TablerIconsModule, + HeaderComponent, + AppHorizontalHeaderComponent, + AppHorizontalSidebarComponent, + AppBreadcrumbComponent, + CustomizerComponent, + ], + templateUrl: './full.component.html', + styleUrls: [], + encapsulation: ViewEncapsulation.None +}) +export class FullComponent implements OnInit { + navItems = navItems; + + @ViewChild('leftsidenav') + public sidenav: MatSidenav; + resView = false; + @ViewChild('content', { static: true }) content!: MatSidenavContent; + //get options from service + options = this.settings.getOptions(); + private layoutChangesSubscription = Subscription.EMPTY; + private isMobileScreen = false; + private isContentWidthFixed = true; + private isCollapsedWidthFixed = false; + private htmlElement!: HTMLHtmlElement; + + get isOver(): boolean { + return this.isMobileScreen; + } + + get isTablet(): boolean { + return this.resView; + } + + // for mobile app sidebar + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/apps/chat', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'eCommerce App', + subtitle: 'Buy a Product', + link: '/apps/email/inbox', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/apps/invoice', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/apps/calendar', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/apps/contacts', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/apps/tickets', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/apps/email/inbox', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Courses', + subtitle: 'Create new course', + link: '/apps/courses', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/theme-pages/pricing', + }, + { + id: 2, + title: 'Authentication Design', + link: '/authentication/login', + }, + { + id: 3, + title: 'Register Now', + link: '/authentication/side-register', + }, + { + id: 4, + title: '404 Error Page', + link: '/authentication/error', + }, + { + id: 5, + title: 'Notes App', + link: '/apps/notes', + }, + { + id: 6, + title: 'Employee App', + link: '/apps/employee', + }, + { + id: 7, + title: 'Todo Application', + link: '/apps/todo', + }, + { + id: 8, + title: 'Treeview', + link: '/theme-pages/treeview', + }, + ]; + + constructor( + private settings: CoreService, + private mediaMatcher: MediaMatcher, + private router: Router, + private breakpointObserver: BreakpointObserver, + private navService: NavService, private cdr: ChangeDetectorRef + ) { + this.htmlElement = document.querySelector('html')!; + this.layoutChangesSubscription = this.breakpointObserver + .observe([MOBILE_VIEW, TABLET_VIEW, MONITOR_VIEW, BELOWMONITOR]) + .subscribe((state) => { + // SidenavOpened must be reset true when layout changes + this.options.sidenavOpened = true; + this.isMobileScreen = state.breakpoints[MOBILE_VIEW]; + if (this.options.sidenavCollapsed == false) { + this.options.sidenavCollapsed = state.breakpoints[TABLET_VIEW]; + } + this.isContentWidthFixed = state.breakpoints[MONITOR_VIEW]; + this.resView = state.breakpoints[BELOWMONITOR]; + }); + + // Initialize project theme with options + this.receiveOptions(this.options); + + // This is for scroll to top + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .subscribe((e) => { + this.content.scrollTo({ top: 0 }); + }); + } + + isFilterNavOpen = false; + + toggleFilterNav() { + this.isFilterNavOpen = !this.isFilterNavOpen; + console.log('Sidebar open:', this.isFilterNavOpen); + this.cdr.detectChanges(); // Ensures Angular updates the view + } + + ngOnInit(): void {} + + ngOnDestroy() { + this.layoutChangesSubscription.unsubscribe(); + } + + toggleCollapsed() { + this.isContentWidthFixed = false; + this.options.sidenavCollapsed = !this.options.sidenavCollapsed; + this.resetCollapsedState(); + } + + resetCollapsedState(timer = 400) { + setTimeout(() => this.settings.setOptions(this.options), timer); + } + + onSidenavClosedStart() { + this.isContentWidthFixed = false; + } + + onSidenavOpenedChange(isOpened: boolean) { + this.isCollapsedWidthFixed = !this.isOver; + this.options.sidenavOpened = isOpened; + this.settings.setOptions(this.options); + } + + receiveOptions(options: AppSettings): void { + this.toggleDarkTheme(options); + this.toggleColorsTheme(options); + } + + toggleDarkTheme(options: AppSettings) { + + if (options.theme === 'dark') { + this.htmlElement.classList.add('dark-theme'); + this.htmlElement.classList.remove('light-theme'); + } else { + this.htmlElement.classList.remove('dark-theme'); + this.htmlElement.classList.add('light-theme'); + } + } + + toggleColorsTheme(options: AppSettings) { + // Remove any existing theme class dynamically + this.htmlElement.classList.forEach((className) => { + if (className.endsWith('_theme')) { + this.htmlElement.classList.remove(className); + } + }); + + // Add the selected theme class + this.htmlElement.classList.add(options.activeTheme); + } +} diff --git a/theme/packages/starterkit/src/app/layouts/full/horizontal/header/header.component.html b/theme/packages/starterkit/src/app/layouts/full/horizontal/header/header.component.html new file mode 100644 index 0000000..1f928dd --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/horizontal/header/header.component.html @@ -0,0 +1,296 @@ + +
+
+ +
+ + + + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + +
+
Notifications
+ + 5 new + +
+ @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
diff --git a/theme/packages/starterkit/src/app/layouts/full/horizontal/header/header.component.ts b/theme/packages/starterkit/src/app/layouts/full/horizontal/header/header.component.ts new file mode 100644 index 0000000..800d0ef --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/horizontal/header/header.component.ts @@ -0,0 +1,296 @@ +import { Component, Output, EventEmitter, Input } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { MatDialog } from '@angular/material/dialog'; +import { navItems } from '../../vertical/sidebar/sidebar-data'; +import { TranslateService } from '@ngx-translate/core'; +import { RouterModule } from '@angular/router'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { BrandingComponent } from '../../vertical/sidebar/branding.component'; +import { AppSettings } from 'src/app/config'; +import { FormsModule } from '@angular/forms'; + +interface notifications { + id: number; + img: string; + title: string; + subtitle: string; +} + +interface profiledd { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +@Component({ + selector: 'app-horizontal-header', + imports: [RouterModule, TablerIconsModule, MaterialModule, BrandingComponent], + templateUrl: './header.component.html', +}) +export class AppHorizontalHeaderComponent { + @Input() showToggle = true; + @Input() toggleChecked = false; + @Output() toggleMobileNav = new EventEmitter(); + @Output() toggleMobileFilterNav = new EventEmitter(); + @Output() toggleCollapsed = new EventEmitter(); + + showFiller = false; + + @Output() optionsChange = new EventEmitter(); + + public selectedLanguage: any = { + language: 'English', + code: 'en', + type: 'US', + icon: '/assets/images/flag/icon-flag-en.svg', + }; + + public languages: any[] = [ + { + language: 'English', + code: 'en', + type: 'US', + icon: '/assets/images/flag/icon-flag-en.svg', + }, + { + language: 'Español', + code: 'es', + icon: '/assets/images/flag/icon-flag-es.svg', + }, + { + language: 'Français', + code: 'fr', + icon: '/assets/images/flag/icon-flag-fr.svg', + }, + { + language: 'German', + code: 'de', + icon: '/assets/images/flag/icon-flag-de.svg', + }, + ]; + + constructor( + private settings: CoreService, + private vsidenav: CoreService, + public dialog: MatDialog, + private translate: TranslateService + ) { + translate.setDefaultLang('en'); + } + + openDialog() { + const dialogRef = this.dialog.open(AppHorizontalSearchDialogComponent); + + dialogRef.afterClosed().subscribe((result) => { + console.log(`Dialog result: ${result}`); + }); + } + + changeLanguage(lang: any): void { + this.translate.use(lang.code); + this.selectedLanguage = lang; + } + + options = this.settings.getOptions(); + + private emitOptions() { + this.optionsChange.emit(this.options); + } + + setlightDark(theme: string) { + this.options.theme = theme; + this.emitOptions(); + } + + notifications: notifications[] = [ + { + id: 1, + img: '/assets/images/profile/user-1.jpg', + title: 'Roman Joined the Team!', + subtitle: 'Congratulate him', + }, + { + id: 2, + img: '/assets/images/profile/user-2.jpg', + title: 'New message received', + subtitle: 'Salma sent you new message', + }, + { + id: 3, + img: '/assets/images/profile/user-3.jpg', + title: 'New Payment received', + subtitle: 'Check your earnings', + }, + { + id: 4, + img: '/assets/images/profile/user-4.jpg', + title: 'Jolly completed tasks', + subtitle: 'Assign her new tasks', + }, + { + id: 5, + img: '/assets/images/profile/user-5.jpg', + title: 'Roman Joined the Team!', + subtitle: 'Congratulate him', + }, + ]; + + profiledd: profiledd[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-account.svg', + title: 'My Profile', + subtitle: 'Account Settings', + link: '/', + }, + { + id: 2, + img: '/assets/images/svgs/icon-inbox.svg', + title: 'My Inbox', + subtitle: 'Messages & Email', + link: '/', + }, + { + id: 3, + img: '/assets/images/svgs/icon-tasks.svg', + title: 'My Tasks', + subtitle: 'To-do and Daily Tasks', + link: '/', + }, + ]; + + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'eCommerce App', + subtitle: 'Buy a Product', + link: '/', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Courses', + subtitle: 'Create new course', + link: '/', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/', + }, + { + id: 2, + title: 'Authentication Design', + link: '/', + }, + { + id: 3, + title: 'Register Now', + link: '/', + }, + { + id: 4, + title: '404 Error Page', + link: '/', + }, + { + id: 5, + title: 'Notes App', + link: '/', + }, + { + id: 6, + title: 'Employee App', + link: '/', + }, + { + id: 7, + title: 'Todo Application', + link: '/', + }, + { + id: 8, + title: 'Treeview', + link: '/', + }, + ]; +} + +@Component({ + selector: 'app-search-dialog', + imports: [RouterModule, MaterialModule, TablerIconsModule, FormsModule], + templateUrl: 'search-dialog.component.html', +}) +export class AppHorizontalSearchDialogComponent { + searchText: string = ''; + navItems = navItems; + + navItemsData = navItems.filter((navitem) => navitem.displayName); + + // filtered = this.navItemsData.find((obj) => { + // return obj.displayName == this.searchinput; + // }); +} diff --git a/theme/packages/starterkit/src/app/layouts/full/horizontal/header/search-dialog.component.html b/theme/packages/starterkit/src/app/layouts/full/horizontal/header/search-dialog.component.html new file mode 100644 index 0000000..df13304 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/horizontal/header/search-dialog.component.html @@ -0,0 +1,39 @@ +
+
+
+ + + +
+
+ +
+
+
+ + +

Quick Page Links

+ + @for(item of navItemsData; track item.route) { + +
+ {{ item.displayName }} +
+ {{ item.route }} +
+ } +
diff --git a/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.html b/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.html new file mode 100644 index 0000000..21be8e6 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.html @@ -0,0 +1,21 @@ +@if(!item.navCap){ + + + {{ item.displayName }} + @if(item.children && item.children.length){ + + expand_more + + } + +} +@if(item.children){ +
+ @for(child of item.children; track child){ + + + } +
+} \ No newline at end of file diff --git a/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.ts b/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.ts new file mode 100644 index 0000000..cf26fed --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/nav-item/nav-item.component.ts @@ -0,0 +1,29 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../../services/nav.service'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { CommonModule } from '@angular/common'; +import { MatIconModule } from '@angular/material/icon'; + +@Component({ + selector: 'app-horizontal-nav-item', + imports: [TablerIconsModule, CommonModule, MatIconModule], + templateUrl: './nav-item.component.html', +}) +export class AppHorizontalNavItemComponent implements OnInit { + @Input() depth: any; + @Input() item: any; + + constructor(public navService: NavService, public router: Router) { + if (this.depth === undefined) { + this.depth = 0; + } + } + + ngOnInit() {} + onItemSelected(item: any) { + if (!item.children || !item.children.length) { + this.router.navigate([item.route]); + } + } +} diff --git a/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts b/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts new file mode 100644 index 0000000..5b14524 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/sidebar-data.ts @@ -0,0 +1,57 @@ +import { NavItem } from '../../vertical/sidebar/nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Starter', + iconName: 'home', + route: '/starter', + }, + { + displayName: 'Login', + iconName: 'lock', + route: '/authentication/login', + }, + { + navCap: 'Other', + }, + { + displayName: 'Menu Level', + iconName: 'box-multiple', + route: '/menu-level', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + { + displayName: 'Disabled', + iconName: 'ban', + route: '/disabled', + disabled: true, + }, +]; diff --git a/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/sidebar.component.html b/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/sidebar.component.html new file mode 100644 index 0000000..4a27ec4 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/sidebar.component.html @@ -0,0 +1,16 @@ +@if(mobileQuery.matches) { +
+
+
+
+ @for(item of navItems; track item) { + + + } +
+
+
+
+ } \ No newline at end of file diff --git a/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts b/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts new file mode 100644 index 0000000..f0e13f5 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/horizontal/sidebar/sidebar.component.ts @@ -0,0 +1,48 @@ +import { + Component, + OnInit, + Input, + ChangeDetectorRef, + OnChanges, +} from '@angular/core'; +import { navItems } from './sidebar-data'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../services/nav.service'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { AppHorizontalNavItemComponent } from './nav-item/nav-item.component'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-horizontal-sidebar', + imports: [AppHorizontalNavItemComponent, CommonModule], + templateUrl: './sidebar.component.html', +}) +export class AppHorizontalSidebarComponent implements OnInit { + navItems = navItems; + parentActive = ''; + + mobileQuery: MediaQueryList; + private _mobileQueryListener: () => void; + + constructor( + public navService: NavService, + public router: Router, + media: MediaMatcher, + changeDetectorRef: ChangeDetectorRef + ) { + this.mobileQuery = media.matchMedia('(min-width: 1100px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + this.router.events.subscribe( + () => (this.parentActive = this.router.url.split('/')[1]) + ); + } + + ngOnInit(): void { + this.parentActive = this.router.url.split('/')[1]; + + this.router.events.subscribe(() => { + this.parentActive = this.router.url.split('/')[1]; + }); + } +} diff --git a/theme/packages/starterkit/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.html b/theme/packages/starterkit/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.html new file mode 100644 index 0000000..b44906d --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.html @@ -0,0 +1,31 @@ +@if(pageInfo?.['title'] != 'Analytical' && pageInfo?.['title'] != 'eCommerce'){ +
+
+
+

+ {{ pageInfo?.['title'] }} +

+
+ +
+
+
+ +
+
+
+} \ No newline at end of file diff --git a/theme/packages/starterkit/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts b/theme/packages/starterkit/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts new file mode 100644 index 0000000..e9119c0 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/shared/breadcrumb/breadcrumb.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { Router, NavigationEnd, ActivatedRoute, Data } from '@angular/router'; +import { filter, map, mergeMap } from 'rxjs/operators'; +import { TablerIconsModule } from 'angular-tabler-icons'; + +@Component({ + selector: 'app-breadcrumb', + imports: [RouterModule, TablerIconsModule], + templateUrl: './breadcrumb.component.html', + styleUrls: [], +}) +export class AppBreadcrumbComponent { + // @Input() layout; + pageInfo: Data | any = Object.create(null); + myurl: any = this.router.url.slice(1).split('/'); + constructor( + private router: Router, + private activatedRoute: ActivatedRoute, + private titleService: Title + ) { + this.router.events + .pipe(filter((event) => event instanceof NavigationEnd)) + .pipe(map(() => this.activatedRoute)) + .pipe( + map((route) => { + while (route.firstChild) { + route = route.firstChild; + } + return route; + }) + ) + .pipe(filter((route) => route.outlet === 'primary')) + .pipe(mergeMap((route) => route.data)) + // tslint:disable-next-line - Disables all + .subscribe((event) => { + // tslint:disable-next-line - Disables all + this.titleService.setTitle(event['title'] + ' - Angular 20'); + this.pageInfo = event; + }); + } +} diff --git a/theme/packages/starterkit/src/app/layouts/full/shared/customizer/customizer.component.html b/theme/packages/starterkit/src/app/layouts/full/shared/customizer/customizer.component.html new file mode 100644 index 0000000..4b26b25 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/shared/customizer/customizer.component.html @@ -0,0 +1,173 @@ +
+ +
+
Theme Option
+ + +
+ + Light +
+
+ +
+ + Dark +
+
+
+ +
+
+ Theme Colors +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ Theme Direction +
+ + + +
+ + LTR +
+
+ +
+ + RTL +
+
+
+ + +
+ Layout type +
+ + + +
+ + Vertical +
+
+ +
+ + Horizontal +
+
+
+ @if(!options.horizontal){ +
+
+ Sidebar type +
+ + + +
+ + Full +
+
+ +
+ + Minisidebar +
+
+
+
+ } +
+ Card with +
+ + + +
+ + Shadow +
+
+ +
+ + Border +
+
+
+ +
+ Container Option +
+ + + +
+ + Full +
+
+ +
+ + Boxed +
+
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/starterkit/src/app/layouts/full/shared/customizer/customizer.component.scss b/theme/packages/starterkit/src/app/layouts/full/shared/customizer/customizer.component.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/shared/customizer/customizer.component.scss @@ -0,0 +1 @@ + diff --git a/theme/packages/starterkit/src/app/layouts/full/shared/customizer/customizer.component.ts b/theme/packages/starterkit/src/app/layouts/full/shared/customizer/customizer.component.ts new file mode 100644 index 0000000..243bef4 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/shared/customizer/customizer.component.ts @@ -0,0 +1,56 @@ +import { + Component, + Output, + EventEmitter, + ViewEncapsulation, + signal, +} from '@angular/core'; +import { AppSettings } from 'src/app/config'; +import { CoreService } from 'src/app/services/core.service'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { FormsModule } from '@angular/forms'; +import { NgScrollbarModule } from 'ngx-scrollbar'; + +@Component({ + selector: 'app-customizer', + imports: [TablerIconsModule, MaterialModule, FormsModule, NgScrollbarModule], + templateUrl: './customizer.component.html', + styleUrls: ['./customizer.component.scss'], + encapsulation: ViewEncapsulation.None, +}) +export class CustomizerComponent { + options = this.settings.getOptions(); + + @Output() optionsChange = new EventEmitter(); + hideSingleSelectionIndicator = signal(true); + + constructor(private settings: CoreService) { + + } + setDark(theme: string) { + this.settings.setOptions({ theme: theme }); + this.emitOptions(); + + } + + setColor(color: string) { + this.settings.setOptions({ activeTheme: color }); + this.emitOptions(); + } + + setDir(dir: 'ltr' | 'rtl') { + this.settings.setOptions({ dir: dir }); + this.emitOptions(); + } + + + setSidebar(sidenavOpened: boolean) { + this.settings.setOptions({ sidenavOpened: sidenavOpened }); + this.emitOptions(); + } + + private emitOptions() { + this.optionsChange.emit(this.options); + } +} diff --git a/theme/packages/starterkit/src/app/layouts/full/vertical/header/header.component.html b/theme/packages/starterkit/src/app/layouts/full/vertical/header/header.component.html new file mode 100644 index 0000000..d41f342 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/vertical/header/header.component.html @@ -0,0 +1,215 @@ + + + + @if(showToggle) { + + } + + + @if(!showToggle) { + + } + + + + + + + +
+ + + + + +
+
+
+
+ @for(appdd of apps; track appdd.title) { + + } +
+
+
+ + Frequently + Asked Questions + + Check +
+
+
+
+

Quick Links

+ @for(quicklink of quicklinks; track quicklink.title) { + + } +
+
+
+
+ Chat + Calendar + Email +
+ + + + + + + + + + + + @for(lang of languages; track lang.icon) { + + } + + @if(options.theme=='light'){ + + }@else{ + + } + + + + + + + +
+
Notifications
+ + 5 new + +
+ + @for(notification of notifications; track notification.title) { + + } + +
+ +
+
+ + + + + + + +
+
User Profile
+ +
+ +
+
Mathew Anderson
+ Designer + + + info@modernize.com + +
+
+
+
+ @for(profile of profiledd; track profile.title) { + +
+ + +
+
+ {{ profile.title }} +
+ {{ profile.subtitle }} +
+
+
+ } + + +
+
+
+
+ Unlimited
+ Access +
+ +
+
+ upgrade-bg +
+
+
+
+ +
+ Logout +
+
+
+
\ No newline at end of file diff --git a/theme/packages/starterkit/src/app/layouts/full/vertical/header/header.component.ts b/theme/packages/starterkit/src/app/layouts/full/vertical/header/header.component.ts new file mode 100644 index 0000000..e105c77 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/vertical/header/header.component.ts @@ -0,0 +1,314 @@ +import { + Component, + Output, + EventEmitter, + Input, + signal, + ViewEncapsulation, +} from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { MatDialog } from '@angular/material/dialog'; +import { navItems } from '../sidebar/sidebar-data'; +import { TranslateService } from '@ngx-translate/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { RouterModule } from '@angular/router'; + +import { FormsModule } from '@angular/forms'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { AppSettings } from 'src/app/config'; + +interface notifications { + id: number; + img: string; + title: string; + subtitle: string; +} + +interface profiledd { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface apps { + id: number; + img: string; + title: string; + subtitle: string; + link: string; +} + +interface quicklinks { + id: number; + title: string; + link: string; +} + +@Component({ + selector: 'app-header', + imports: [ + RouterModule, + NgScrollbarModule, + TablerIconsModule, + MaterialModule +], + templateUrl: './header.component.html', + encapsulation: ViewEncapsulation.None, +}) +export class HeaderComponent { + @Input() showToggle = true; + @Input() toggleChecked = false; + @Output() toggleMobileNav = new EventEmitter(); + @Output() toggleMobileFilterNav = new EventEmitter(); + @Output() toggleCollapsed = new EventEmitter(); + + + showFiller = false; + + public selectedLanguage: any = { + language: 'English', + code: 'en', + type: 'US', + icon: '/assets/images/flag/icon-flag-en.svg', + }; + + public languages: any[] = [ + { + language: 'English', + code: 'en', + type: 'US', + icon: '/assets/images/flag/icon-flag-en.svg', + }, + { + language: 'Español', + code: 'es', + icon: '/assets/images/flag/icon-flag-es.svg', + }, + { + language: 'Français', + code: 'fr', + icon: '/assets/images/flag/icon-flag-fr.svg', + }, + { + language: 'German', + code: 'de', + icon: '/assets/images/flag/icon-flag-de.svg', + }, + ]; + + @Output() optionsChange = new EventEmitter(); + + constructor( + private settings: CoreService, + private vsidenav: CoreService, + public dialog: MatDialog, + private translate: TranslateService + ) { + translate.setDefaultLang('en'); + + } + + options = this.settings.getOptions(); + + + openDialog() { + const dialogRef = this.dialog.open(AppSearchDialogComponent); + + dialogRef.afterClosed().subscribe((result) => { + console.log(`Dialog result: ${result}`); + }); + } + + changeLanguage(lang: any): void { + this.translate.use(lang.code); + this.selectedLanguage = lang; + } + + setlightDark(theme: string) { + this.options.theme =theme; + this.emitOptions(); + + } + + private emitOptions() { + this.optionsChange.emit(this.options); + } + + notifications: notifications[] = [ + { + id: 1, + img: '/assets/images/profile/user-1.jpg', + title: 'Roman Joined the Team!', + subtitle: 'Congratulate him sf', + }, + { + id: 2, + img: '/assets/images/profile/user-2.jpg', + title: 'New message received', + subtitle: 'Salma sent you new message', + }, + { + id: 3, + img: '/assets/images/profile/user-3.jpg', + title: 'New Payment received', + subtitle: 'Check your earnings', + }, + { + id: 4, + img: '/assets/images/profile/user-4.jpg', + title: 'Jolly completed tasks', + subtitle: 'Assign her new tasks', + }, + { + id: 5, + img: '/assets/images/profile/user-5.jpg', + title: 'Roman Joined thed Team!', + subtitle: 'Congratulate him', + }, + ]; + + profiledd: profiledd[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-account.svg', + title: 'My Profile', + subtitle: 'Account Settings', + link: '/', + }, + { + id: 2, + img: '/assets/images/svgs/icon-inbox.svg', + title: 'My Inbox', + subtitle: 'Messages & Email', + link: '/', + }, + { + id: 3, + img: '/assets/images/svgs/icon-tasks.svg', + title: 'My Tasks', + subtitle: 'To-do and Daily Tasks', + link: '/', + }, + ]; + + apps: apps[] = [ + { + id: 1, + img: '/assets/images/svgs/icon-dd-chat.svg', + title: 'Chat Application', + subtitle: 'Messages & Emails', + link: '/', + }, + { + id: 2, + img: '/assets/images/svgs/icon-dd-cart.svg', + title: 'eCommerce App', + subtitle: 'Buy a Product', + link: '/', + }, + { + id: 3, + img: '/assets/images/svgs/icon-dd-invoice.svg', + title: 'Invoice App', + subtitle: 'Get latest invoice', + link: '/', + }, + { + id: 4, + img: '/assets/images/svgs/icon-dd-date.svg', + title: 'Calendar App', + subtitle: 'Get Dates', + link: '/', + }, + { + id: 5, + img: '/assets/images/svgs/icon-dd-mobile.svg', + title: 'Contact Application', + subtitle: '2 Unsaved Contacts', + link: '/', + }, + { + id: 6, + img: '/assets/images/svgs/icon-dd-lifebuoy.svg', + title: 'Tickets App', + subtitle: 'Create new ticket', + link: '/', + }, + { + id: 7, + img: '/assets/images/svgs/icon-dd-message-box.svg', + title: 'Email App', + subtitle: 'Get new emails', + link: '/', + }, + { + id: 8, + img: '/assets/images/svgs/icon-dd-application.svg', + title: 'Courses', + subtitle: 'Create new course', + link: '/', + }, + ]; + + quicklinks: quicklinks[] = [ + { + id: 1, + title: 'Pricing Page', + link: '/t', + }, + { + id: 2, + title: 'Authentication Design', + link: '/', + }, + { + id: 3, + title: 'Register Now', + link: '/', + }, + { + id: 4, + title: '404 Error Page', + link: '/', + }, + { + id: 5, + title: 'Notes App', + link: '/', + }, + { + id: 6, + title: 'Employee App', + link: '/', + }, + { + id: 7, + title: 'Todo Application', + link: '/', + }, + { + id: 8, + title: 'Treeview', + link: '/', + }, + ]; +} + +@Component({ + selector: 'search-dialog', + imports: [RouterModule, MaterialModule, TablerIconsModule, FormsModule], + templateUrl: 'search-dialog.component.html', +}) +export class AppSearchDialogComponent { + searchText: string = ''; + navItems = navItems; + + navItemsData = navItems.filter((navitem) => navitem.displayName); + + // filtered = this.navItemsData.find((obj) => { + // return obj.displayName == this.searchinput; + // }); +} diff --git a/theme/packages/starterkit/src/app/layouts/full/vertical/header/search-dialog.component.html b/theme/packages/starterkit/src/app/layouts/full/vertical/header/search-dialog.component.html new file mode 100644 index 0000000..79df4cf --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/vertical/header/search-dialog.component.html @@ -0,0 +1,39 @@ +
+
+
+ + + +
+
+ +
+
+
+ + +

Quick Page Links

+ + @for(item of navItemsData; track item.displayName) { + +
+ {{ item.displayName }} +
+ {{ item.route }} +
+ } +
diff --git a/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/branding.component.ts b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/branding.component.ts new file mode 100644 index 0000000..c383e9f --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/branding.component.ts @@ -0,0 +1,28 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; + +@Component({ + selector: 'app-branding', + imports: [], + template: ` + + logo + + + + logo + + `, +}) +export class BrandingComponent { + options = this.settings.getOptions(); + constructor(private settings: CoreService) {} +} diff --git a/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.html b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.html new file mode 100644 index 0000000..06940c0 --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.html @@ -0,0 +1,43 @@ +@if(item.navCap){ + +} @if(!item.navCap && !item.external && !item.twoLines) { + + + {{ item.displayName | translate }} + @if(item.children && item.children.length) { + + + + expand_more + + + } @if(item.chip) { + + {{ item.chipContent }} + + } + +} + + + +@if(!item.navCap && item.external) { + + + {{ item.displayName | translate }} + +} + + +@if(expanded) { @for(child of item.children; track child) { + + +} } \ No newline at end of file diff --git a/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts new file mode 100644 index 0000000..45bfd2f --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.component.ts @@ -0,0 +1,104 @@ +import { + Component, + HostBinding, + Input, + OnInit, + OnChanges, + Output, + EventEmitter, +} from '@angular/core'; +import { NavItem } from './nav-item'; +import { Router } from '@angular/router'; +import { NavService } from '../../../../../services/nav.service'; +import { + animate, + state, + style, + transition, + trigger, +} from '@angular/animations'; +import { TranslateModule } from '@ngx-translate/core'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-nav-item', + imports: [TranslateModule, TablerIconsModule, MaterialModule, CommonModule], + templateUrl: './nav-item.component.html', + styleUrls: [], + animations: [ + trigger('indicatorRotate', [ + state('collapsed', style({ transform: 'rotate(0deg)' })), + state('expanded', style({ transform: 'rotate(180deg)' })), + transition( + 'expanded <=> collapsed', + animate('225ms cubic-bezier(0.4,0.0,0.2,1)') + ), + ]), + ], +}) +export class AppNavItemComponent implements OnChanges { + @Output() toggleMobileLink: any = new EventEmitter(); + @Output() notify: EventEmitter = new EventEmitter(); + + expanded: any = false; + disabled: any = false; + twoLines: any = false; + @HostBinding('attr.aria-expanded') ariaExpanded = this.expanded; + @Input() item: NavItem | any; + @Input() depth: any; + + constructor(public navService: NavService, public router: Router) { + if (this.depth === undefined) { + this.depth = 0; + } + } + + ngOnChanges() { + const url = this.navService.currentUrl(); + if (this.item.route && url) { + this.expanded = url.indexOf(`/${this.item.route}`) === 0; + this.ariaExpanded = this.expanded; + } + } + + onItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + this.router.navigate([item.route]); + } + if (item.children && item.children.length) { + this.expanded = !this.expanded; + } + //scroll + window.scroll({ + top: 0, + left: 0, + behavior: 'smooth', + }); + if (!this.expanded) { + if (window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + onSubItemSelected(item: NavItem) { + if (!item.children || !item.children.length) { + if (this.expanded && window.innerWidth < 1024) { + this.notify.emit(); + } + } + } + + isDirectlyActive(item: NavItem): boolean { + return !!item.route && this.router.isActive(item.route, true); + } + + isChildActive(item: NavItem): boolean { + if (!item.children) return false; + return item.children.some( + (child) => this.isDirectlyActive(child) || this.isChildActive(child) + ); + } +} diff --git a/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.ts b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.ts new file mode 100644 index 0000000..a6274be --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/nav-item/nav-item.ts @@ -0,0 +1,15 @@ +export interface NavItem { + displayName?: string; + disabled?: boolean; + external?: boolean; + twoLines?: boolean; + chip?: boolean; + iconName?: string; + navCap?: string; + chipContent?: string; + chipClass?: string; + subtext?: string; + route?: string; + children?: NavItem[]; + ddType?: string; +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/sidebar-data.ts b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/sidebar-data.ts new file mode 100644 index 0000000..8c0b7ba --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/sidebar-data.ts @@ -0,0 +1,84 @@ +import { NavItem } from './nav-item/nav-item'; + +export const navItems: NavItem[] = [ + { + navCap: 'Home', + }, + { + displayName: 'Starter', + iconName: 'home', + route: '/starter', + }, + { + displayName: 'Login', + iconName: 'lock', + route: '/authentication/login', + }, + { + displayName: 'Register', + iconName: 'user-edit', + route: '/authentication/register', + }, + { + navCap: 'Other', + }, + { + displayName: 'Menu Level', + iconName: 'box-multiple', + route: '/menu-level', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + children: [ + { + displayName: 'Menu 1', + iconName: 'point', + route: '/menu-1', + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + + { + displayName: 'Menu 2', + iconName: 'point', + route: '/menu-2', + }, + ], + }, + { + displayName: 'Disabled', + iconName: 'ban', + route: '/disabled', + disabled: true, + }, + { + displayName: 'Chip', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'bg-primary text-white', + chipContent: '9', + }, + { + displayName: 'Outlined', + iconName: 'mood-smile', + route: '/', + chip: true, + chipClass: 'b-1 border-primary text-primary', + chipContent: 'outlined', + }, + { + displayName: 'External Link', + iconName: 'star', + route: 'https://www.google.com/', + external: true, + }, +]; diff --git a/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/sidebar.component.html b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/sidebar.component.html new file mode 100644 index 0000000..5330def --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/sidebar.component.html @@ -0,0 +1,13 @@ +
+
+ + @if(showToggle) { + + + + } +
diff --git a/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/sidebar.component.ts b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/sidebar.component.ts new file mode 100644 index 0000000..fc21a5e --- /dev/null +++ b/theme/packages/starterkit/src/app/layouts/full/vertical/sidebar/sidebar.component.ts @@ -0,0 +1,25 @@ +import { + Component, + EventEmitter, + Input, + OnInit, + Output, + ViewChild, +} from '@angular/core'; +import { BrandingComponent } from './branding.component'; +import { TablerIconsModule } from 'angular-tabler-icons'; +import { MaterialModule } from 'src/app/material.module'; + +@Component({ + selector: 'app-sidebar', + imports: [BrandingComponent, TablerIconsModule, MaterialModule], + templateUrl: './sidebar.component.html', +}) +export class SidebarComponent implements OnInit { + constructor() {} + @Input() showToggle = true; + @Output() toggleMobileNav = new EventEmitter(); + @Output() toggleCollapsed = new EventEmitter(); + + ngOnInit(): void {} +} diff --git a/theme/packages/starterkit/src/app/material.module.ts b/theme/packages/starterkit/src/app/material.module.ts new file mode 100644 index 0000000..4f8ca3a --- /dev/null +++ b/theme/packages/starterkit/src/app/material.module.ts @@ -0,0 +1,85 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +// Material Form Controls +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatSelectModule } from '@angular/material/select'; +import { MatSliderModule } from '@angular/material/slider'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +// Material Navigation +import { MatMenuModule } from '@angular/material/menu'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatToolbarModule } from '@angular/material/toolbar'; +// Material Layout +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatListModule } from '@angular/material/list'; +import { MatStepperModule } from '@angular/material/stepper'; +import { MatTabsModule } from '@angular/material/tabs'; +import { MatTreeModule } from '@angular/material/tree'; +// Material Buttons & Indicators +import { MatButtonModule } from '@angular/material/button'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatIconModule } from '@angular/material/icon'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +// Material Popups & Modals +import { MatBottomSheetModule } from '@angular/material/bottom-sheet'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { MatTooltipModule } from '@angular/material/tooltip'; +// Material Data tables +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatSortModule } from '@angular/material/sort'; +import { MatTableModule } from '@angular/material/table'; + +@NgModule({ + declarations: [], + exports: [ + MatAutocompleteModule, + MatCheckboxModule, + MatDatepickerModule, + MatFormFieldModule, + MatInputModule, + MatRadioModule, + MatSelectModule, + MatSliderModule, + MatSlideToggleModule, + MatMenuModule, + MatSidenavModule, + MatToolbarModule, + MatCardModule, + MatDividerModule, + MatExpansionModule, + MatGridListModule, + MatListModule, + MatStepperModule, + MatTabsModule, + MatTreeModule, + MatButtonModule, + MatButtonToggleModule, + MatBadgeModule, + MatChipsModule, + MatIconModule, + MatProgressSpinnerModule, + MatProgressBarModule, + MatRippleModule, + MatBottomSheetModule, + MatDialogModule, + MatSnackBarModule, + MatTooltipModule, + MatPaginatorModule, + MatSortModule, + MatTableModule, + ], +}) +export class MaterialModule {} diff --git a/theme/packages/starterkit/src/app/pages/authentication/authentication.routes.ts b/theme/packages/starterkit/src/app/pages/authentication/authentication.routes.ts new file mode 100644 index 0000000..236411d --- /dev/null +++ b/theme/packages/starterkit/src/app/pages/authentication/authentication.routes.ts @@ -0,0 +1,26 @@ +import { Routes } from '@angular/router'; + +import { AppErrorComponent } from './error/error.component'; +import { AppSideLoginComponent } from './side-login/side-login.component'; +import { AppSideRegisterComponent } from './side-register/side-register.component'; + +export const AuthenticationRoutes: Routes = [ + { + path: '', + children: [ + { + path: 'error', + component: AppErrorComponent, + }, + + { + path: 'login', + component: AppSideLoginComponent, + }, + { + path: 'register', + component: AppSideRegisterComponent, + }, + ], + }, +]; diff --git a/theme/packages/starterkit/src/app/pages/authentication/error/error.component.html b/theme/packages/starterkit/src/app/pages/authentication/error/error.component.html new file mode 100644 index 0000000..33c5deb --- /dev/null +++ b/theme/packages/starterkit/src/app/pages/authentication/error/error.component.html @@ -0,0 +1,10 @@ +
+
+
+ error-bg +

Opps!!!

+
This page you are looking for could not be found.
+ Go back to Home +
+
+
diff --git a/theme/packages/starterkit/src/app/pages/authentication/error/error.component.ts b/theme/packages/starterkit/src/app/pages/authentication/error/error.component.ts new file mode 100644 index 0000000..f975566 --- /dev/null +++ b/theme/packages/starterkit/src/app/pages/authentication/error/error.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +@Component({ + selector: 'app-error', + imports: [RouterModule], + templateUrl: './error.component.html' +}) +export class AppErrorComponent {} diff --git a/theme/packages/starterkit/src/app/pages/authentication/side-login/side-login.component.html b/theme/packages/starterkit/src/app/pages/authentication/side-login/side-login.component.html new file mode 100644 index 0000000..9a98119 --- /dev/null +++ b/theme/packages/starterkit/src/app/pages/authentication/side-login/side-login.component.html @@ -0,0 +1,97 @@ +
+
+
+
+ + + + +
+ login +
+
+
+
+
+
+
+

Welcome to Modernize

+ Your Admin Dashboard + +
+
+ +
+
+ +
+
+ +
or sign in with
+ +
+ Username + + + @if(f['uname'].touched && f['uname'].invalid){ + + @if(f['uname'].errors && f['uname'].errors['required']){ +
+ Name is required. +
+ } + @if(f['uname'].errors && f['uname'].errors['minlength']){ +
+ Name should be 6 character. +
+ } +
+ } +
+ + + Password + + + @if(f['password'].touched && f['password'].invalid){ + + @if(f['password'].errors && f['password'].errors['required']){ +
+ Password is required. +
+ } +
+ } +
+ +
+ Remember this Device + Forgot Password ? +
+ + +
+ New to Modernize? + + Create an account + +
+
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/starterkit/src/app/pages/authentication/side-login/side-login.component.ts b/theme/packages/starterkit/src/app/pages/authentication/side-login/side-login.component.ts new file mode 100644 index 0000000..9da107c --- /dev/null +++ b/theme/packages/starterkit/src/app/pages/authentication/side-login/side-login.component.ts @@ -0,0 +1,32 @@ +import { Component } from '@angular/core'; +import { FormGroup, FormControl, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; +import { RouterModule } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { FormsModule } from '@angular/forms'; +import { ReactiveFormsModule } from '@angular/forms'; +import { BrandingComponent } from 'src/app/layouts/full/vertical/sidebar/branding.component'; + +@Component({ + selector: 'app-side-login', + imports: [RouterModule, MaterialModule, FormsModule, ReactiveFormsModule, BrandingComponent], + templateUrl: './side-login.component.html', +}) +export class AppSideLoginComponent { + + constructor( private router: Router) {} + + form = new FormGroup({ + uname: new FormControl('', [Validators.required, Validators.minLength(6)]), + password: new FormControl('', [Validators.required]), + }); + + get f() { + return this.form.controls; + } + + submit() { + // console.log(this.form.value); + this.router.navigate(['/starter']); + } +} diff --git a/theme/packages/starterkit/src/app/pages/authentication/side-register/side-register.component.html b/theme/packages/starterkit/src/app/pages/authentication/side-register/side-register.component.html new file mode 100644 index 0000000..d6957dc --- /dev/null +++ b/theme/packages/starterkit/src/app/pages/authentication/side-register/side-register.component.html @@ -0,0 +1,103 @@ +
+
+
+
+ + +
+ login +
+
+
+
+
+
+
+

Welcome to Modernize

+ Your Admin Dashboard + +
+
+ +
+
+ +
+
+ +
or sign up with
+ +
+ Name + + + @if(f['uname'].touched && f['uname'].invalid){ + + @if(f['uname'].errors && f['uname'].errors['required']){ +
+ Name is required. +
+ } + @if(f['uname'].errors && f['uname'].errors['minlength']){ +
+ Name should be 6 character. +
+ } +
+ } +
+ + Email Address + + + @if(f['email'].touched && f['email'].invalid){ + + @if(f['email'].errors && f['email'].errors['required']){ +
+ Email is required. +
+ } +
+ } +
+ + Password + + + @if(f['password'].touched && f['password'].invalid){ + + @if(f['password'].errors && f['password'].errors['required']){ +
+ Password is required. +
+ } +
+ } +
+ + + +
+ Already have an Account? + + + Sign In + +
+
+
+
+
+
\ No newline at end of file diff --git a/theme/packages/starterkit/src/app/pages/authentication/side-register/side-register.component.ts b/theme/packages/starterkit/src/app/pages/authentication/side-register/side-register.component.ts new file mode 100644 index 0000000..8a569f9 --- /dev/null +++ b/theme/packages/starterkit/src/app/pages/authentication/side-register/side-register.component.ts @@ -0,0 +1,34 @@ +import { Component } from '@angular/core'; +import { CoreService } from 'src/app/services/core.service'; +import { FormGroup, FormControl, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; +import { MaterialModule } from 'src/app/material.module'; +import { BrandingComponent } from 'src/app/layouts/full/vertical/sidebar/branding.component'; + +@Component({ + selector: 'app-side-register', + imports: [RouterModule, MaterialModule, FormsModule, ReactiveFormsModule, BrandingComponent], + templateUrl: './side-register.component.html', +}) +export class AppSideRegisterComponent { + options = this.settings.getOptions(); + + constructor(private settings: CoreService, private router: Router) {} + + form = new FormGroup({ + uname: new FormControl('', [Validators.required, Validators.minLength(6)]), + email: new FormControl('', [Validators.required]), + password: new FormControl('', [Validators.required]), + }); + + get f() { + return this.form.controls; + } + + submit() { + // console.log(this.form.value); + this.router.navigate(['/']); + } +} diff --git a/theme/packages/starterkit/src/app/pages/pages.routes.ts b/theme/packages/starterkit/src/app/pages/pages.routes.ts new file mode 100644 index 0000000..a2a0de4 --- /dev/null +++ b/theme/packages/starterkit/src/app/pages/pages.routes.ts @@ -0,0 +1,16 @@ +import { Routes } from '@angular/router'; +import { StarterComponent } from './starter/starter.component'; + +export const PagesRoutes: Routes = [ + { + path: '', + component: StarterComponent, + data: { + title: 'Starter Page', + urls: [ + { title: 'Dashboard', url: '/dashboards/dashboard1' }, + { title: 'Starter Page' }, + ], + }, + }, +]; diff --git a/theme/packages/starterkit/src/app/pages/starter/starter.component.html b/theme/packages/starterkit/src/app/pages/starter/starter.component.html new file mode 100644 index 0000000..38f4a50 --- /dev/null +++ b/theme/packages/starterkit/src/app/pages/starter/starter.component.html @@ -0,0 +1,155 @@ + + + + + + Sample Page + This is test page + +
+ + + + + + + + + + +
+ +
+ + + + + + + +
+
+
+ + + + Ordrinary Form + + +

this is test

+
+ + Email + + + We'll never share your email with anyone else. + + + Password + + + + + Check Me Out! +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
No.{{ element.position }}Name{{ element.name }}Weight{{ element.weight }}Symbol{{ element.symbol }}
+
+
+ + + + Chip + + + + + Photo of a Shiba Inu + Dog one + + + Photo of a Shiba Inu + Dog two + + + Photo of a Shiba Inu + Dog three + + + + diff --git a/theme/packages/starterkit/src/app/pages/starter/starter.component.scss b/theme/packages/starterkit/src/app/pages/starter/starter.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/starterkit/src/app/pages/starter/starter.component.ts b/theme/packages/starterkit/src/app/pages/starter/starter.component.ts new file mode 100644 index 0000000..34e13e8 --- /dev/null +++ b/theme/packages/starterkit/src/app/pages/starter/starter.component.ts @@ -0,0 +1,38 @@ +import { Component, ViewEncapsulation } from '@angular/core'; +import { MaterialModule } from 'src/app/material.module'; + + +export interface PeriodicElement { + name: string; + position: number; + weight: number; + symbol: string; +} + +const ELEMENT_DATA: PeriodicElement[] = [ + { position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' }, + { position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' }, + { position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' }, + { position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be' }, + { position: 5, name: 'Boron', weight: 10.811, symbol: 'B' }, + { position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C' }, + { position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N' }, + { position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O' }, + { position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F' }, + { position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne' }, +]; + + +@Component({ + selector: 'app-starter', + templateUrl: './starter.component.html', + imports: [MaterialModule], + styleUrls: ['./starter.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class StarterComponent { + + displayedColumns: string[] = ['position', 'name', 'weight', 'symbol']; + dataSource = ELEMENT_DATA; + +} diff --git a/theme/packages/starterkit/src/app/pipe/filter.pipe.ts b/theme/packages/starterkit/src/app/pipe/filter.pipe.ts new file mode 100644 index 0000000..207702b --- /dev/null +++ b/theme/packages/starterkit/src/app/pipe/filter.pipe.ts @@ -0,0 +1,18 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ name: 'appFilter', standalone: true, pure: true }) +export class FilterPipe implements PipeTransform { + transform(items: any[], searchText: string): any[] { + if (!items) { + return []; + } + if (!searchText) { + return items; + } + searchText = searchText.toLocaleLowerCase(); + + return items.filter((it) => { + return it.displayName.toLocaleLowerCase().includes(searchText); + }); + } +} diff --git a/theme/packages/starterkit/src/app/services/core.service.ts b/theme/packages/starterkit/src/app/services/core.service.ts new file mode 100644 index 0000000..72ee084 --- /dev/null +++ b/theme/packages/starterkit/src/app/services/core.service.ts @@ -0,0 +1,42 @@ +import { Injectable, signal } from '@angular/core'; +import { AppSettings, defaults } from '../config'; +import { BehaviorSubject, Observable } from 'rxjs'; + +@Injectable({ + providedIn: 'root', +}) +export class CoreService { + private optionsSignal = signal(defaults); + private notify$ = new BehaviorSubject>({}); + + constructor() { + this.notify$.next(this.optionsSignal()); + } + + // Observable for notification updates + get notify(): Observable> { + return this.notify$.asObservable(); + } + + // Get the current options + getOptions(): AppSettings { + return this.optionsSignal(); + } + + setOptions(options: Partial) { + this.optionsSignal.update((current) => ({ + ...current, + ...options, + })); + this.notify$.next(this.optionsSignal); + + } + + setLanguage(lang: string) { + this.setOptions({ language: lang }); + } + + getLanguage() { + return this.getOptions().language; + } +} diff --git a/theme/packages/starterkit/src/app/services/nav.service.ts b/theme/packages/starterkit/src/app/services/nav.service.ts new file mode 100644 index 0000000..93d7336 --- /dev/null +++ b/theme/packages/starterkit/src/app/services/nav.service.ts @@ -0,0 +1,17 @@ +import { Injectable, signal } from '@angular/core'; +import { Event, NavigationEnd, Router } from '@angular/router'; + +@Injectable({ providedIn: 'root' }) +export class NavService { + showClass: any = false; + + public currentUrl = signal(undefined); + + constructor(private router: Router) { + this.router.events.subscribe((event: Event) => { + if (event instanceof NavigationEnd) { + this.currentUrl.set(event.urlAfterRedirects); + } + }); + } +} diff --git a/theme/packages/starterkit/src/assets/.gitkeep b/theme/packages/starterkit/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/theme/packages/starterkit/src/assets/i18n/de.json b/theme/packages/starterkit/src/assets/i18n/de.json new file mode 100644 index 0000000..b00d7bf --- /dev/null +++ b/theme/packages/starterkit/src/assets/i18n/de.json @@ -0,0 +1,7 @@ +{ + "Starter": "Menüebene", + "Menu Level": "Menüebene", + "Menu 1": "Menü 1", + "Menu 2": "Menü 2", + "Disabled": "Behinderte" +} diff --git a/theme/packages/starterkit/src/assets/i18n/en.json b/theme/packages/starterkit/src/assets/i18n/en.json new file mode 100644 index 0000000..2911b85 --- /dev/null +++ b/theme/packages/starterkit/src/assets/i18n/en.json @@ -0,0 +1,7 @@ +{ + "Starter": "Starter", + "Menu Level": "Menu Level", + "Menu 1": "Menu 1", + "Menu 2": "Menu 2", + "Disabled": "Disabled" +} diff --git a/theme/packages/starterkit/src/assets/i18n/es.json b/theme/packages/starterkit/src/assets/i18n/es.json new file mode 100644 index 0000000..949bd8b --- /dev/null +++ b/theme/packages/starterkit/src/assets/i18n/es.json @@ -0,0 +1,7 @@ +{ + "Starter": "Analítica", + "Menu Level": "Nível do menu", + "Menu 1": "Menu 1", + "Menu 2": "Menu 2", + "Disabled": "Desabilitada" +} diff --git a/theme/packages/starterkit/src/assets/i18n/fr.json b/theme/packages/starterkit/src/assets/i18n/fr.json new file mode 100644 index 0000000..5700085 --- /dev/null +++ b/theme/packages/starterkit/src/assets/i18n/fr.json @@ -0,0 +1,7 @@ +{ + "Starter": "Analytique", + "Menu Level": "Niveau menu", + "Menu 1": "Menu 1", + "Menu 2": "Menu 2", + "Disabled": "Désactivé" +} diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/404-error-idea.gif b/theme/packages/starterkit/src/assets/images/backgrounds/404-error-idea.gif new file mode 100644 index 0000000..6f5bf86 Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/backgrounds/404-error-idea.gif differ diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/bronze.png b/theme/packages/starterkit/src/assets/images/backgrounds/bronze.png new file mode 100644 index 0000000..d0e5bfa Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/backgrounds/bronze.png differ diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/errorimg.svg b/theme/packages/starterkit/src/assets/images/backgrounds/errorimg.svg new file mode 100644 index 0000000..1f523c4 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/backgrounds/errorimg.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/gold.png b/theme/packages/starterkit/src/assets/images/backgrounds/gold.png new file mode 100644 index 0000000..bdc7ede Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/backgrounds/gold.png differ diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/login-bg.svg b/theme/packages/starterkit/src/assets/images/backgrounds/login-bg.svg new file mode 100644 index 0000000..b5b43a4 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/backgrounds/login-bg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/maintenance.svg b/theme/packages/starterkit/src/assets/images/backgrounds/maintenance.svg new file mode 100644 index 0000000..71eccf6 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/backgrounds/maintenance.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/maintenance2.svg b/theme/packages/starterkit/src/assets/images/backgrounds/maintenance2.svg new file mode 100644 index 0000000..260f07f --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/backgrounds/maintenance2.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/piggy.png b/theme/packages/starterkit/src/assets/images/backgrounds/piggy.png new file mode 100644 index 0000000..c8dcbfd Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/backgrounds/piggy.png differ diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/profilebg.jpg b/theme/packages/starterkit/src/assets/images/backgrounds/profilebg.jpg new file mode 100644 index 0000000..1b318aa Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/backgrounds/profilebg.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/silver.png b/theme/packages/starterkit/src/assets/images/backgrounds/silver.png new file mode 100644 index 0000000..818e736 Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/backgrounds/silver.png differ diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/track-bg.png b/theme/packages/starterkit/src/assets/images/backgrounds/track-bg.png new file mode 100644 index 0000000..429ffee Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/backgrounds/track-bg.png differ diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/unlimited-bg.png b/theme/packages/starterkit/src/assets/images/backgrounds/unlimited-bg.png new file mode 100644 index 0000000..501f5bb Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/backgrounds/unlimited-bg.png differ diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/website-under-construction.gif b/theme/packages/starterkit/src/assets/images/backgrounds/website-under-construction.gif new file mode 100644 index 0000000..5ff9a25 Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/backgrounds/website-under-construction.gif differ diff --git a/theme/packages/starterkit/src/assets/images/backgrounds/welcome-bg2.png b/theme/packages/starterkit/src/assets/images/backgrounds/welcome-bg2.png new file mode 100644 index 0000000..9b9ea3c Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/backgrounds/welcome-bg2.png differ diff --git a/theme/packages/starterkit/src/assets/images/breadcrumb/ChatBc.png b/theme/packages/starterkit/src/assets/images/breadcrumb/ChatBc.png new file mode 100644 index 0000000..ef22544 Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/breadcrumb/ChatBc.png differ diff --git a/theme/packages/starterkit/src/assets/images/breadcrumb/emailSv.png b/theme/packages/starterkit/src/assets/images/breadcrumb/emailSv.png new file mode 100644 index 0000000..3c01e85 Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/breadcrumb/emailSv.png differ diff --git a/theme/packages/starterkit/src/assets/images/flag/icon-flag-de.svg b/theme/packages/starterkit/src/assets/images/flag/icon-flag-de.svg new file mode 100644 index 0000000..efec2cb --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/flag/icon-flag-de.svg @@ -0,0 +1,10 @@ + + + ic_flag_cn + + + + + + + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/flag/icon-flag-en.svg b/theme/packages/starterkit/src/assets/images/flag/icon-flag-en.svg new file mode 100644 index 0000000..485ad5c --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/flag/icon-flag-en.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/flag/icon-flag-es.svg b/theme/packages/starterkit/src/assets/images/flag/icon-flag-es.svg new file mode 100644 index 0000000..8b517ff --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/flag/icon-flag-es.svg @@ -0,0 +1,10 @@ + + + ic_flag_sa + + + + + + + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/flag/icon-flag-fr.svg b/theme/packages/starterkit/src/assets/images/flag/icon-flag-fr.svg new file mode 100644 index 0000000..2ae63a1 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/flag/icon-flag-fr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/logos/dark-logo.svg b/theme/packages/starterkit/src/assets/images/logos/dark-logo.svg new file mode 100644 index 0000000..c0e674b --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/logos/dark-logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/theme/packages/starterkit/src/assets/images/logos/dark-rtl-logo.svg b/theme/packages/starterkit/src/assets/images/logos/dark-rtl-logo.svg new file mode 100644 index 0000000..afa324d --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/logos/dark-rtl-logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/starterkit/src/assets/images/logos/light-logo-rtl.svg b/theme/packages/starterkit/src/assets/images/logos/light-logo-rtl.svg new file mode 100644 index 0000000..1b3c4a6 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/logos/light-logo-rtl.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/starterkit/src/assets/images/logos/light-logo.svg b/theme/packages/starterkit/src/assets/images/logos/light-logo.svg new file mode 100644 index 0000000..0eb8718 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/logos/light-logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/starterkit/src/assets/images/profile/user-1.jpg b/theme/packages/starterkit/src/assets/images/profile/user-1.jpg new file mode 100644 index 0000000..e19df67 Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/profile/user-1.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/profile/user-10.jpg b/theme/packages/starterkit/src/assets/images/profile/user-10.jpg new file mode 100644 index 0000000..7d4531f Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/profile/user-10.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/profile/user-2.jpg b/theme/packages/starterkit/src/assets/images/profile/user-2.jpg new file mode 100644 index 0000000..52d8f1f Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/profile/user-2.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/profile/user-3.jpg b/theme/packages/starterkit/src/assets/images/profile/user-3.jpg new file mode 100644 index 0000000..2a541d7 Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/profile/user-3.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/profile/user-4.jpg b/theme/packages/starterkit/src/assets/images/profile/user-4.jpg new file mode 100644 index 0000000..e9312df Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/profile/user-4.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/profile/user-5.jpg b/theme/packages/starterkit/src/assets/images/profile/user-5.jpg new file mode 100644 index 0000000..ff2e6f0 Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/profile/user-5.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/profile/user-6.jpg b/theme/packages/starterkit/src/assets/images/profile/user-6.jpg new file mode 100644 index 0000000..867b150 Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/profile/user-6.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/profile/user-7.jpg b/theme/packages/starterkit/src/assets/images/profile/user-7.jpg new file mode 100644 index 0000000..df8e3fb Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/profile/user-7.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/profile/user-8.jpg b/theme/packages/starterkit/src/assets/images/profile/user-8.jpg new file mode 100644 index 0000000..facea41 Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/profile/user-8.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/profile/user-9.jpg b/theme/packages/starterkit/src/assets/images/profile/user-9.jpg new file mode 100644 index 0000000..9de110f Binary files /dev/null and b/theme/packages/starterkit/src/assets/images/profile/user-9.jpg differ diff --git a/theme/packages/starterkit/src/assets/images/svgs/facebook-icon.svg b/theme/packages/starterkit/src/assets/images/svgs/facebook-icon.svg new file mode 100644 index 0000000..c24d6ba --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/facebook-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/svgs/google-icon.svg b/theme/packages/starterkit/src/assets/images/svgs/google-icon.svg new file mode 100644 index 0000000..1307b69 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/google-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-account.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-account.svg new file mode 100644 index 0000000..da8f1a1 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-account.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-briefcase.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-briefcase.svg new file mode 100644 index 0000000..6bbd6d4 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-briefcase.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-connect.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-connect.svg new file mode 100644 index 0000000..0adb3ea --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-connect.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-dd-application.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-application.svg new file mode 100644 index 0000000..6adaa3c --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-application.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-dd-cart.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-cart.svg new file mode 100644 index 0000000..00b79fe --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-cart.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-dd-chat.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-chat.svg new file mode 100644 index 0000000..fdb1ad0 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-chat.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-dd-date.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-date.svg new file mode 100644 index 0000000..f56859c --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-date.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-dd-invoice.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-invoice.svg new file mode 100644 index 0000000..035cebf --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-invoice.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-dd-lifebuoy.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-lifebuoy.svg new file mode 100644 index 0000000..9d464e1 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-lifebuoy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-dd-message-box.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-message-box.svg new file mode 100644 index 0000000..f2d4d07 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-message-box.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-dd-mobile.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-mobile.svg new file mode 100644 index 0000000..66c22f0 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-dd-mobile.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-favorites.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-favorites.svg new file mode 100644 index 0000000..84fedaa --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-favorites.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-inbox.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-inbox.svg new file mode 100644 index 0000000..ebcb4ec --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-inbox.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-mailbox.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-mailbox.svg new file mode 100644 index 0000000..a4a3aa3 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-mailbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-master-card-2.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-master-card-2.svg new file mode 100644 index 0000000..4adbf06 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-master-card-2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-master-card.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-master-card.svg new file mode 100644 index 0000000..2ceeaad --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-master-card.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-office-bag-2.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-office-bag-2.svg new file mode 100644 index 0000000..8b7cbe1 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-office-bag-2.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-office-bag.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-office-bag.svg new file mode 100644 index 0000000..a7dedaa --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-office-bag.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-paypal.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-paypal.svg new file mode 100644 index 0000000..c17ed7f --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-paypal.svg @@ -0,0 +1,4 @@ + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-pie.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-pie.svg new file mode 100644 index 0000000..01d5297 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-pie.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-speech-bubble.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-speech-bubble.svg new file mode 100644 index 0000000..2e1f2bd --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-speech-bubble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-tasks.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-tasks.svg new file mode 100644 index 0000000..a6c280f --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-tasks.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/theme/packages/starterkit/src/assets/images/svgs/icon-user-male.svg b/theme/packages/starterkit/src/assets/images/svgs/icon-user-male.svg new file mode 100644 index 0000000..2832c4f --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/icon-user-male.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/svgs/mastercard.svg b/theme/packages/starterkit/src/assets/images/svgs/mastercard.svg new file mode 100644 index 0000000..3fdc683 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/mastercard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/images/svgs/paypal.svg b/theme/packages/starterkit/src/assets/images/svgs/paypal.svg new file mode 100644 index 0000000..41e02d5 --- /dev/null +++ b/theme/packages/starterkit/src/assets/images/svgs/paypal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/_container.scss b/theme/packages/starterkit/src/assets/scss/_container.scss new file mode 100644 index 0000000..c9a3f6a --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/_container.scss @@ -0,0 +1,153 @@ +@use "variables" as *; + +*, +:after, +:before { + box-sizing: border-box; +} + +body { + font-family: $font-family; + line-height: 1.334rem; + overflow-x: hidden; + color: var(--mat-sys-on-background); +} + +.mainWrapper { + display: flex; + min-height: 100vh; + width: 100%; + flex: 1; + height: 100%; +} + +.container { + max-width: 1200px; + padding-left: 24px; + padding-right: 24px; + margin: 0 auto; + + &.full-width { + display: flex; + align-items: center; + width: 100%; + } +} + +.pageWrapper { + padding: 24px; + min-height: calc(100vh - 70px); + + margin: 0 auto; + + &.maxWidth { + max-width: $boxedWidth; + } +} + +.w-100 { + width: 100%; +} + +.h-100 { + height: 100%; +} + +.shadow-none { + box-shadow: none !important; +} + +.rounded { + border-radius: $border-radius !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 25px !important; +} + +.overflow-hidden { + overflow: hidden; +} + +.text-decoration-none { + text-decoration: none; +} + +.position-relative { + position: relative; +} + +.table-responsive { + overflow-x: auto; + + td, + mat-cell { + white-space: nowrap; + padding: 16px; + } +} + +.op-5 { + opacity: 0.5; +} + +.cursor-pointer { + cursor: pointer; +} + +.avatar-group { + img { + border: 2px solid $white; + margin-right: -5px; + + &:last-child { + margin-right: 0; + } + } +} + +a { + color: var(--mat-sys-on-background); + + &:hover { + color: $primary; + } +} + +.filter-sidebar { + width: 290px; + position: fixed; + right: -290px; + top: 0; + z-index: 10; + height: 100%; + transition: all 0.3s ease-in-out; + box-shadow: var(--mat-sys-level3); + background-color: var(--mat-sys-background); + &.open { + right: 0; + } +} + +pre { + margin: 0; + white-space: nowrap; +} + +td.hljs-ln-line.hljs-ln-numbers { + padding-right: 10px; +} + +@media (min-width: 768px) { + html .flex-sm-row { + flex-direction: row !important; + } +} + +.mat-drawer[style*="visibility: hidden"] { + display: none; +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/_variables.scss b/theme/packages/starterkit/src/assets/scss/_variables.scss new file mode 100644 index 0000000..c06babd --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/_variables.scss @@ -0,0 +1,43 @@ +@import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap"); + +// font +$font-family: "Plus Jakarta Sans", sans-serif; + +// light color variable + +// Sidenav +$sidenav-desktop: 270px !default; +$sidenav-mini: 80px !default; +$header-height: 70px !default; + +//BorderColor +$borderColor: var(--mat-sys-outline-variant); +$borderformColor: var(--mat-sys-outline-variant); + +// custom +$primary: var(--mat-sys-primary); +$secondary: var(--mat-sys-secondary); +$accent: var(--mat-sys-secondary); +$error: var(--mat-sys-error); +$warning: #ffae1f; +$success: #13deb9; +$white: #ffffff; + +$light: var(--mat-sys-surface-bright); +$light-primary: var(--mat-sys-primary-fixed-dim); +$light-secondary: var(--mat-sys-secondary-fixed-dim); +$light-accent: var(--mat-sys-secondary-fixed-dim); +$light-error: var(--mat-sys-error-fixed-dim); +$light-warning: #ffad1f40; +$light-success: #13deb940; + +// layout +$boxedWidth: 1200px; +$border-radius: 7px; + +$card-spacer: 24px; + +$text-color: var(--mat-sys-on-background); + +$dark-text-secondary: rgba(255, 255, 255, 0.67); +$dark-body-bg: #141a21; diff --git a/theme/packages/starterkit/src/assets/scss/dark/_dark.scss b/theme/packages/starterkit/src/assets/scss/dark/_dark.scss new file mode 100644 index 0000000..b371092 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/dark/_dark.scss @@ -0,0 +1,68 @@ +@use "sass:meta"; +@use "../variables" as *; + +.dark-theme { + // typography + color: $dark-text-secondary; + + .mat-mdc-menu-panel { + color: var(--mat-sys-on-background) !important; + } + + .bg-white, + .mdc-menu-surface { + background-color: var(--mat-sys-surface) !important; + } + + .topbar { + background-color: var(--mat-sys-surface); + } + + .hljs { + background: var(--mat-sys-surface); + } + + // ------------------------------------------------------- + // border + // ------------------------------------------------------- + + .b-1 { + border: 1px solid var(--mat-sys-outline-variant) !important; + } + + .b-b-1 { + border-bottom: 1px solid var(--mat-sys-outline-variant) !important; + } + + .b-t-1 { + border-top: 1px solid var(--mat-sys-outline-variant) !important; + } + + .b-r-1 { + border-right: 1px solid var(--mat-sys-outline-variant) !important; + } + + .b-l-1 { + border-left: 1px solid var(--mat-sys-outline-variant); + } + + // fill + .customizer-button-group .mat-button-toggle-appearance-standard.mat-button-toggle-checked i-tabler.fill-icon { + fill: var(--mat-sys-primary-fixed-dim); + } + +} + +// horizontal + dark + +html.dark-theme { + .logodark { + display: none; + } +} + +html.light-theme { + .logolight { + display: none; + } +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/grid/_grid.scss b/theme/packages/starterkit/src/assets/scss/grid/_grid.scss new file mode 100644 index 0000000..bfbd802 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/grid/_grid.scss @@ -0,0 +1,35 @@ +@use 'variables'; +@use 'mixins'; + +.row { + display: flex; + flex-wrap: wrap; + margin-right: variables.$grid-gutter * -.5; + margin-left: variables.$grid-gutter * -.5; +} + +.no-gutters { + margin-right: 0; + margin-left: 0; + + > .col, + > [class*='col-'] { + padding-right: 0; + padding-left: 0; + } +} + +@include mixins.make-grid-columns(); + + +@each $breakpoint, $infix in variables.$breakpoint-infixs { + @if ($breakpoint== 'xsmall') { + @include mixins.loop-grid-columns(variables.$grid-columns, $infix); + } + + @else { + @include mixins.bp-gt($breakpoint) { + @include mixins.loop-grid-columns(variables.$grid-columns, $infix); + } + } +} diff --git a/theme/packages/starterkit/src/assets/scss/grid/_mixins.scss b/theme/packages/starterkit/src/assets/scss/grid/_mixins.scss new file mode 100644 index 0000000..dde3026 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/grid/_mixins.scss @@ -0,0 +1,79 @@ +@use 'sass:map'; +@use 'sass:math'; +@use 'variables'; + +@function bp($name, $breakpoints: variables.$breakpoints) { + $min: map.get($breakpoints, $name); + + @return $min; +} + +// Media of at least the minimum breakpoint width. +@mixin bp-gt($name, $breakpoints: variables.$breakpoints) { + $min: bp($name, $breakpoints); + + @if $min { + @media (min-width: $min) { + @content; + } + } + @else { + @content; + } +} + +// Media of at most the maximum breakpoint width. +@mixin bp-lt($name, $breakpoints: variables.$breakpoints) { + $max: bp($name, $breakpoints) - 1px; + + @if $max { + @media (max-width: $max) { + @content; + } + } + @else { + @content; + } +} + +@mixin make-grid-columns($i: 1, $list: '.col') { + @each $breakpoint, $infix in variables.$breakpoint-infixs { + $infix: if($infix == '', '', '-#{$infix}'); + + @if ($infix != '') { + $list: '#{$list}, .col#{$infix}'; + } + + @for $i from 1 through variables.$grid-columns { + $list: '#{$list}, .col#{$infix}-#{$i}'; + } + } + + #{$list} { + position: relative; + width: 100%; + padding-right: variables.$grid-gutter * .5; + padding-left: variables.$grid-gutter * .5; + } +} + +@mixin loop-grid-columns($columns: $grid-columns, $breakpoint-infix: '') { + $infix: if($breakpoint-infix == '', '', '-#{$breakpoint-infix}'); + + .col#{$infix} { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } + + @for $i from 1 through $columns { + .col#{$infix}-#{$i} { + flex: 0 0 math.percentage(math.div($i, $columns)); + max-width: math.percentage(math.div($i, $columns)); + } + + .offset#{$infix}-#{$i} { + margin-left: math.percentage(math.div($i, $columns)); + } + } +} diff --git a/theme/packages/starterkit/src/assets/scss/grid/_variables.scss b/theme/packages/starterkit/src/assets/scss/grid/_variables.scss new file mode 100644 index 0000000..2f3edbc --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/grid/_variables.scss @@ -0,0 +1,18 @@ +$grid-columns: 12 !default; +$grid-gutter: 30px !default; + +$breakpoints: ( + xsmall: 0, + small: 600px, + medium: 960px, + large: 1280px, + xlarge: 2100px +) !default; + +$breakpoint-infixs: ( + xsmall: '', + small: 'sm', + medium: 'md', + large: 'lg', + xlarge: 'xl' +) !default; \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_border-color.scss b/theme/packages/starterkit/src/assets/scss/helpers/_border-color.scss new file mode 100644 index 0000000..86197ad --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_border-color.scss @@ -0,0 +1,18 @@ +@use "../variables" as *; +@use "sass:meta"; // Import meta module for working with keyword arguments + +// Mixin to dynamically generate classes based on provided colors +@mixin syntax-colors2($args2...) { + @each $name2, $color2 in meta.keywords($args2) { + html .border-#{$name2} { + border: 1px solid #{$color2} !important; + } + } +} + +// Including the mixin with variables and CSS variables +@include syntax-colors2($primary: var(--mat-sys-primary), + $secondary: var(--mat-sys-secondary), + $success: $success, + $warning: $warning, + $error: var(--mat-sys-error)); \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_border.scss b/theme/packages/starterkit/src/assets/scss/helpers/_border.scss new file mode 100644 index 0000000..a1e0393 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_border.scss @@ -0,0 +1,32 @@ +@use 'variables'; + +$utilities: ( + 'border': ( + property: border, + class: b, + values: variables.$borders + ), + 'border-top': ( + property: border-top, + class: b-t, + values: variables.$borders + ), + 'border-bottom': ( + property: border-bottom, + class: b-b, + values: variables.$borders + ), + 'border-left': ( + property: border-left, + class: b-l, + values: variables.$borders + ), + 'border-right': ( + property: border-right, + class: b-r, + values: variables.$borders + ), + +); + + diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_color.scss b/theme/packages/starterkit/src/assets/scss/helpers/_color.scss new file mode 100644 index 0000000..45e559b --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_color.scss @@ -0,0 +1,37 @@ +@use "sass:meta"; +@use "../variables" as *; + +@mixin syntax-colors($args...) { + @each $name, $color in meta.keywords($args) { + html .bg-#{$name} { + background-color: $color !important; + } + + html .text-#{$name} { + color: $color !important; + } + } +} + +@include syntax-colors($primary: var(--mat-sys-primary), + $secondary: var(--mat-sys-secondary), + $success: $success, + $warning: $warning, + $error: var(--mat-sys-error), + $white: $white, + $light: $light, + $light-error: var(--mat-sys-error-fixed-dim), + $light-secondary: var(--mat-sys-secondary-fixed-dim), + $light-success: $light-success, + $light-warning: $light-warning, + $light-primary: var(--mat-sys-primary-fixed-dim)); + +.fill-warning svg { + fill: $warning; + color: $warning; +} + +.fill-light svg { + fill: $light; + color: $light; +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_custom-flex.scss b/theme/packages/starterkit/src/assets/scss/helpers/_custom-flex.scss new file mode 100644 index 0000000..69458d9 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_custom-flex.scss @@ -0,0 +1,54 @@ +@media (min-width: 1200px) { + body { + .d-lg-flex { + display: flex !important; + } + + .d-lg-none { + display: none !important; + } + .align-items-lg-center { + align-items: center !important; + } + } +} + +@media (min-width: 960px) { + .d-md-none { + display: none !important; + } +} + +@media (min-width: 768px) { + body { + .d-sm-flex { + display: flex !important; + } + } +} + +@media (max-width: 767px) { + .p-xs-6 { + padding: 0 6px !important; + } +} + +.flex-shrink-0 { + flex-shrink: 0; +} + +.flex-1-auto { + flex: 1 1 0%; +} + +.hstack { + display: flex; + flex-direction: row; + gap: 20px; +} + +@media (max-width: 767px) { + .hstack { + flex-direction: column; + } +} diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_display.scss b/theme/packages/starterkit/src/assets/scss/helpers/_display.scss new file mode 100644 index 0000000..ae8250e --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_display.scss @@ -0,0 +1,8 @@ +@use "variables"; + +$utilities: ( + "display": (property: display, + class: d, + values: inline inline-block block grid table table-row table-cell flex inline-flex none, + ), +); \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_flexbox.scss b/theme/packages/starterkit/src/assets/scss/helpers/_flexbox.scss new file mode 100644 index 0000000..d7d21d5 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_flexbox.scss @@ -0,0 +1,71 @@ +@use "variables"; + +$utilities: ( + "flex": (property: flex, + class: flex, + values: (fill: 1 1 auto, + ), + ), + "flex-direction": (property: flex-direction, + class: flex, + values: (row: row, + row-reverse: row-reverse, + col: column, + col-reverse: column-reverse, + ), + ), + "flex-grow": (property: flex-grow, + class: flex, + values: (grow-0: 0, + grow-1: 1, + ), + ), + "flex-shrink": (property: flex-shrink, + class: flex, + values: (shrink-0: 0, + shrink-1: 1, + ), + ), + "flex-wrap": (property: flex-wrap, + class: flex, + values: wrap nowrap wrap-reverse, + ), + "justify-content": (property: justify-content, + class: justify-content, + values: (start: flex-start, + end: flex-end, + center: center, + between: space-between, + around: space-around, + ), + ), + "align-content": (property: align-content, + class: align-content, + values: (start: flex-start, + end: flex-end, + center: center, + between: space-between, + around: space-around, + stretch: stretch, + ), + ), + "align-items": (property: align-items, + class: align-items, + values: (start: flex-start, + end: flex-end, + center: center, + baseline: baseline, + stretch: stretch, + ), + ), + "align-self": (property: align-self, + class: align-self, + values: (auto: auto, + start: flex-start, + end: flex-end, + center: center, + baseline: baseline, + stretch: stretch, + ), + ), +); \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_functions.scss b/theme/packages/starterkit/src/assets/scss/helpers/_functions.scss new file mode 100644 index 0000000..1c7dd6c --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_functions.scss @@ -0,0 +1,25 @@ +@use "sass:map"; + +// It makes the value negative. +@function negativify-map($map) { + $result: (); + + @each $key, $value in $map { + @if $key !=0 { + $result: map.merge($result, ("-" + $key: (-$value))); + } + } + + @return $result; +} + +// It allows to combine multiple maps together. +@function map-collect($maps...) { + $collection: (); + + @each $map in $maps { + $collection: map.merge($collection, $map); + } + + @return $collection; +} diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_icon-size.scss b/theme/packages/starterkit/src/assets/scss/helpers/_icon-size.scss new file mode 100644 index 0000000..e483077 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_icon-size.scss @@ -0,0 +1,15 @@ +@use "sass:meta"; + +$columns: 48; + +@mixin icon_size { + @for $i from 1 through $columns { + .icon-#{$i} { + height: #{$i}px !important; + width: #{$i}px !important; + line-height: #{$i + 8}px !important; + } + } +} + +@include icon_size; diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_index.scss b/theme/packages/starterkit/src/assets/scss/helpers/_index.scss new file mode 100644 index 0000000..3ca9bce --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_index.scss @@ -0,0 +1,108 @@ +@use "sass:map"; +@use "sass:meta"; +@use "sass:list"; +@use "variables"; + +@use "functions"; +@use "flexbox"; +@use "display"; +@use "border"; +@use "text"; +@use "spacing"; +@use "rounded"; + +$utilities: functions.map-collect(variables.$utilities, + display.$utilities, + flexbox.$utilities, + spacing.$utilities, + border.$utilities, + rounded.$utilities, + text.$utilities); + +@each $key, $utility in $utilities { + $values: map.get($utility, values); + + // If the values are a list or string, convert it into a map + @if meta.type-of($values)=="string" or meta.type-of(list.nth($values, 1)) !="list" + + { + $values: list.zip($values, $values); + } + + $properties: map.get($utility, property); + $property-class-prefix: map.get($utility, class); + + // Utility class maybe empty, (e.g. with position class) + $property-class-prefix-hyphen: if($property-class-prefix =="", + $property-class-prefix, + $property-class-prefix + "-" + ); + + @each $class-modifier, $value in $values { + .#{$property-class-prefix-hyphen + $class-modifier} { + @each $property in $properties { + #{$property}: $value !important; + } + } + } +} + +$ltrutilities: functions.map-collect(spacing.$ltr); + +@each $key, $utility in $ltrutilities { + $values: map.get($utility, values); + + // If the values are a list or string, convert it into a map + @if meta.type-of($values)=="string" or meta.type-of(list.nth($values, 1)) !="list" + + { + $values: list.zip($values, $values); + } + + $properties: map.get($utility, property); + $property-class-prefix: map.get($utility, class); + + // Utility class maybe empty, (e.g. with position class) + $property-class-prefix-hyphen: if($property-class-prefix =="", + $property-class-prefix, + $property-class-prefix + "-" + ); + + @each $class-modifier, $value in $values { + [dir="ltr"] .#{$property-class-prefix-hyphen + $class-modifier} { + @each $property in $properties { + #{$property}: $value !important; + } + } + } +} + +$rtlutilities: functions.map-collect(spacing.$rtl); + +@each $key, $utility in $rtlutilities { + $values: map.get($utility, values); + + // If the values are a list or string, convert it into a map + @if meta.type-of($values)=="string" or meta.type-of(list.nth($values, 1)) !="list" + + { + $values: list.zip($values, $values); + } + + $properties: map.get($utility, property); + $property-class-prefix: map.get($utility, class); + + // Utility class maybe empty, (e.g. with position class) + $property-class-prefix-hyphen: if($property-class-prefix =="", + $property-class-prefix, + $property-class-prefix + "-" + ); + + @each $class-modifier, $value in $values { + [dir="rtl"] .#{$property-class-prefix-hyphen + $class-modifier} { + @each $property in $properties { + #{$property}: $value !important; + } + } + } +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_rounded.scss b/theme/packages/starterkit/src/assets/scss/helpers/_rounded.scss new file mode 100644 index 0000000..9bbf013 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_rounded.scss @@ -0,0 +1,40 @@ +@use "variables"; + +$utilities: ( + "border-radius": (property: border-radius, + class: rounded, + values: variables.$radius, + ), + "border-top-left-radius": (property: border-top-left-radius, + class: r-t-l, + values: variables.$radius, + ), + "border-top-right-radius": (property: border-top-right-radius, + class: r-t-r, + values: variables.$radius, + ), + "border-bottom-right-radius": (property: border-bottom-right-radius, + class: r-b-r, + values: variables.$radius, + ), + "border-bottom-left-radius": (property: border-bottom-left-radius, + class: r-b-l, + values: variables.$radius, + ), + "border-top-radius": (property: border-top-left-radius border-top-right-radius, + class: r-t, + values: variables.$radius, + ), + "border-bottom-radius": (property: border-bottom-left-radius border-bottom-right-radius, + class: r-b, + values: variables.$radius, + ), + "border-left-radius": (property: border-top-left-radius border-bottom-left-radius, + class: r-l, + values: variables.$radius, + ), + "border-right-radius": (property: border-top-right-radius border-bottom-right-radius, + class: r-r, + values: variables.$radius, + ), +); \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_spacing.scss b/theme/packages/starterkit/src/assets/scss/helpers/_spacing.scss new file mode 100644 index 0000000..6d8a8f3 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_spacing.scss @@ -0,0 +1,136 @@ +@use "sass:map"; +@use "variables"; + +$utilities: ( + "margin": (property: margin, + class: m, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "margin-x": (property: margin-left margin-right, + class: m-x, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "margin-y": (property: margin-top margin-bottom, + class: m-y, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "margin-top": (property: margin-top, + class: m-t, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + + "margin-bottom": (property: margin-bottom, + class: m-b, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + + "negative-margin": (property: margin, + class: m, + values: variables.$negative-spacers, + ), + "negative-margin-x": (property: margin-left margin-right, + class: m-x, + values: variables.$negative-spacers, + ), + "negative-margin-y": (property: margin-top margin-bottom, + class: m-y, + values: variables.$negative-spacers, + ), + "negative-margin-top": (property: margin-top, + class: m-t, + values: variables.$negative-spacers, + ), + "negative-margin-right": (property: margin-right, + class: m-r, + values: variables.$negative-spacers, + ), + "negative-margin-bottom": (property: margin-bottom, + class: m-b, + values: variables.$negative-spacers, + ), + "negative-margin-left": (property: margin-left, + class: m-l, + values: variables.$negative-spacers, + ), + "padding": (property: padding, + class: p, + values: variables.$spacers, + ), + "padding-x": (property: padding-left padding-right, + class: p-x, + values: variables.$spacers, + ), + "padding-y": (property: padding-top padding-bottom, + class: p-y, + values: variables.$spacers, + ), + "padding-top": (property: padding-top, + class: p-t, + values: variables.$spacers, + ), + + "padding-bottom": (property: padding-bottom, + class: p-b, + values: variables.$spacers, + ), + "gap": (property: gap, + class: gap, + values: variables.$spacers, + ), +); + +$ltr: ( + "margin-right": (property: margin-right, + class: m-r, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "margin-left": (property: margin-left, + class: m-l, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "padding-left": (property: padding-left, + class: p-l, + values: variables.$spacers, + ), + "padding-right": (property: padding-right, + class: p-r, + values: variables.$spacers, + ), +); + +$rtl: ( + "margin-right": (property: margin-left, + class: m-r, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "margin-left": (property: margin-right, + class: m-l, + values: map.merge(variables.$spacers, + (auto: auto, + )), + ), + "padding-left": (property: padding-right, + class: p-l, + values: variables.$spacers, + ), + "padding-right": (property: padding-left, + class: p-r, + values: variables.$spacers, + ), +); \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_text.scss b/theme/packages/starterkit/src/assets/scss/helpers/_text.scss new file mode 100644 index 0000000..5fef9f5 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_text.scss @@ -0,0 +1,80 @@ +@use "sass:map"; +@use "variables"; + +$utilities: ( + "font-size": ( + property: font-size, + class: f-s, + values: variables.$font-sizes, + ), + "font-weight": ( + property: font-weight, + class: f-w, + values: variables.$font-wieghts, + ), + "font-style": ( + property: font-style, + class: font, + values: italic normal, + ), + "text-align": ( + property: text-align, + class: text, + values: center right left, + ), + "text-decoration": ( + property: text-decoration, + class: text, + values: none underline line-through, + ), + "text-transform": ( + property: text-transform, + class: text, + values: capitalize uppercase lowercase, + ), + "white-space": ( + property: white-space, + class: text, + values: ( + wrap: normal, + nowrap: nowrap, + ), + ), + "word-wrap": ( + property: word-wrap word-break, + class: text, + values: ( + break: break-word, + ), + ), + "text-overflow": ( + property: text-overflow, + class: text, + values: ellipsis, + ), + "text-color": ( + property: color, + class: text, + values: ( + reset: inherit, + current: currentColor, + ), + ), +); + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0px; +} + +.lh-lg { + line-height: 36px !important; +} + +.lh-sm { + line-height: 20px !important; +} diff --git a/theme/packages/starterkit/src/assets/scss/helpers/_variables.scss b/theme/packages/starterkit/src/assets/scss/helpers/_variables.scss new file mode 100644 index 0000000..b0d0806 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/helpers/_variables.scss @@ -0,0 +1,94 @@ +@use "functions" as *; + +// Utility Map + +$utilities: () !default; + +// Spacing + +$spacer: 16px !default; +$spacers: ( + 0: 0, + 2: $spacer * 0.125, + 4: $spacer * 0.25, + 5: 5px, + 6: 7px, + 8: $spacer * 0.5, + 10: 10px, + 12: $spacer * 0.75, + 14: 14px, + 15: 15px, + 16: $spacer, + 20: 20px, + 24: $spacer * 1.5, + 30: 30px, + 32: $spacer * 2, + 48: $spacer * 3, +) !default; +$negative-spacers: negativify-map($spacers) !default; + +// Border + +$border-color: var(--mat-sys-outline-variant) !default; +$borders: ( + 0: 0, + 1: 1px solid $border-color, + 2: 2px solid $border-color, + 4: 4px solid $border-color, + 8: 8px solid $border-color, +) !default; + +// Border radius + +$radius-base: 7px !default; +$radius: ( + 0: 0, + 7: $radius-base, + 8: $radius-base * 2, + 12: $radius-base * 3, + 16: $radius-base * 4, + full: 9999px, +) !default; + +// Text + +$font-wieghts: ( + 100: 100, + 200: 200, + 300: 300, + 400: 400, + 500: 500, + 600: 600, + 700: 700, + 800: 800, + 900: 900, +) !default; + +$font-sizes: ( + 0: 0, + 10: 10px, + 12: 12px, + 14: 14px, + 15: 15px, + 16: 16px, + 18: 18px, + 20: 20px, + 21: 21px, + 24: 24px, + 30: 30px, +) !default; + +// Sizing + +$sizes: ( + 0: 0, + 20: 20%, + 25: 25%, + 40: 40%, + 50: 50%, + 60: 60%, + 75: 75%, + 80: 80%, + full: 100%, + auto: auto, +) !default; diff --git a/theme/packages/starterkit/src/assets/scss/horizontal/_horizontal.scss b/theme/packages/starterkit/src/assets/scss/horizontal/_horizontal.scss new file mode 100644 index 0000000..57658c5 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/horizontal/_horizontal.scss @@ -0,0 +1,208 @@ +@use "../variables" as *; + +.sidebarNav-horizontal { + .childBox { + background: var(--mat-sys-surface); + } + + // header + .horizontal-topbar { + box-shadow: var(--mat-sys-level2); + + .branding { + padding-left: 0; + } + + .container { + max-width: $boxedWidth; + display: flex; + align-items: center; + width: 100%; + } + } + + // sidebar + .horizontal-navbar { + position: relative; + gap: 3px !important; + + .parentBox { + position: relative; + z-index: 5; + margin: 5px 0; + + &.mega-menu { + position: static; + + &:hover { + >.childBox>.ddmenu { + display: inline-block; + } + } + + >.childBox { + width: 100%; + left: 0; + + >.ddmenu { + width: 24%; + } + } + } + + &.two-column { + &:hover { + >.childBox>.ddmenu { + display: inline-block; + } + } + + >.childBox { + width: 600px; + + >.ddmenu { + width: 49%; + border-radius: $border-radius; + } + } + } + + .menuLink { + padding: 10px; + border-radius: $border-radius; + display: flex; + align-items: center; + height: 40px; + gap: 10px; + font-size: 14px; + } + + &:hover>.menuLink { + background-color: var(--mat-sys-surface-bright); + } + + &:hover>.activeMenu, + .activeMenu { + color: $white !important; + background-color: $primary; + } + + .down-icon .mat-icon { + width: 18px; + height: 18px; + font-size: 18px; + } + + .childBox { + border-radius: $border-radius; + box-shadow: var(--mat-sys-level1); + position: absolute; + width: 250px; + background-color: var(--mat-sys-surface); + + .ddmenu { + display: none; + padding: 10px; + margin: 6px; + position: relative; + border-radius: $border-radius; + } + } + + &:hover>.childBox>.ddmenu:hover { + background-color: var(--mat-sys-surface-bright); + + &:hover>.childBox>.ddmenu:hover { + background-color: var(--mat-sys-surface-bright); + } + } + + &:hover>.childBox>.ddmenu:hover>.childBox { + left: 230px; + top: 0px; + z-index: 9; + + >.ddmenu:hover>.childBox { + left: 235px; + top: 0; + } + } + + &:hover>.childBox>.ddmenu { + display: block; + padding: 0; + + &:hover>.childBox>.ddmenu { + display: block; + padding: 0; + + &:hover>.childBox>.ddmenu { + display: block; + padding: 0; + } + } + } + } + } +} + +.sidebarNav-horizontal { + + .topbar, + .mainWrapper { + width: 100%; + } + + .horizontal-navbar { + .parentBox { + + &.pactive>a, + &.pactive>a:hover, + &.pactive:hover>a { + background-color: var(--mat-sys-primary); + color: $white !important; + border-radius: $border-radius; + } + } + } +} + +.ltr { + .sidebarNav-horizontal { + .horizontal-navbar { + .parentBox { + &:last-child:hover>.childBox>.ddmenu { + &:hover>.childBox { + right: 250px; + left: unset; + + >.ddmenu:hover>.childBox { + right: 250px; + left: unset; + } + } + } + } + } + } +} + +.rtl { + .sidebarNav-horizontal { + .horizontal-navbar { + .parentBox { + &:last-child:hover>.childBox>.ddmenu { + &:hover>.childBox { + left: 250px; + right: unset; + + >.ddmenu:hover>.childBox { + left: 250px; + right: unset; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/layouts/_breacrumb.scss b/theme/packages/starterkit/src/assets/scss/layouts/_breacrumb.scss new file mode 100644 index 0000000..28a6c54 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/layouts/_breacrumb.scss @@ -0,0 +1,33 @@ +@use "../variables" as *; + +.breadcrumb-icon { + position: absolute; + top: -20px; + right: 19px; +} + +.breadcrumb { + list-style: none; + margin: 0; + padding: 0px; + display: flex; +} + +.breadcrumb-item { + padding: 0 10px 0 0; + + &:first-child { + &::marker { + display: none; + } + } + + a { + text-decoration: none; + font-size: 14px; + + &:hover { + color: $primary; + } + } +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/layouts/_customizer.scss b/theme/packages/starterkit/src/assets/scss/layouts/_customizer.scss new file mode 100644 index 0000000..86bb076 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/layouts/_customizer.scss @@ -0,0 +1,117 @@ +@use "../variables" as *; + +html .customizerNav { + border-radius: 0px !important; +} + +.customizer-button-group { + &.two-row { + display: inline-block; + + &.theme-colors { + .mat-button-toggle-appearance-standard { + margin-left: 16px; + + &:first-child { + margin-left: 0; + } + } + } + + .mat-button-toggle-appearance-standard { + width: 80px; + height: 65px; + float: left; + display: flex; + align-items: center; + margin-bottom: 16px; + + .mat-button-toggle-button { + display: flex; + justify-content: center; + } + + &:nth-child(4) { + margin-left: 0; + } + + &.mat-button-toggle-checked { + .theme-circle { + .theme-icon { + display: flex; + color: $white; + } + } + } + + .theme-circle { + width: 25px; + height: 25px; + border-radius: var(--mat-sys-corner-full); + color: $white; + display: flex; + align-items: center; + justify-content: center; + + .theme-icon { + display: none; + } + + &.orange_theme { + background-color: rgb(250, 137, 107); + } + + &.blue_theme { + background-color: rgb(93, 135, 255); + } + + &.aqua_theme { + background-color: rgb(0, 116, 186); + } + + &.purple_theme { + background-color: rgb(118, 62, 189); + } + + &.green_theme { + background-color: rgb(10, 126, 164); + } + + &.cyan_theme { + background-color: rgb(1, 192, 200); + } + } + } + } + + .mat-button-toggle-appearance-standard { + padding: 9px; + border: 1px solid var(--mat-sys-outline-variant) !important; + box-shadow: none; + border-radius: $border-radius; + transition: all 0.1s ease-in 0s; + + &:hover { + transform: scale(1.05); + } + + &.mat-button-toggle-checked { + background-color: var(--mat-sys-primary-fixed-dim); + + i-tabler.fill-icon { + color: var(--mat-sys-primary); + fill: var(--mat-sys-on-primary); + } + } + } + + &.mat-button-toggle-group { + overflow: unset; + border-radius: 0; + } + + .mat-button-toggle-standalone.mat-button-toggle-appearance-standard, + &.mat-button-toggle-group-appearance-standard { + border: 0 !important; + } +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/layouts/_header.scss b/theme/packages/starterkit/src/assets/scss/layouts/_header.scss new file mode 100644 index 0000000..d24e1f8 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/layouts/_header.scss @@ -0,0 +1,64 @@ +@use "../variables" as *; + +html .topbar { + position: sticky; + top: 0; + z-index: 9; + height: $header-height; + + .notification-badge{ + .mat-badge-content{ + left: 80%; + bottom: 85%; + width: 16px; + height: 16px; + } + } +} + +.topbar-dd { + min-width: 360px !important; +} + +.apps-dd { + min-width: 830px !important; + overflow: unset !important; + + .mat-mdc-menu-content { + padding: 0; + } +} + +.text-hover-primary:hover { + .hover-text { + color: $primary; + } +} + +.upgrade-bg { + position: absolute; + top: 0px; + right: 0px; + height: 100%; +} + +.object-cover { + object-fit: cover; +} + +.profile-dd { + margin-top: -5px; + margin-left: -5px; +} + +.dark-theme { + .topbar { + .mat-mdc-icon-button { + color: $dark-text-secondary !important; + } + + .mdc-button { + --mat-button-text-label-text-color: $dark-text-secondary !important; + } + } +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/layouts/_layouts.scss b/theme/packages/starterkit/src/assets/scss/layouts/_layouts.scss new file mode 100644 index 0000000..c56764a --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/layouts/_layouts.scss @@ -0,0 +1,4 @@ +@use "sidebar"; +@use "header"; +@use "customizer"; +@use "breacrumb"; \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/layouts/_sidebar.scss b/theme/packages/starterkit/src/assets/scss/layouts/_sidebar.scss new file mode 100644 index 0000000..1c9c1f8 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/layouts/_sidebar.scss @@ -0,0 +1,210 @@ +@use "../variables" as *; + +.mat-drawer.sidebarNav { + width: $sidenav-desktop; + flex-shrink: 0; + transition: swift-ease-out(width); + position: absolute; + overflow-x: hidden; + border-right: 1px solid $borderColor; + border-radius: 0px !important; +} + +.branding { + padding: 20px; +} + +.sidebarNav-mini { + .sidebarNav { + width: $sidenav-mini; + + .profile-bar { + display: none; + } + + .sidebar-list { + .menu-list-item { + padding: 8px 17px; + + .mdc-list-item__content { + display: none; + } + + .mdc-list-item__start { + margin-left: 6px !important; + margin-right: 8px !important; + } + } + } + + &:hover { + width: $sidenav-desktop; + + .profile-bar { + display: block; + } + + .sidebar-list { + .menu-list-item { + padding: 8px 10px; + + .mdc-list-item__content { + display: inline; + } + + .mdc-list-item__start { + margin-left: 0 !important; + } + } + + &.mdc-list { + padding: 0 24px; + max-width: $sidenav-desktop; + + .mdc-list-group__subheader { + text-align: left; + } + } + } + } + } + + .hideMenu { + overflow: hidden; + width: $sidenav-mini; + } + + .branding { + width: $sidenav-mini - 15px; + overflow: hidden; + } + + .sidebar-list { + &.mdc-list { + padding: 0 12px; + + .mdc-list-group__subheader { + text-align: center; + } + } + } + + .contentWrapper { + transition: swift-ease-out(width); + } +} + +@media (min-width: 1024px) { + .sidebarNav-mini { + .contentWrapper { + margin-left: $sidenav-mini !important; + } + } +} + +.customizerBtn { + position: fixed; + right: 30px; + bottom: 30px; + z-index: 9; +} + +.sidebar-list { + &.mdc-list { + padding: 0 24px; + + .mdc-list-group__subheader { + margin: 12px 0; + text-transform: uppercase; + font-size: 0.75rem; + font-weight: 700; + margin-top: 24px; + } + + .menu-list-item { + height: 45px; + padding: 8px 10px !important; + margin-bottom: 2px; + + &.twoline { + height: 60px; + align-items: center; + } + + &:before, + &:focus { + z-index: -1; + } + + &.disabled { + opacity: 0.38; + } + + .item-chip { + height: 24px; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; + } + + &.activeMenu { + background-color: var(--mat-sys-primary); + + .mdc-list-item__primary-text { + color: $white !important; + } + + .mat-mdc-list-item-icon { + color: $white !important; + } + } + + .mdc-list-item__start { + margin-right: 14px; + margin-left: 0 !important; + width: 20px; + height: 20px; + line-height: 0px; + fill: transparent !important; + } + + .mdc-list-item__primary-text { + display: flex; + align-items: center; + justify-content: space-between; + + .arrow-icon { + display: flex; + + .mat-icon { + font-size: 18px; + width: 18px; + height: 18px; + display: flex; + align-items: center; + justify-content: center; + } + } + } + } + } +} + +.sidebar-list .top-parent .menu-list-item.activemenu { + background-color: color-mix(in srgb, var(--mat-sys-primary) 10%, transparent); + + .mdc-list-item__primary-text { + color: var(--mat-sys-primary) !important; + } + + .mat-mdc-list-item-icon { + color: var(--mat-sys-primary) !important; + } +} + +.flex-layout { + display: flex; + flex-direction: column; + height: 100%; +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/layouts/_transitions.scss b/theme/packages/starterkit/src/assets/scss/layouts/_transitions.scss new file mode 100644 index 0000000..fdc42bc --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/layouts/_transitions.scss @@ -0,0 +1,17 @@ +$swift-ease-out-duration: 400ms; +$swift-ease-out-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1); + +@function swift-ease-out($property) { + // The Material default animation curves. + $transition: $property $swift-ease-out-duration + $swift-ease-out-timing-function; + + @return $transition; +} + +@function fast-out-slow($property) { + // The Material default animation curves. + $transition: $property 225ms cubic-bezier(0.4, 0, 0.2, 1); + + @return $transition; +} diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_badge.scss b/theme/packages/starterkit/src/assets/scss/override-component/_badge.scss new file mode 100644 index 0000000..cb94c06 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_badge.scss @@ -0,0 +1,7 @@ +@use "sass:map"; +@use "@angular/material" as mat; +@include mat.badge-overrides( + ( + background-color: var(--mat-sys-primary), + ) +); diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_button-toggle.scss b/theme/packages/starterkit/src/assets/scss/override-component/_button-toggle.scss new file mode 100644 index 0000000..bdd2d6d --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_button-toggle.scss @@ -0,0 +1,9 @@ +@use "sass:map"; +@use "@angular/material" as mat; +@use "../variables" as *; + +@include mat.button-toggle-overrides( + ( + shape: $border-radius, + ) +); diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_button.scss b/theme/packages/starterkit/src/assets/scss/override-component/_button.scss new file mode 100644 index 0000000..f85ed5a --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_button.scss @@ -0,0 +1,136 @@ +@use "sass:map"; +@use "@angular/material" as mat; +@use "../variables" as *; + +@include mat.button-overrides( + ( + protected-hover-container-elevation-shadow: var(--mat-sys-level1), + filled-horizontal-padding: 15px, + outlined-horizontal-padding: 15px, + protected-horizontal-padding: 15px, + text-horizontal-padding: 15px, + filled-container-shape: var(--mat-sys-corner-small), + outlined-container-shape: var(--mat-sys-corner-small), + protected-container-shape: var(--mat-sys-corner-small), + text-container-shape: var(--mat-sys-corner-small), + ) +); + +@include mat.icon-button-overrides( + ( + icon-color: $text-color, + ) +); + +// styles +html { + .mat-mdc-button-base.bg-light-primary:hover, + .mat-mdc-button-base.bg-light-secondary:hover, + .mat-mdc-button-base.bg-light-error:hover, + .mat-mdc-button-base.bg-light-warning:hover, + .mat-mdc-button-base.bg-light-success:hover { + color: $white !important; + } + + .mat-mdc-button-base.bg-light-primary { + &:hover { + background-color: var(--mat-sys-primary) !important; + } + } + + .mat-mdc-button-base.bg-light-secondary { + &:hover { + background-color: var(--mat-sys-secondary) !important; + } + } + + .mat-mdc-button-base.bg-light-error { + &:hover { + background-color: var(--mat-sys-error) !important; + } + } + + .mat-mdc-button-base.bg-light-warning { + &:hover { + background-color: $warning !important; + } + } + + .mat-mdc-button-base.bg-light-success { + &:hover { + background-color: $success !important; + } + } + + .mat-mdc-outlined-button:not(:disabled) { + border-color: inherit !important; + } + + .mat-mdc-button-base.text-secondary:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $secondary; + } + } + + .mat-mdc-button-base.text-error:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $error; + } + } + + .mat-mdc-button-base.text-warning:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $warning; + } + } + + .mat-mdc-button-base.text-success:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $success; + } + } + + .mat-mdc-outlined-button:not(:disabled).mat-secondary { + color: var(--mat-sys-secondary); + border-color: var(--mat-sys-secondary); + + &:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $secondary; + } + } + } + + .mat-mdc-outlined-button:not(:disabled).mat-success { + color: $success; + border-color: $success; + + &:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $success; + } + } + } + + .mat-mdc-outlined-button:not(:disabled).mat-error { + color: $error; + border-color: $error; + + &:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $error; + } + } + } + + .mat-mdc-outlined-button:not(:disabled).mat-warning { + color: $warning; + border-color: $warning; + + &:hover { + .mat-mdc-button-persistent-ripple::before { + background-color: $warning; + } + } + } +} diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_card.scss b/theme/packages/starterkit/src/assets/scss/override-component/_card.scss new file mode 100644 index 0000000..660e579 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_card.scss @@ -0,0 +1,60 @@ +@use "sass:map"; +@use "@angular/material" as mat; +@use "../variables" as *; + +@include mat.card-overrides( + ( + elevated-container-color: $white, + title-text-size: 1.125rem, + subtitle-text-size: 14px, + title-text-line-height: 1.6rem, + title-text-weight: 600, + subtitle-text-weight: 400, + elevated-container-shape: var(--mat-sys-corner-small), + outlined-container-shape: var(--mat-sys-corner-small), + elevated-container-elevation: var(--mat-sys-level2), + ) +); + +// styles +html { + .mat-mdc-card { + margin-bottom: $card-spacer; + + .mat-mdc-card-header { + padding: $card-spacer $card-spacer 0 !important; + } + + .mat-mdc-card-header + .mat-mdc-card-content { + padding: 0 $card-spacer $card-spacer; + } + + > .mat-mdc-card-content { + padding: $card-spacer !important; + } + + .mdc-card__actions { + padding: $card-spacer !important; + } + } + + .card-hover { + transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &:hover { + scale: 1.01; + transition: all 0.1s ease-in 0s; + } + } + + .cardBorder { + .mdc-card { + box-shadow: none !important; + border: 1px solid $borderColor !important; + + &.shadow-none { + border: 0 !important; + } + } + } +} diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_checkbox.scss b/theme/packages/starterkit/src/assets/scss/override-component/_checkbox.scss new file mode 100644 index 0000000..eba7679 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_checkbox.scss @@ -0,0 +1,23 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.checkbox-overrides( + ( + unselected-focus-icon-color: + var(--mat-checkbox-unselected-hover-state-layer-color), + ) +); + +// styles +html { + .mdc-checkbox__background { + border-radius: 4px; + width: 21px; + height: 21px; + border: 1px solid var(--mat-sys-outline); + } + + .mdc-checkbox .mdc-checkbox__native-control:focus ~ .mdc-checkbox__ripple { + background-color: var(--mat-checkbox-unselected-hover-state-layer-color); + } +} diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_chip.scss b/theme/packages/starterkit/src/assets/scss/override-component/_chip.scss new file mode 100644 index 0000000..6aabfd0 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_chip.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.chips-overrides( + ( + focus-state-layer-color: var(--mat-option-focus-state-layer-color), + ) +); diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_dialog.scss b/theme/packages/starterkit/src/assets/scss/override-component/_dialog.scss new file mode 100644 index 0000000..1dee46e --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_dialog.scss @@ -0,0 +1,15 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.dialog-overrides( + ( + container-shape: var(--mat-sys-corner-small), + subhead-size: 18px, + subhead-weight: 600, + content-padding: 20px 24px, + actions-padding: 20px 24px, + container-min-width: 300px, + subhead-tracking: unset, + supporting-text-tracking: unset, + ) +); diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_drawer.scss b/theme/packages/starterkit/src/assets/scss/override-component/_drawer.scss new file mode 100644 index 0000000..1ed3a41 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_drawer.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.sidenav-overrides( + ( + container-shape: 0, + ) +); diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_fab.scss b/theme/packages/starterkit/src/assets/scss/override-component/_fab.scss new file mode 100644 index 0000000..77b39ed --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_fab.scss @@ -0,0 +1,15 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.fab-overrides( + ( + small-container-shape: 30px, + container-shape: 30px, + container-elevation-shadow: none, + small-container-elevation-shadow: none, + small-hover-container-elevation-shadow: var(--mat-sys-level3), + hover-container-elevation-shadow: var(--mat-sys-level3), + extended-hover-container-elevation-shadow: var(--mat-sys-level3), + extended-container-elevation-shadow: none, + ) +); diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_form-field.scss b/theme/packages/starterkit/src/assets/scss/override-component/_form-field.scss new file mode 100644 index 0000000..a1eda9b --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_form-field.scss @@ -0,0 +1,27 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.form-field-overrides( + ( + container-height: 37px, + outlined-container-shape: var(--mat-sys-corner-small), + container-vertical-padding: 6px, + ) +); + +// forms +html { + .hide-hint { + .mat-mdc-form-field-subscript-wrapper { + display: none; + } + } + + .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label { + top: calc(var(--mat-form-field-container-height) / 2.15); + } + + .demo-inline-calendar-card { + width: 300px; + } +} diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_index.scss b/theme/packages/starterkit/src/assets/scss/override-component/_index.scss new file mode 100644 index 0000000..6645776 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_index.scss @@ -0,0 +1,15 @@ +@use "badge"; +@use "button"; +@use "button-toggle"; +@use "card"; +@use "checkbox"; +@use "chip"; +@use "dialog"; +@use "fab"; +@use "form-field"; +@use "list"; +@use "menu"; +@use "theme"; +@use "table"; +@use "typography"; +@use "drawer"; diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_list.scss b/theme/packages/starterkit/src/assets/scss/override-component/_list.scss new file mode 100644 index 0000000..de39959 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_list.scss @@ -0,0 +1,12 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.list-overrides( + ( + list-item-hover-state-layer-color: var(--mat-sys-primary), + list-item-container-shape: var(--mat-sys-corner-small), + active-indicator-shape: var(--mat-sys-corner-small), + list-item-two-line-container-height: 70px, + list-item-three-line-container-height: 100px, + ) +); diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_menu.scss b/theme/packages/starterkit/src/assets/scss/override-component/_menu.scss new file mode 100644 index 0000000..32a6e73 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_menu.scss @@ -0,0 +1,19 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.menu-overrides( + ( + container-shape: var(--mat-sys-corner-small), + ) +); + +// styles +html { + .mat-mdc-menu-panel { + box-shadow: var(--mat-sys-level3) !important; + } + + .mat-mdc-select-panel { + padding: 8px !important; + } +} diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_table.scss b/theme/packages/starterkit/src/assets/scss/override-component/_table.scss new file mode 100644 index 0000000..379ddcd --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_table.scss @@ -0,0 +1,8 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@include mat.table-overrides( + ( + background-color: var(--mat-card-elevated-container-color), + ) +); diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_theme.scss b/theme/packages/starterkit/src/assets/scss/override-component/_theme.scss new file mode 100644 index 0000000..e840626 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_theme.scss @@ -0,0 +1,25 @@ +@use "sass:map"; +@use "@angular/material" as mat; +@use "../variables" as *; + +html { + @include mat.theme( + ( + color: mat.$azure-palette, + typography: $font-family, + ) + ); + + @include mat.theme-overrides( + ( + primary: rgb(93, 135, 255), + error: rgb(250, 137, 107), + body-medium-size: 14px, + body-large-size: 14px, + outline-variant: #d7dde2, + level1: 0px 12px 24px -4px rgb(145 158 171 / 30%), + level2: rgba(145, 158, 171, 0.12) 0px 1px 16px, + level3: 0px 12px 24px -4px rgb(145 158 171 / 30%), + ) + ); +} diff --git a/theme/packages/starterkit/src/assets/scss/override-component/_typography.scss b/theme/packages/starterkit/src/assets/scss/override-component/_typography.scss new file mode 100644 index 0000000..c65fc04 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/override-component/_typography.scss @@ -0,0 +1,9 @@ +@use "../variables" as *; +html { + .mdc-list-item__primary-text, + .mat-drawer-container, + .mat-drawer, + .text-body { + color: $text-color; + } +} diff --git a/theme/packages/starterkit/src/assets/scss/pages/_auth.scss b/theme/packages/starterkit/src/assets/scss/pages/_auth.scss new file mode 100644 index 0000000..1b51841 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/pages/_auth.scss @@ -0,0 +1,109 @@ +@use "../variables" as *; + +.blank-layout-container { + height: 100vh; + display: flex; + background-size: cover; + align-items: center; +} + +.auth-title { + font-size: 36px; + line-height: 44px; +} + +.bg-gredient { + &::before { + content: ""; + position: absolute; + height: 100%; + width: 100%; + opacity: 0.3; + background: radial-gradient(rgb(210, 241, 223), + rgb(211, 215, 250), + rgb(186, 216, 244)) 0% 0% / 400% 400%; + animation: 15s ease 0s infinite normal none running gradient; + z-index: -1; + } +} + +@keyframes gradient { + 0% { + background-position: 0% 50%; + } + + 50% { + background-position: 100% 50%; + } + + 100% { + background-position: 50% 0%; + } +} + +.img-height { + height: calc(100vh - 83px); +} + +.custom-row { + &.row { + margin-right: -8px; + margin-left: -8px; + + .col-2, + .col-12 { + padding-right: 8px; + padding-left: 8px; + } + } +} + +.or-border { + position: relative; + text-align: center; + + &:before { + content: ""; + position: absolute; + left: 0; + width: 120px; + top: 50%; + height: 1px; + background: var(--mat-sys-outline); + } + + &:after { + content: ""; + position: absolute; + right: 0; + width: 120px; + top: 50%; + height: 1px; + background: var(--mat-sys-outline); + } +} + +.boxed-auth { + width: 100%; + max-width: 480px; + margin: 0 auto; +} + +.max-width-form { + max-width: 450px; +} + +.mat-mdc-form-field.mat-form-field-invalid { + + .mdc-notched-outline__leading, + .mdc-notched-outline__notch, + .mdc-notched-outline__trailing { + border-color: $error !important; + } +} + +.error-msg { + position: absolute; + top: -19px; + right: 3px; +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/rtl/_rtl.scss b/theme/packages/starterkit/src/assets/scss/rtl/_rtl.scss new file mode 100644 index 0000000..616be02 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/rtl/_rtl.scss @@ -0,0 +1,92 @@ +@use "../variables" as *; + +[dir="rtl"] { + + // ------------------------------------------------------ + // header + // ------------------------------------------------------ + .upgrade-bg { + left: 0; + right: unset; + transform: scaleX(-1); + } + + // highlight + td.hljs-ln-line.hljs-ln-numbers { + padding-left: 10px; + padding-right: 0; + } + + // customizer + .customizerBtn { + left: 30px; + right: unset; + } + + // logo flip + .branding img { + transform: scaleX(-1); + } + + .breadcrumb-icon { + left: 19px; + right: unset; + } + + .breadcrumb-item { + &:first-child { + margin-left: 0; + margin-right: -20px; + } + + &.active { + margin-left: 0; + margin-right: 20px; + } + } + + // sidebar + + .mat-drawer.sidebarNav { + border-left: 1px solid var(--mat-sys-outline-variant); + border-right: 0; + } + + .sidebar-list.mdc-list .menu-list-item .mdc-list-item__start { + margin-right: 0 !important; + margin-left: 14px !important; + } + + // minisidebar + &.sidebarNav-mini { + .contentWrapper { + margin-right: $sidenav-mini !important; + margin-left: 0 !important; + transition: swift-ease-out(width); + } + + .sidebarNav { + + // sidebar + .sidebar-list { + .menu-list-item { + .mdc-list-item__start { + margin-right: 8px !important; + margin-left: 7px !important; + } + } + } + + &:hover { + .sidebar-list { + .menu-list-item { + .mdc-list-item__start { + margin-right: 0 !important; + margin-left: 16px !important; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/style.scss b/theme/packages/starterkit/src/assets/scss/style.scss new file mode 100644 index 0000000..007761d --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/style.scss @@ -0,0 +1,36 @@ +@use "sass:map"; +@use "@angular/material" as mat; + +@use "themecolors/blue_theme"; +@use "themecolors/orange_theme"; +@use "themecolors/aqua_theme"; +@use "themecolors/cyan_theme"; +@use "themecolors/green_theme"; +@use "themecolors/purple_theme"; + +@use "variables" as *; +@use "override-component"; +@use "theme-variables/default-variables"; +@use "theme-variables/light-theme-variables"; +@use "theme-variables/dark-theme-variables"; + +//container layout +@use "layouts/transitions"; +@use "helpers/color"; +@use "helpers/border-color"; +@use "helpers/icon-size"; +@use "container"; +@use "layouts/layouts"; +@use "grid/grid"; +@use "helpers/custom-flex"; +@use "helpers"; + +// horizontal +@use "horizontal/horizontal"; +@use "dark/dark"; + + +@use "pages/auth"; + +// RTL Theme +@use "rtl/rtl"; \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/theme-variables/_dark-theme-variables.scss b/theme/packages/starterkit/src/assets/scss/theme-variables/_dark-theme-variables.scss new file mode 100644 index 0000000..0375fc4 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/theme-variables/_dark-theme-variables.scss @@ -0,0 +1,32 @@ +@use "@angular/material" as mat; + +html.dark-theme { + color-scheme: dark; + --mat-sys-background: #141a21; + --mat-sys-on-background: rgba(255, 255, 255, 0.9); + --mat-sys-on-primary: #fff; + --mat-sys-surface-bright: #ffffff05; + --mat-sys-surface: #141a21; + --mat-sys-surface-container: #141a21; + --mat-sys-surface-container-low: #141a21; + --mat-sys-outline-variant: #2e3f50; + --mat-sys-outline: #2e3f50; + --mat-form-field-outlined-hover-outline-color: #465670; + --mat-checkbox-unselected-hover-state-layer-color: #19212a; + --mat-menu-item-hover-state-layer-color: #19212a; + --mat-button-toggle-state-layer-color: #19212a; + --mat-option-focus-state-layer-color: #19212a; + --mat-option-hover-state-layer-color: #19212a; + --mat-slide-toggle-unselected-track-color: #19212a; + --mat-stepper-header-focus-state-layer-color: #19212a; + --mat-stepper-header-hover-state-layer-color: #19212a; + --mat-expansion-header-hover-state-layer-color: #19212a; + @include mat.card-overrides((elevated-container-color: #1c252e, + elevated-container-elevation: rgba(0, 0, 0, 0.2) 0px 0px 2px 0px, + subtitle-text-color: rgba(255, 255, 255, 0.67), + )); + @include mat.theme-overrides((level1: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level2: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + level3: 0px 12px 24px -4px rgba(143, 176, 210, 0.02), + )); +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/theme-variables/_default-variables.scss b/theme/packages/starterkit/src/assets/scss/theme-variables/_default-variables.scss new file mode 100644 index 0000000..e3adeb2 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/theme-variables/_default-variables.scss @@ -0,0 +1,12 @@ +html { + --mat-sys-error-fixed-dim: rgba(247, 68, 86, 0.15); + --mat-select-container-elevation-shadow: var(--mat-sys-level3); + --mat-list-list-item-label-text-tracking: 0; + --mat-slide-toggle-track-height: 28px; + --mat-sidenav-container-divider-color: var(--mat-sys-outline-variant); + --mat-dialog-with-actions-content-padding: 20px 24px; + --mat-form-field-container-text-tracking: unset; + --mat-slide-toggle-with-icon-handle-size: 21px; + --mat-badge-text-color: white; + --mat-slide-toggle-selected-with-icon-handle-horizontal-margin: 0 26px; +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/theme-variables/_light-theme-variables.scss b/theme/packages/starterkit/src/assets/scss/theme-variables/_light-theme-variables.scss new file mode 100644 index 0000000..735309e --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/theme-variables/_light-theme-variables.scss @@ -0,0 +1,23 @@ +html.light-theme { + color-scheme: light; + --mat-sys-corner-small: 7px; + --mat-sys-background: #fff; + --mat-sys-surface-bright: #f2f6fa; + --mat-sys-surface: #fff; + --mat-sys-surface-container: #fff; + --mat-sys-surface-container-low: #fff; + --mat-sys-on-background: #2a3547; + --mat-sys-outline: #d7dde2; + --mat-sys-outline-variant: #d7dde2; + --mat-form-field-outlined-hover-outline-color: #d7dde2; + --mat-checkbox-unselected-hover-state-layer-color: #d7dde2; + --mat-menu-item-hover-state-layer-color: #f6f9fc; + --mat-button-toggle-state-layer-color: #f6f9fc; + --mat-option-focus-state-layer-color: #f6f9fc; + --mat-option-hover-state-layer-color: #f6f9fc; + --mat-slide-toggle-unselected-track-color: #f6f9fc; + --mat-stepper-header-focus-state-layer-color: #f6f9fc; + --mat-stepper-header-hover-state-layer-color: #f6f9fc; + --mat-dialog-supporting-text-color: var(--mat-sys-on-background); + --mat-expansion-header-hover-state-layer-color: #f6f9fc; + } \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/themecolors/_aqua_theme.scss b/theme/packages/starterkit/src/assets/scss/themecolors/_aqua_theme.scss new file mode 100644 index 0000000..185291b --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/themecolors/_aqua_theme.scss @@ -0,0 +1,7 @@ +html.aqua_theme { + --mat-sys-primary: rgb(0, 116, 186); + --mat-sys-primary-fixed-dim: rgb(0, 116, 186, 0.15); + --mat-sys-secondary: rgb(71, 215, 188); + --mat-sys-secondary-fixed-dim: rgb(71, 215, 188, 0.15); + --mat-sys-tertiary: rgb(71, 215, 188); +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/themecolors/_blue_theme.scss b/theme/packages/starterkit/src/assets/scss/themecolors/_blue_theme.scss new file mode 100644 index 0000000..b34c0bd --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/themecolors/_blue_theme.scss @@ -0,0 +1,6 @@ +html.blue_theme { + --mat-sys-primary: rgb(93, 135, 255); + --mat-sys-primary-fixed-dim: rgb(93, 135, 255, 0.15); + --mat-sys-secondary: rgb(68, 183, 247); + --mat-sys-secondary-fixed-dim: rgb(68, 183, 247, 0.15); +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/themecolors/_cyan_theme.scss b/theme/packages/starterkit/src/assets/scss/themecolors/_cyan_theme.scss new file mode 100644 index 0000000..7dea9b0 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/themecolors/_cyan_theme.scss @@ -0,0 +1,7 @@ +html.cyan_theme { + --mat-sys-primary: rgb(0, 185, 192); + --mat-sys-primary-fixed-dim: rgb(0, 185, 192, 0.15); + --mat-sys-secondary: rgb(244, 139, 108); + --mat-sys-secondary-fixed-dim: rgb(244, 139, 108, 0.15); + --mat-sys-tertiary: rgb(244, 139, 108); +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/themecolors/_green_theme.scss b/theme/packages/starterkit/src/assets/scss/themecolors/_green_theme.scss new file mode 100644 index 0000000..d80c4b8 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/themecolors/_green_theme.scss @@ -0,0 +1,7 @@ +html.green_theme { + --mat-sys-primary: rgb(6, 118, 154); + --mat-sys-primary-fixed-dim: rgb(6, 118, 154, 0.15); + --mat-sys-secondary: rgb(195, 208, 70); + --mat-sys-secondary-fixed-dim: rgb(195, 208, 70, 0.15); + --mat-sys-tertiary: rgb(195, 208, 70); +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/themecolors/_orange_theme.scss b/theme/packages/starterkit/src/assets/scss/themecolors/_orange_theme.scss new file mode 100644 index 0000000..20bed3b --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/themecolors/_orange_theme.scss @@ -0,0 +1,7 @@ +html.orange_theme { + --mat-sys-primary: rgb(250, 137, 107); + --mat-sys-primary-fixed-dim: rgb(250, 137, 107, 0.15); + --mat-sys-secondary: rgb(0, 127, 180); + --mat-sys-secondary-fixed-dim: rgb(0, 127, 180, 0.15); + --mat-sys-error-fixed-dim: rgba(247, 68, 86, 0.15); +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/assets/scss/themecolors/_purple_theme.scss b/theme/packages/starterkit/src/assets/scss/themecolors/_purple_theme.scss new file mode 100644 index 0000000..1476625 --- /dev/null +++ b/theme/packages/starterkit/src/assets/scss/themecolors/_purple_theme.scss @@ -0,0 +1,7 @@ +html.purple_theme { + --mat-sys-primary: rgb(110, 53, 183); + --mat-sys-primary-fixed-dim: rgb(110, 53, 183, 0.15); + --mat-sys-secondary: rgb(139, 200, 206); + --mat-sys-secondary-fixed-dim: rgb(139, 200, 206, 0.15); + --mat-sys-tertiary: rgb(139, 200, 206); +} \ No newline at end of file diff --git a/theme/packages/starterkit/src/favicon.ico b/theme/packages/starterkit/src/favicon.ico new file mode 100644 index 0000000..997406a Binary files /dev/null and b/theme/packages/starterkit/src/favicon.ico differ diff --git a/theme/packages/starterkit/src/index.html b/theme/packages/starterkit/src/index.html new file mode 100644 index 0000000..5c0083b --- /dev/null +++ b/theme/packages/starterkit/src/index.html @@ -0,0 +1,16 @@ + + + + + Modernize Angular Admin Template + + + + + + + + + + + diff --git a/theme/packages/starterkit/src/main.ts b/theme/packages/starterkit/src/main.ts new file mode 100644 index 0000000..514c89a --- /dev/null +++ b/theme/packages/starterkit/src/main.ts @@ -0,0 +1,7 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err) +); diff --git a/theme/packages/starterkit/src/styles.scss b/theme/packages/starterkit/src/styles.scss new file mode 100644 index 0000000..b28c7e4 --- /dev/null +++ b/theme/packages/starterkit/src/styles.scss @@ -0,0 +1,7 @@ +/* You can add global styles to this file, and also import other style files */ + +html, +body { + height: 100%; + margin: 0; +} \ No newline at end of file diff --git a/theme/packages/starterkit/tsconfig.app.json b/theme/packages/starterkit/tsconfig.app.json new file mode 100644 index 0000000..374cc9d --- /dev/null +++ b/theme/packages/starterkit/tsconfig.app.json @@ -0,0 +1,14 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/theme/packages/starterkit/tsconfig.json b/theme/packages/starterkit/tsconfig.json new file mode 100644 index 0000000..5b683aa --- /dev/null +++ b/theme/packages/starterkit/tsconfig.json @@ -0,0 +1,34 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "strictPropertyInitialization": false, + "lib": [ + "ES2022", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true, + } +} diff --git a/theme/packages/starterkit/tsconfig.spec.json b/theme/packages/starterkit/tsconfig.spec.json new file mode 100644 index 0000000..be7e9da --- /dev/null +++ b/theme/packages/starterkit/tsconfig.spec.json @@ -0,0 +1,14 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +}