diff --git a/.claude/settings.local 2.json b/.claude/settings.local 2.json new file mode 100644 index 0000000..65a446f --- /dev/null +++ b/.claude/settings.local 2.json @@ -0,0 +1,24 @@ +{ + "permissions": { + "allow": [ + "Bash(npm run build:*)", + "Bash(npm install)", + "Bash(npm run lint)", + "Bash(rm:*)", + "Bash(ls:*)", + "Bash(pkill:*)", + "Bash(true)", + "Bash(npm start)", + "Bash(grep:*)", + "Bash(sudo rm:*)", + "Bash(npx eslint:*)", + "Bash(npm run lint:*)", + "Bash(gh release create:*)", + "Bash(npm search:*)", + "Bash(npm pack:*)", + "Bash(npm:*)", + "WebFetch(domain:keenthemes.com)" + ], + "deny": [] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index ff62f49..fa8845e 100755 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,9 @@ logs npm-debug.log* node_modules yarn.lock +yarn-error.log* +pnpm-lock.yaml +package-lock.json # ---------------------------- # Project Folders @@ -30,4 +33,36 @@ yarn.lock build/ dist/ -CLAUDE.md + +# ---------------------------- +# Development Files +# ---------------------------- + +*.map +*.ts +tsconfig.json +.env +.env.local +.env.development +.env.test +.env.production + +# ---------------------------- +# Editor Directories +# ---------------------------- + +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# ---------------------------- +# OS Files +# ---------------------------- + +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes diff --git a/CHANGELOG.md b/CHANGELOG.md index 90b6424..f64ef8a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,55 @@ # Changelog +## [2.8.0] - 2025-08-11 + +### Dependency Modernization & Security Updates + +This release focuses on modernizing the build system, updating dependencies to their latest stable versions, and removing deprecated packages to ensure better security and performance. + +### Key Improvements + +#### Build System Enhancements +- **Replaced deprecated file-loader with Webpack 5 native asset modules** - Modernized asset handling using Webpack 5's built-in capabilities +- **Moved @babel/runtime to production dependencies** - Properly configured runtime dependencies for production builds +- **Fixed all import/export warnings** - Resolved module resolution issues for cleaner builds + +#### Major Dependency Updates +- **Upgraded cross-env from v7 to v10** - Latest version with ESM support and TypeScript improvements +- **Updated all Babel packages to v7.28.0** - Latest stable Babel 7 release +- **Updated TypeScript to v5.9.2** - Latest TypeScript with improved type checking +- **Updated Webpack to v5.101.0** - Latest Webpack 5 with performance improvements +- **Updated ESLint to v9.33.0** - Latest ESLint with new rules and fixes + +#### Security & Maintenance +- Updated all FullCalendar components to v6.1.19 +- Updated all development dependencies to latest stable versions +- Removed non-existent test.html reference from build configuration +- Fixed stylelint configuration compatibility issues + +### Technical Details + +**Removed Deprecated Packages:** +- `file-loader` - Replaced with Webpack 5 asset/resource modules + +**Updated Dependencies:** +- @babel/core: 7.27.4 → 7.28.0 +- @babel/runtime: 7.27.6 → 7.28.2 (moved to production dependencies) +- @eslint/js: 9.29.0 → 9.33.0 +- @typescript-eslint/eslint-plugin: 8.36.0 → 8.39.0 +- @typescript-eslint/parser: 8.36.0 → 8.39.0 +- @fullcalendar/*: 6.1.17 → 6.1.19 (all packages) +- cross-env: 7.0.3 → 10.0.0 +- eslint: 9.29.0 → 9.33.0 +- typescript: 5.8.3 → 5.9.2 +- webpack: 5.99.9 → 5.101.0 +- And various other minor updates + +### Build Status +- Zero build errors +- Zero build warnings +- All linting rules pass successfully +- Production build size remains optimized + ## [2.7.1] - 2025-07-10 ### Bug Fixes & Improvements diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..27448f2 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,162 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Development Commands + +### Core Development +- `npm start` - Start development server with hot reload (available at http://localhost:4000) +- `npm run dev` - Start development server with webpack dashboard +- `npm run build` - Build for production (optimized) +- `npm run release:minified` - Build production with minification +- `npm run release:unminified` - Build production without minification +- `npm run preview` - Preview production build locally + +### Code Quality +- `npm run lint` - Run all linters (JavaScript + SCSS) +- `npm run lint:js` - Lint JavaScript files using ESLint 9.x flat config +- `npm run lint:scss` - Lint SCSS files using Stylelint + +### Utility Commands +- `npm run clean` - Clean the dist directory + +## Project Architecture + +### Technology Stack +- **Build System**: Webpack 5.99.9 with modern configuration +- **JavaScript**: ES6+ with Babel transpilation, ESLint 9.x flat config +- **CSS**: Sass/SCSS with PostCSS processing, Bootstrap 5.3.7 +- **Frontend Framework**: **100% jQuery-free** vanilla JavaScript with modern class-based architecture +- **Theme System**: CSS variables-based dark/light mode system + +### Core Application Structure +The application follows a modular class-based architecture: + +**Main Application Class** (`src/assets/scripts/app.js`): +- `AdminatorApp` - Main application controller with component management +- Handles initialization, mobile optimizations, and global event coordination +- Component registry system for managing feature modules + +**Core Components**: +- `Sidebar` (`src/assets/scripts/components/Sidebar.js`) - Navigation sidebar logic +- `ChartComponent` (`src/assets/scripts/components/Chart.js`) - Chart rendering and theme integration +- `Theme` (`src/assets/scripts/utils/theme.js`) - Theme management with localStorage persistence + +**Utility Modules**: +- `DOM` (`src/assets/scripts/utils/dom.js`) - DOM manipulation helpers +- `DateUtils` (`src/assets/scripts/utils/date.js`) - Date handling with Day.js integration + +### Dark Mode System +The project features a comprehensive dark mode implementation: + +**Theme Toggle Integration**: +- Automatically injects theme toggle into navigation if missing +- Detects OS preference on first visit +- Persists theme choice in localStorage +- Real-time theme switching without page reload + +**Component Theme Awareness**: +- Chart.js integration with dynamic color schemes +- FullCalendar dark mode support +- Vector maps with theme-specific palettes +- All UI components use CSS variables for theming + +**CSS Variables Architecture**: +- Semantic color variables (e.g., `--c-bkg-body`, `--c-text-base`) +- Component-specific theme variables +- Automatic contrast and accessibility considerations + +### Mobile Optimization +The application includes extensive mobile enhancements: + +**Responsive Features**: +- Full-width search overlay for mobile +- Enhanced dropdown behavior with overlay management +- Touch-friendly interactions +- Viewport-based responsive breakpoints + +**Mobile-Specific Behavior**: +- Prevents horizontal scrolling on mobile +- Auto-focus management for form inputs +- Gesture-based navigation support + +### File Organization +``` +src/ +├── assets/ +│ ├── scripts/ # JavaScript modules +│ │ ├── components/ # Reusable UI components +│ │ ├── utils/ # Utility functions +│ │ ├── charts/ # Chart initialization modules +│ │ ├── fullcalendar/ # Calendar integration +│ │ └── app.js # Main application entry point +│ ├── styles/ # SCSS stylesheets +│ │ ├── spec/ # Custom component styles +│ │ └── vendor/ # Third-party plugin styles +│ └── static/ # Static assets (fonts, images) +├── *.html # HTML template pages +``` + +### Build Configuration +**Webpack Setup**: +- Modern flat ESLint configuration +- Sass compilation with PostCSS processing +- Source map generation for development +- Production optimization with minification +- Hot module replacement for development + +**Development Server**: +- Webpack dev server on port 4000 +- Live reload and hot module replacement +- Proxy configuration for API endpoints + +## Working with This Codebase + +### Adding New Components +1. Create component class in `src/assets/scripts/components/` +2. Register component in `AdminatorApp.init()` method +3. Add component-specific styles in `src/assets/styles/spec/components/` +4. Ensure theme compatibility using CSS variables + +### Modifying Themes +- Theme logic is centralized in `src/assets/scripts/utils/theme.js` +- CSS variables are defined in `src/assets/styles/utils/theme.css` +- Chart.js theme integration is automatic via `Chart.defaults` configuration + +### Testing Changes +- Always run `npm run lint` before committing +- Test both light and dark themes +- Verify mobile responsiveness at various breakpoints +- Check component integration via browser developer tools + +### Development Workflow +1. Run `npm start` for development server +2. Use `npm run dev` for enhanced debugging with webpack dashboard +3. Lint code with `npm run lint` before commits +4. Build production assets with `npm run build` +5. Preview production build with `npm run preview` + +### Key Dependencies +- **Bootstrap 5.3.7**: UI framework and CSS components (JS components replaced with vanilla alternatives) +- **Chart.js 4.5.0**: Interactive charts with theme support (replaces jQuery Sparkline) +- **FullCalendar 6.1.17**: Calendar component with dark mode +- **Day.js 1.11.13**: Lightweight date manipulation +- **Perfect Scrollbar 1.5.6**: Custom scrollbar implementation +- **Masonry Layout 4.2.2**: Grid layouts (vanilla JS compatible) + +### Removed jQuery Dependencies +**Successfully removed all jQuery dependencies (~600KB bundle reduction):** +- ❌ `jquery` (3.7.1) - Replaced with vanilla JS DOM manipulation +- ❌ `jquery-sparkline` (2.4.0) - Replaced with Chart.js mini charts +- ❌ `bootstrap-datepicker` (1.10.0) - Replaced with HTML5 date inputs + vanilla JS +- ❌ `datatables` (1.10.18) - Replaced with vanilla JS table component +- ❌ `easy-pie-chart` (2.1.7) - Replaced with vanilla JS SVG pie charts +- ❌ `jvectormap` (2.0.4) - Replaced with vanilla JS SVG world map + +### Modern Vanilla JS Implementations +- **Sparkline Charts**: Chart.js-based mini charts with theme support +- **Pie Charts**: Custom SVG-based circular progress indicators +- **Data Tables**: Full-featured table with sorting, pagination, and search +- **Date Pickers**: Enhanced HTML5 date inputs with custom styling +- **Vector Maps**: SVG-based world map with markers and interactions +- **Bootstrap 5 Components**: Vanilla JS implementations of modals, dropdowns, popovers, tooltips, and accordions \ No newline at end of file diff --git a/README.md b/README.md index d5dcbd7..5ad1290 100755 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -# Adminator Bootstrap 5 Admin Template v2.7.1 +# Adminator Bootstrap 5 Admin Template v2.8.0 -**Adminator** is a responsive Bootstrap 5 Admin Template built with modern development tools. It provides you with a collection of ready to use code snippets and utilities, custom pages, a collection of applications and some useful widgets. +**Adminator** is a responsive Bootstrap 5 Admin Template built with modern development tools. It provides you with a collection of ready to use code snippets and utilities, custom pages, a collection of applications and some useful widgets. -**Latest Update (v2.7.1)**: **100% jQuery-Free** - Complete removal of jQuery dependency (~600KB bundle reduction) with modern vanilla JavaScript implementation. +**Latest Update (v2.8.0)**: Dependency modernization with Webpack 5 native asset modules, updated build tools, and comprehensive security updates ensuring optimal performance and maintainability. + +**Looking for more premium admin templates?** Visit **[DashboardPack.com](https://dashboardpack.com/)** for a curated collection of high-quality admin dashboard templates for various frameworks and technologies. **Performance Benefits**: Faster load times, smaller bundle size, modern ES6+ code, and zero jQuery overhead. @@ -35,6 +37,22 @@ Preview of this awesome admin template available here: https://colorlib.com/poly - [Authors](#authors) - [License](#license) +## What's New in v2.8.0 + +### Dependency Modernization & Build System Enhancements +- **Webpack 5 Native Asset Modules**: Replaced deprecated file-loader with modern Webpack 5 asset handling +- **Updated Build Tools**: All build dependencies updated to latest stable versions +- **Cross-env v10**: Upgraded to latest version with ESM support and TypeScript improvements +- **Zero Build Warnings**: Fixed all import/export issues for cleaner builds +- **Security Updates**: Comprehensive dependency updates addressing all known vulnerabilities + +### Technical Improvements +- Moved @babel/runtime to production dependencies for proper runtime support +- Updated TypeScript to v5.9.2 for enhanced type checking +- Updated ESLint to v9.33.0 with latest rules and fixes +- All FullCalendar components updated to v6.1.19 +- Webpack updated to v5.101.0 with performance improvements + ## What's New in v2.7.1 **jQuery-Free Release** - Complete removal of jQuery dependency with modern vanilla JavaScript: @@ -388,15 +406,16 @@ See [CHANGELOG.md](CHANGELOG.md) for detailed version history. 📚 **[Online Documentation](https://puikinsh.github.io/Adminator-admin-dashboard/)** includes comprehensive guides for all features. -#### Latest Release: V 2.7.1 (2025-07-10) -- **100% jQuery-Free** - Complete removal of jQuery dependency (~600KB reduction) -- **Modern Vanilla JavaScript** - Class-based architecture with ES6+ features -- **Chart.js Integration** - Replaced jQuery Sparkline with Chart.js -- **HTML5 Date Pickers** - Enhanced native inputs with Day.js support -- **SVG Vector Maps** - Pure JavaScript world maps with theme support -- **Zero Breaking Changes** - All functionality preserved with better performance +#### Latest Release: V 2.8.0 (2025-08-11) +- **Webpack 5 Asset Modules** - Replaced deprecated file-loader with native Webpack 5 capabilities +- **Dependency Modernization** - Updated all build tools and dependencies to latest stable versions +- **Zero Build Warnings** - Fixed all import/export issues for cleaner production builds +- **Security Updates** - Comprehensive dependency updates addressing all known vulnerabilities +- **Cross-env v10** - Upgraded to latest version with ESM support +- **TypeScript 5.9.2** - Latest TypeScript with enhanced type checking -#### Previous Releases +#### Previous Releases +- **V 2.7.1**: 100% jQuery-Free with modern vanilla JavaScript - **V 2.6.0**: Complete Dark Mode System with theme switching - **V 2.5.0**: Updated all dependencies, ESLint 9.x, zero vulnerabilities - **V 2.1.0**: Upgraded all dependencies @@ -407,7 +426,16 @@ See [CHANGELOG.md](CHANGELOG.md) for detailed version history. ## Authors [Colorlib](https://colorlib.com) -## More info +## Looking for More Admin Templates? + +**Visit [DashboardPack.com](https://dashboardpack.com/)** - Your premier destination for high-quality admin dashboard templates: +- Premium and free admin templates for all major frameworks +- React, Vue, Angular, Bootstrap, and vanilla JavaScript templates +- Modern designs with dark mode support +- Comprehensive documentation and support +- Regular updates and new releases + +## More Resources from Colorlib - [Bootstrap Dashboards](https://colorlib.com/wp/free-bootstrap-admin-dashboard-templates/) - [Bootstrap Templates](https://colorlib.com/wp/free-bootstrap-templates/) - [HTML Templates](https://colorlib.com/wp/free-html-website-templates/) diff --git a/forms.php b/forms.php deleted file mode 100644 index df8b648..0000000 --- a/forms.php +++ /dev/null @@ -1,787 +0,0 @@ - - - - - - Forms - - - - - - - - - -
-
-
- - - - - -
- - - - -
- - - - -
-
-
-
-
-
-
Basic Form
-
-
-
- - - We'll never share your email with anyone else. -
-
- - -
-
- - -
- -
-
-
-
- - "; - echo $password; - } - ?> -
-
-
Complex Form Layout
-
-
-
-
- - -
-
- - -
-
-
- - -
-
- - -
-
-
- - -
-
- - -
-
- - -
-
-
-
- -
-
-
- -
- -
-
-
-
-
-
- - -
-
- -
-
-
-
-
-
-
Horizontal Form
-
-
-
- -
- -
-
-
- -
- -
-
-
-
- Radios -
-
- -
-
- -
-
- -
-
-
-
-
-
Checkbox
-
-
- -
-
-
-
-
- -
-
-
-
-
-
-
-
-
Disabled Forms
-
-
-
-
- - -
-
- - -
-
- -
- -
-
-
-
-
-
-
-
Validation
-
-
-
-
- - -
-
- - -
-
-
-
- - -
- Please provide a valid city. -
-
-
- - -
- Please provide a valid state. -
-
-
- - -
- Please provide a valid zip. -
-
-
- -
- -
-
-
-
-
-
- - - -
-
- - diff --git a/package-lock.json b/package-lock.json index 5f09758..baf2aa9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,25 +1,25 @@ { "name": "adminator-admin-dashboard", - "version": "2.7.0", + "version": "2.7.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "adminator-admin-dashboard", - "version": "2.7.0", + "version": "2.7.1", "license": "MIT", "dependencies": { - "@fullcalendar/core": "^6.1.17", - "@fullcalendar/daygrid": "^6.1.17", - "@fullcalendar/interaction": "^6.1.17", - "@fullcalendar/list": "^6.1.17", - "@fullcalendar/timegrid": "^6.1.17", + "@babel/runtime": "^7.28.2", + "@fullcalendar/core": "^6.1.19", + "@fullcalendar/daygrid": "^6.1.19", + "@fullcalendar/interaction": "^6.1.19", + "@fullcalendar/list": "^6.1.19", + "@fullcalendar/timegrid": "^6.1.19", "@popperjs/core": "^2.11.8", "bootstrap": "^5.3.7", "brand-colors": "^2.1.1", "chart.js": "^4.5.0", "dayjs": "^1.11.13", - "file-loader": "^6.2.0", "jsvectormap": "^1.6.0", "load-google-maps-api": "^2.0.2", "lodash": "^4.17.21", @@ -28,40 +28,39 @@ "skycons": "^1.0.0" }, "devDependencies": { - "@babel/core": "^7.27.4", - "@babel/eslint-parser": "^7.27.5", - "@babel/plugin-transform-runtime": "^7.27.4", - "@babel/preset-env": "^7.27.2", - "@babel/runtime": "^7.27.6", - "@eslint/js": "^9.29.0", + "@babel/core": "^7.28.0", + "@babel/eslint-parser": "^7.28.0", + "@babel/plugin-transform-runtime": "^7.28.0", + "@babel/preset-env": "^7.28.0", + "@eslint/js": "^9.33.0", "@types/lodash": "^4.17.20", "@types/masonry-layout": "^4.2.8", - "@types/node": "^24.0.12", - "@typescript-eslint/eslint-plugin": "^8.36.0", - "@typescript-eslint/parser": "^8.36.0", + "@types/node": "^24.2.1", + "@typescript-eslint/eslint-plugin": "^8.39.0", + "@typescript-eslint/parser": "^8.39.0", "babel-loader": "^10.0.0", "case-sensitive-paths-webpack-plugin": "^2.4.0", "copy-webpack-plugin": "^13.0.0", - "cross-env": "^7.0.3", + "cross-env": "^10.0.0", "css-loader": "^7.1.2", "css-minimizer-webpack-plugin": "^7.0.2", - "eslint": "^9.29.0", + "eslint": "^9.33.0", "eslint-formatter-table": "^7.32.1", - "globals": "^16.2.0", + "globals": "^16.3.0", "html-webpack-plugin": "^5.6.3", - "mini-css-extract-plugin": "^2.9.2", + "mini-css-extract-plugin": "^2.9.3", "postcss": "^8.5.6", "postcss-loader": "^8.1.1", - "postcss-preset-env": "^10.2.3", - "sass": "^1.89.2", + "postcss-preset-env": "^10.2.4", + "sass": "^1.90.0", "sass-loader": "^16.0.5", "shx": "^0.4.0", "style-loader": "^4.0.0", - "stylelint": "^16.21.0", + "stylelint": "^16.23.1", "stylelint-config-standard": "^38.0.0", "ts-loader": "^9.5.2", - "typescript": "^5.8.3", - "webpack": "^5.99.9", + "typescript": "^5.9.2", + "webpack": "^5.101.0", "webpack-cli": "^6.0.1", "webpack-dashboard": "^3.3.8", "webpack-dev-server": "^5.2.2" @@ -100,9 +99,9 @@ } }, "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==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", "dev": true, "license": "MIT", "engines": { @@ -110,22 +109,22 @@ } }, "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==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", + "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", + "@babel/generator": "^7.28.0", "@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/helpers": "^7.27.6", + "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", - "@babel/traverse": "^7.27.4", - "@babel/types": "^7.27.3", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -141,9 +140,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.27.5.tgz", - "integrity": "sha512-HLkYQfRICudzcOtjGwkPvGc5nF1b4ljLZh1IRDj50lRZ718NAKVgQpIAUX8bfg6u/yuSKY3L7E0YzIV+OxrB8Q==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.0.tgz", + "integrity": "sha512-N4ntErOlKvcbTt01rr5wj3y55xnIdx1ymrfIr8C2WnM1Y9glFgWaGDEULJIazOX3XM9NRzhfJ6zZnQ1sBNWU+w==", "dev": true, "license": "MIT", "dependencies": { @@ -160,16 +159,16 @@ } }, "node_modules/@babel/generator": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", - "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", "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", + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" }, "engines": { @@ -247,22 +246,32 @@ } }, "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==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.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", @@ -442,13 +451,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", - "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.27.3" + "@babel/types": "^7.28.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -620,15 +629,15 @@ } }, "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==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", "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" + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -672,9 +681,9 @@ } }, "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==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz", + "integrity": "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -722,18 +731,18 @@ } }, "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==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.0.tgz", + "integrity": "sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.27.1", - "globals": "^11.1.0" + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -742,16 +751,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-classes/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/@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", @@ -770,13 +769,14 @@ } }, "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==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", + "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -851,6 +851,23 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", + "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0" + }, + "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", @@ -1118,16 +1135,17 @@ } }, "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==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz", + "integrity": "sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==", "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" + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -1187,9 +1205,9 @@ } }, "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==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "dev": true, "license": "MIT", "dependencies": { @@ -1254,9 +1272,9 @@ } }, "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==", + "version": "7.28.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.1.tgz", + "integrity": "sha512-P0QiV/taaa3kXpLY+sXla5zec4E+4t4Aqc9ggHlfZ7a2cp8/x/Gv08jfwEtn9gnnYIMvHx6aoOZ8XJL8eU71Dg==", "dev": true, "license": "MIT", "dependencies": { @@ -1303,17 +1321,17 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.27.4.tgz", - "integrity": "sha512-D68nR5zxU64EUzV8i7T3R5XP0Xhrou/amNnddsRQssx6GrTLdZl1rLxyjtVZBd+v/NVX4AbTPOB5aU8thAZV1A==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.0.tgz", + "integrity": "sha512-dGopk9nZrtCs2+nfIem25UuHyt5moSJamArzIoh9/vezUQPmYDOzjaHDCkAzuGJibCIkPup8rMT2+wYB6S73cA==", "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", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", "semver": "^6.3.1" }, "engines": { @@ -1472,13 +1490,13 @@ } }, "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==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.0.tgz", + "integrity": "sha512-VmaxeGOwuDqzLl5JUkIRM1X2Qu2uKGxHEQWh+cvvbl7JuJRgKGJSfsEF/bUaxFhJl/XAyxBe7q7qSuTbKFuCyg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", + "@babel/compat-data": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", @@ -1492,19 +1510,20 @@ "@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-generator-functions": "^7.28.0", "@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-block-scoping": "^7.28.0", "@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-classes": "^7.28.0", "@babel/plugin-transform-computed-properties": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", "@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-explicit-resource-management": "^7.28.0", "@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", @@ -1521,15 +1540,15 @@ "@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-rest-spread": "^7.28.0", "@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-parameters": "^7.27.7", "@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-regenerator": "^7.28.0", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", @@ -1542,10 +1561,10 @@ "@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", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "engines": { @@ -1571,10 +1590,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", - "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", - "dev": true, + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", + "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1596,38 +1614,28 @@ } }, "node_modules/@babel/traverse": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", - "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", - "@babel/parser": "^7.27.4", + "@babel/generator": "^7.28.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", - "@babel/types": "^7.27.3", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/types": "^7.28.0", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/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/@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==", + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2157,9 +2165,9 @@ } }, "node_modules/@csstools/postcss-cascade-layers": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.1.tgz", - "integrity": "sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.2.tgz", + "integrity": "sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==", "dev": true, "funding": [ { @@ -3148,6 +3156,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/@epic-web/invariant": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz", + "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", @@ -3191,9 +3206,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.1.tgz", - "integrity": "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3206,9 +3221,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.3.tgz", - "integrity": "sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", + "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3216,9 +3231,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", - "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3266,9 +3281,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.29.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz", - "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==", + "version": "9.33.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.33.0.tgz", + "integrity": "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==", "dev": true, "license": "MIT", "engines": { @@ -3289,78 +3304,65 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.2.tgz", - "integrity": "sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.0", + "@eslint/core": "^0.15.2", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.0.tgz", - "integrity": "sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/@fullcalendar/core": { - "version": "6.1.17", - "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.17.tgz", - "integrity": "sha512-0W7lnIrv18ruJ5zeWBeNZXO8qCWlzxDdp9COFEsZnyNjiEhUVnrW/dPbjRKYpL0edGG0/Lhs0ghp1z/5ekt8ZA==", + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.19.tgz", + "integrity": "sha512-z0aVlO5e4Wah6p6mouM0UEqtRf1MZZPt4mwzEyU6kusaNL+dlWQgAasF2cK23hwT4cmxkEmr4inULXgpyeExdQ==", "license": "MIT", "dependencies": { "preact": "~10.12.1" } }, "node_modules/@fullcalendar/daygrid": { - "version": "6.1.17", - "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.17.tgz", - "integrity": "sha512-K7m+pd7oVJ9fW4h7CLDdDGJbc9szJ1xDU1DZ2ag+7oOo1aCNLv44CehzkkknM6r8EYlOOhgaelxQpKAI4glj7A==", + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.19.tgz", + "integrity": "sha512-IAAfnMICnVWPjpT4zi87i3FEw0xxSza0avqY/HedKEz+l5MTBYvCDPOWDATpzXoLut3aACsjktIyw9thvIcRYQ==", "license": "MIT", "peerDependencies": { - "@fullcalendar/core": "~6.1.17" + "@fullcalendar/core": "~6.1.19" } }, "node_modules/@fullcalendar/interaction": { - "version": "6.1.17", - "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.17.tgz", - "integrity": "sha512-AudvQvgmJP2FU89wpSulUUjeWv24SuyCx8FzH2WIPVaYg+vDGGYarI7K6PcM3TH7B/CyaBjm5Rqw9lXgnwt5YA==", + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.19.tgz", + "integrity": "sha512-GOciy79xe8JMVp+1evAU3ytdwN/7tv35t5i1vFkifiuWcQMLC/JnLg/RA2s4sYmQwoYhTw/p4GLcP0gO5B3X5w==", "license": "MIT", "peerDependencies": { - "@fullcalendar/core": "~6.1.17" + "@fullcalendar/core": "~6.1.19" } }, "node_modules/@fullcalendar/list": { - "version": "6.1.17", - "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.17.tgz", - "integrity": "sha512-fkyK49F9IxwlGUBVhJGsFpd/LTi/vRVERLIAe1HmBaGkjwpxnynm8TMLb9mZip97wvDk3CmZWduMe6PxscAlow==", + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.19.tgz", + "integrity": "sha512-knZHpAVF0LbzZpSJSUmLUUzF0XlU/MRGK+Py2s0/mP93bCtno1k2L3XPs/kzh528hSjehwLm89RgKTSfW1P6cA==", "license": "MIT", "peerDependencies": { - "@fullcalendar/core": "~6.1.17" + "@fullcalendar/core": "~6.1.19" } }, "node_modules/@fullcalendar/timegrid": { - "version": "6.1.17", - "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.17.tgz", - "integrity": "sha512-K4PlA3L3lclLOs3IX8cvddeiJI9ZVMD7RA9IqaWwbvac771971foc9tFze9YY+Pqesf6S+vhS2dWtEVlERaGlQ==", + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.19.tgz", + "integrity": "sha512-OuzpUueyO9wB5OZ8rs7TWIoqvu4v3yEqdDxZ2VcsMldCpYJRiOe7yHWKr4ap5Tb0fs7Rjbserc/b6Nt7ol6BRg==", "license": "MIT", "dependencies": { - "@fullcalendar/daygrid": "~6.1.17" + "@fullcalendar/daygrid": "~6.1.19" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.17" + "@fullcalendar/core": "~6.1.19" } }, "node_modules/@humanfs/core": { @@ -3461,32 +3463,21 @@ } }, "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==", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@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==", - "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" @@ -3496,6 +3487,7 @@ "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", @@ -3506,12 +3498,14 @@ "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==", + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3576,14 +3570,11 @@ } }, "node_modules/@keyv/serialize": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz", - "integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.0.tgz", + "integrity": "sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==", "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^6.0.3" - } + "license": "MIT" }, "node_modules/@kurkle/color": { "version": "0.3.4", @@ -4205,6 +4196,7 @@ "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": "*", @@ -4215,6 +4207,7 @@ "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": "*", @@ -4225,6 +4218,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, "license": "MIT" }, "node_modules/@types/express": { @@ -4318,6 +4312,7 @@ "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/lodash": { @@ -4345,12 +4340,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.0.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.12.tgz", - "integrity": "sha512-LtOrbvDf5ndC9Xi+4QZjVL0woFymF/xSTKZKPgrrl7H7XoeDvnD+E2IclKVDyaK9UM756W/3BXqSU+JEHopA9g==", + "version": "24.2.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.1.tgz", + "integrity": "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==", + "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.8.0" + "undici-types": "~7.10.0" } }, "node_modules/@types/node-forge": { @@ -4462,17 +4458,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.36.0.tgz", - "integrity": "sha512-lZNihHUVB6ZZiPBNgOQGSxUASI7UJWhT8nHyUGCnaQ28XFCw98IfrMCG3rUl1uwUWoAvodJQby2KTs79UTcrAg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz", + "integrity": "sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.36.0", - "@typescript-eslint/type-utils": "8.36.0", - "@typescript-eslint/utils": "8.36.0", - "@typescript-eslint/visitor-keys": "8.36.0", + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/type-utils": "8.39.0", + "@typescript-eslint/utils": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -4486,9 +4482,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.36.0", + "@typescript-eslint/parser": "^8.39.0", "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -4502,16 +4498,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.36.0.tgz", - "integrity": "sha512-FuYgkHwZLuPbZjQHzJXrtXreJdFMKl16BFYyRrLxDhWr6Qr7Kbcu2s1Yhu8tsiMXw1S0W1pjfFfYEt+R604s+Q==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.0.tgz", + "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.36.0", - "@typescript-eslint/types": "8.36.0", - "@typescript-eslint/typescript-estree": "8.36.0", - "@typescript-eslint/visitor-keys": "8.36.0", + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "debug": "^4.3.4" }, "engines": { @@ -4523,18 +4519,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.36.0.tgz", - "integrity": "sha512-JAhQFIABkWccQYeLMrHadu/fhpzmSQ1F1KXkpzqiVxA/iYI6UnRt2trqXHt1sYEcw1mxLnB9rKMsOxXPxowN/g==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz", + "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.36.0", - "@typescript-eslint/types": "^8.36.0", + "@typescript-eslint/tsconfig-utils": "^8.39.0", + "@typescript-eslint/types": "^8.39.0", "debug": "^4.3.4" }, "engines": { @@ -4545,18 +4541,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.36.0.tgz", - "integrity": "sha512-wCnapIKnDkN62fYtTGv2+RY8FlnBYA3tNm0fm91kc2BjPhV2vIjwwozJ7LToaLAyb1ca8BxrS7vT+Pvvf7RvqA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz", + "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.36.0", - "@typescript-eslint/visitor-keys": "8.36.0" + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4567,9 +4563,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.36.0.tgz", - "integrity": "sha512-Nhh3TIEgN18mNbdXpd5Q8mSCBnrZQeY9V7Ca3dqYvNDStNIGRmJA6dmrIPMJ0kow3C7gcQbpsG2rPzy1Ks/AnA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz", + "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==", "dev": true, "license": "MIT", "engines": { @@ -4580,18 +4576,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.36.0.tgz", - "integrity": "sha512-5aaGYG8cVDd6cxfk/ynpYzxBRZJk7w/ymto6uiyUFtdCozQIsQWh7M28/6r57Fwkbweng8qAzoMCPwSJfWlmsg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz", + "integrity": "sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.36.0", - "@typescript-eslint/utils": "8.36.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0", + "@typescript-eslint/utils": "8.39.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -4604,13 +4601,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.36.0.tgz", - "integrity": "sha512-xGms6l5cTJKQPZOKM75Dl9yBfNdGeLRsIyufewnxT4vZTrjC0ImQT4fj8QmtJK84F58uSh5HVBSANwcfiXxABQ==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz", + "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==", "dev": true, "license": "MIT", "engines": { @@ -4622,16 +4619,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.36.0.tgz", - "integrity": "sha512-JaS8bDVrfVJX4av0jLpe4ye0BpAaUW7+tnS4Y4ETa3q7NoZgzYbN9zDQTJ8kPb5fQ4n0hliAt9tA4Pfs2zA2Hg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz", + "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.36.0", - "@typescript-eslint/tsconfig-utils": "8.36.0", - "@typescript-eslint/types": "8.36.0", - "@typescript-eslint/visitor-keys": "8.36.0", + "@typescript-eslint/project-service": "8.39.0", + "@typescript-eslint/tsconfig-utils": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -4647,7 +4644,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { @@ -4690,16 +4687,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.36.0.tgz", - "integrity": "sha512-VOqmHu42aEMT+P2qYjylw6zP/3E/HvptRwdn/PZxyV27KhZg2IOszXod4NcXisWzPAGSS4trE/g4moNj6XmH2g==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.36.0", - "@typescript-eslint/types": "8.36.0", - "@typescript-eslint/typescript-estree": "8.36.0" + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4710,17 +4707,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.36.0.tgz", - "integrity": "sha512-vZrhV2lRPWDuGoxcmrzRZyxAggPL+qp3WzUrlZD+slFueDiYHxeBa34dUXPuC0RmGKzl4lS5kFJYvKCq9cnNDA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz", + "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.36.0", + "@typescript-eslint/types": "8.39.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -4748,6 +4745,7 @@ "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", @@ -4758,24 +4756,28 @@ "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", @@ -4787,12 +4789,14 @@ "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", @@ -4805,6 +4809,7 @@ "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" @@ -4814,6 +4819,7 @@ "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" @@ -4823,12 +4829,14 @@ "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", @@ -4845,6 +4853,7 @@ "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", @@ -4858,6 +4867,7 @@ "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", @@ -4870,6 +4880,7 @@ "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", @@ -4884,6 +4895,7 @@ "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", @@ -4941,12 +4953,14 @@ "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/accepts": { @@ -4967,6 +4981,7 @@ "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" @@ -4975,6 +4990,19 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -4989,6 +5017,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -5005,6 +5034,7 @@ "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" @@ -5022,6 +5052,7 @@ "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", @@ -5038,17 +5069,9 @@ "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/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -5202,14 +5225,14 @@ } }, "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==", + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.4", + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { @@ -5217,27 +5240,27 @@ } }, "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==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.3", - "core-js-compat": "^3.40.0" + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.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==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.4" + "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5250,27 +5273,6 @@ "dev": true, "license": "MIT" }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "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/base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", @@ -5301,15 +5303,6 @@ "node": ">=4" } }, - "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==", - "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", @@ -5433,9 +5426,10 @@ "license": "MIT" }, "node_modules/browserslist": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", - "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", + "version": "4.25.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.2.tgz", + "integrity": "sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -5452,8 +5446,8 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001718", - "electron-to-chromium": "^1.5.160", + "caniuse-lite": "^1.0.30001733", + "electron-to-chromium": "^1.5.199", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, @@ -5464,35 +5458,11 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "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": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "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": { @@ -5522,24 +5492,24 @@ } }, "node_modules/cacheable": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.0.tgz", - "integrity": "sha512-SSgQTAnhd7WlJXnGlIi4jJJOiHzgnM5wRMEPaXAU4kECTAMpBoYKoZ9i5zHmclIEZbxcu3j7yY/CF8DTmwIsHg==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.3.tgz", + "integrity": "sha512-M6p10iJ/VT0wT7TLIGUnm958oVrU2cUK8pQAVU21Zu7h8rbk/PeRtRWrvHJBql97Bhzk3g1N6+2VKC+Rjxna9Q==", "dev": true, "license": "MIT", "dependencies": { - "hookified": "^1.8.2", - "keyv": "^5.3.3" + "hookified": "^1.10.0", + "keyv": "^5.4.0" } }, "node_modules/cacheable/node_modules/keyv": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.4.tgz", - "integrity": "sha512-ypEvQvInNpUe+u+w8BIcPkQvEqXquyyibWE/1NB5T2BTzIpS5cGEV1LZskDzPSTvNAaT4+5FutvzlvnkxOSKlw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.0.tgz", + "integrity": "sha512-QG7qR2tijh1ftOvClut4YKKg1iW6cx3GZsKoGyJPxHkGWK9oJhG9P3j5deP0QQOGDowBMVQFaP+Vm4NpGYvmIQ==", "dev": true, "license": "MIT", "dependencies": { - "@keyv/serialize": "^1.0.3" + "@keyv/serialize": "^1.1.0" } }, "node_modules/call-bind-apply-helpers": { @@ -5608,9 +5578,10 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001723", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz", - "integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==", + "version": "1.0.30001734", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001734.tgz", + "integrity": "sha512-uhE1Ye5vgqju6OI71HTQqcBCZrvHugk0MjLak7Q+HfoBgoq5Bi+5YnwjP4fjDgrtYr/l8MVRBvzz9dPD4KyK0A==", + "dev": true, "funding": [ { "type": "opencollective", @@ -5693,6 +5664,7 @@ "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" @@ -5959,13 +5931,13 @@ } }, "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==", + "version": "3.45.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.0.tgz", + "integrity": "sha512-gRoVMBawZg0OnxaVv3zpqLLxaHmsubEGyTnqdpI/CEBvX4JadI1dMSHxagThprYRtSVbuQxvi6iUatdPxohHpA==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.25.0" + "browserslist": "^4.25.1" }, "funding": { "type": "opencollective", @@ -6021,22 +5993,21 @@ } }, "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.0.0.tgz", + "integrity": "sha512-aU8qlEK/nHYtVuN4p7UQgAwVljzMg8hB4YK5ThRqD2l/ziSnryncPNn7bMLt5cFYsKVKBh8HqLqyCoTupEUu7Q==", "dev": true, "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.1" + "@epic-web/invariant": "^1.0.0", + "cross-spawn": "^7.0.6" }, "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" + "cross-env": "dist/bin/cross-env.js", + "cross-env-shell": "dist/bin/cross-env-shell.js" }, "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" + "node": ">=20" } }, "node_modules/cross-spawn": { @@ -6708,9 +6679,10 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.167", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.167.tgz", - "integrity": "sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==", + "version": "1.5.199", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.199.tgz", + "integrity": "sha512-3gl0S7zQd88kCAZRO/DnxtBKuhMO4h0EaQIN3YgZfV6+pW+5+bf2AdQeHNESCoaQqo/gjGVYEf2YM4O5HJQqpQ==", + "dev": true, "license": "ISC" }, "node_modules/emoji-regex": { @@ -6720,15 +6692,6 @@ "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==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", @@ -6834,6 +6797,7 @@ "version": "5.18.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -6924,6 +6888,7 @@ "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": { @@ -6943,6 +6908,7 @@ "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" @@ -6969,20 +6935,20 @@ } }, "node_modules/eslint": { - "version": "9.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz", - "integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==", + "version": "9.33.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz", + "integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.1", - "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.14.0", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.1", + "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.29.0", - "@eslint/plugin-kit": "^0.3.1", + "@eslint/js": "9.33.0", + "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -7047,6 +7013,7 @@ "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", @@ -7178,6 +7145,7 @@ "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" @@ -7190,6 +7158,7 @@ "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" @@ -7199,6 +7168,7 @@ "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" @@ -7241,6 +7211,7 @@ "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" @@ -7445,6 +7416,7 @@ "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": { @@ -7481,6 +7453,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { @@ -7494,6 +7467,7 @@ "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", @@ -7552,44 +7526,6 @@ "node": ">=16.0.0" } }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/filesize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/filesize/-/filesize-7.0.0.tgz", @@ -7903,6 +7839,7 @@ "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/global-modules": { @@ -7947,9 +7884,9 @@ } }, "node_modules/globals": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.2.0.tgz", - "integrity": "sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==", + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz", + "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==", "dev": true, "license": "MIT", "engines": { @@ -7983,6 +7920,7 @@ "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/graphemer": { @@ -8025,6 +7963,7 @@ "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" @@ -8067,9 +8006,9 @@ } }, "node_modules/hookified": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.9.1.tgz", - "integrity": "sha512-u3pxtGhKjcSXnGm1CX6aXS9xew535j3lkOCegbA6jdyh0BaAjTbXI4aslKstCr6zUNtoCxFGFKwjbSHdGrMB8g==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.11.0.tgz", + "integrity": "sha512-aDdIN3GyU5I6wextPplYdfmWCo+aLmjjVbntmX6HLD5RCi/xKsivYEBhnRD+d9224zFf008ZpLMPlWF0ZodYZw==", "dev": true, "license": "MIT" }, @@ -8331,27 +8270,6 @@ "postcss": "^8.1.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "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": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -8882,12 +8800,14 @@ "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/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { @@ -8901,6 +8821,7 @@ "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" @@ -9007,25 +8928,12 @@ "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": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -9205,6 +9113,7 @@ "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": { @@ -9258,6 +9167,7 @@ "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" @@ -9267,6 +9177,7 @@ "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" @@ -9276,9 +9187,9 @@ } }, "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==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.3.tgz", + "integrity": "sha512-tRA0+PsS4kLVijnN1w9jUu5lkxBwUk9E8SbgEB5dBJqchE6pVYdawROG6uQtpmAri7tdCK9i7b1bULeVWqS6Ag==", "dev": true, "license": "MIT", "dependencies": { @@ -9397,6 +9308,7 @@ "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/neo-blessed": { @@ -9452,6 +9364,7 @@ "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/normalize-path": { @@ -9849,6 +9762,7 @@ "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": { @@ -10936,9 +10850,9 @@ } }, "node_modules/postcss-preset-env": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.2.3.tgz", - "integrity": "sha512-zlQN1yYmA7lFeM1wzQI14z97mKoM8qGng+198w1+h6sCud/XxOjcKtApY9jWr7pXNS3yHDEafPlClSsWnkY8ow==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.2.4.tgz", + "integrity": "sha512-q+lXgqmTMdB0Ty+EQ31SuodhdfZetUlwCA/F0zRcd/XdxjzI+Rl2JhZNz5US2n/7t9ePsvuhCnEN4Bmu86zXlA==", "dev": true, "funding": [ { @@ -10952,7 +10866,7 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/postcss-cascade-layers": "^5.0.1", + "@csstools/postcss-cascade-layers": "^5.0.2", "@csstools/postcss-color-function": "^4.0.10", "@csstools/postcss-color-mix-function": "^3.0.10", "@csstools/postcss-color-mix-variadic-function-arguments": "^1.0.0", @@ -11300,6 +11214,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -11363,6 +11278,7 @@ "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" @@ -11594,6 +11510,7 @@ "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" @@ -11722,6 +11639,7 @@ "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", @@ -11746,9 +11664,9 @@ "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==", + "version": "1.90.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.90.0.tgz", + "integrity": "sha512-9GUyuksjw70uNpb1MTYWsH9MQHOHY6kwfnkafC24+7aOMZn9+rVMBxRbLvw756mrBFbIsFg6Xw9IkR2Fnn3k+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -11811,6 +11729,7 @@ "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", @@ -11830,6 +11749,7 @@ "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", @@ -11846,6 +11766,7 @@ "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" @@ -11858,6 +11779,7 @@ "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/select-hose": { @@ -11954,6 +11876,7 @@ "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" @@ -12414,6 +12337,7 @@ "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" @@ -12433,6 +12357,7 @@ "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", @@ -12605,9 +12530,9 @@ } }, "node_modules/stylelint": { - "version": "16.21.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.21.0.tgz", - "integrity": "sha512-ki3PpJGG7xhm3WtINoWGnlvqAmbqSexoRMbEMJzlwewSIOqPRKPlq452c22xAdEJISVi80r+I7KL9GPUiwFgbg==", + "version": "16.23.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.23.1.tgz", + "integrity": "sha512-dNvDTsKV1U2YtiUDfe9d2gp902veFeo3ecCWdGlmLm2WFrAV0+L5LoOj/qHSBABQwMsZPJwfC4bf39mQm1S5zw==", "dev": true, "funding": [ { @@ -12634,7 +12559,7 @@ "debug": "^4.4.1", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^10.1.1", + "file-entry-cache": "^10.1.3", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", @@ -12648,7 +12573,7 @@ "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", - "postcss": "^8.5.5", + "postcss": "^8.5.6", "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", "postcss-selector-parser": "^7.1.0", @@ -12724,25 +12649,25 @@ "license": "MIT" }, "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.1.1.tgz", - "integrity": "sha512-zcmsHjg2B2zjuBgjdnB+9q0+cWcgWfykIcsDkWDB4GTPtl1eXUA+gTI6sO0u01AqK3cliHryTU55/b2Ow1hfZg==", + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.1.3.tgz", + "integrity": "sha512-D+w75Ub8T55yor7fPgN06rkCAUbAYw2vpxJmmjv/GDAcvCnv9g7IvHhIZoxzRZThrXPFI2maeY24pPbtyYU7Lg==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^6.1.10" + "flat-cache": "^6.1.12" } }, "node_modules/stylelint/node_modules/flat-cache": { - "version": "6.1.10", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.10.tgz", - "integrity": "sha512-B6/v1f0NwjxzmeOhzfXPGWpKBVA207LS7lehaVKQnFrVktcFRfkzjZZ2gwj2i1TkEUMQht7ZMJbABUT5N+V1Nw==", + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.12.tgz", + "integrity": "sha512-U+HqqpZPPXP5d24bWuRzjGqVqUcw64k4nZAbruniDwdRg0H10tvN7H6ku1tjhA4rg5B9GS3siEvwO2qjJJ6f8Q==", "dev": true, "license": "MIT", "dependencies": { - "cacheable": "^1.10.0", + "cacheable": "^1.10.3", "flatted": "^3.3.3", - "hookified": "^1.9.1" + "hookified": "^1.10.0" } }, "node_modules/stylelint/node_modules/globby": { @@ -13033,6 +12958,7 @@ "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" @@ -13055,6 +12981,7 @@ "version": "5.42.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.42.0.tgz", "integrity": "sha512-UYCvU9YQW2f/Vwl+P0GfhxJxbUGLwd+5QrrGgLajzWAtC/23AX0vcise32kkP7Eu0Wu9VlzzHAXkLObgjQfFlQ==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -13073,6 +13000,7 @@ "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", @@ -13107,6 +13035,7 @@ "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": "*", @@ -13121,6 +13050,7 @@ "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" @@ -13136,6 +13066,7 @@ "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/thingies": { @@ -13348,9 +13279,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -13376,9 +13307,10 @@ } }, "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==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "dev": true, "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -13449,6 +13381,7 @@ "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", @@ -13479,6 +13412,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -13532,6 +13466,7 @@ "version": "2.4.4", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "dev": true, "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", @@ -13552,21 +13487,23 @@ } }, "node_modules/webpack": { - "version": "5.99.9", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", - "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", + "version": "5.101.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.0.tgz", + "integrity": "sha512-B4t+nJqytPeuZlHuIKTbalhljIFXeNRqrUGAQgTGlfOl2lXXKXw+yZu6bicycP+PUlM44CxBjCFD6aciKFT3LQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", + "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", + "enhanced-resolve": "^5.17.2", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -13580,7 +13517,7 @@ "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" @@ -13879,9 +13816,10 @@ } }, "node_modules/webpack-sources": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.2.tgz", - "integrity": "sha512-ykKKus8lqlgXX/1WjudpIEjqsafjOTcOJqxnAbMLAu/KCsDCJ6GBtvscewvTkrn24HsnvFwrSCbenFrhtcCsAA==", + "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" diff --git a/package.json b/package.json index 1022f54..b836699 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "adminator-admin-dashboard", - "version": "2.7.1", + "version": "2.8.0", "private": false, "description": "Modern jQuery-free Bootstrap 5 Admin Dashboard Template with Dark Mode", "main": "dist/index.html", @@ -52,67 +52,55 @@ "release:minified": "npm run clean && NODE_ENV=production MINIFY=true cross-env webpack", "release:unminified": "npm run clean && NODE_ENV=production MINIFY=false cross-env webpack", "preview": "cross-env webpack server", - "type-check": "tsc --noEmit", - "type-check:watch": "tsc --noEmit --watch", - "build:types": "tsc --emitDeclarationOnly --outDir types", "lint:js": "eslint ./src ./webpack ./*.js -f table --ext .js --ext .jsx", - "lint:ts": "eslint ./src ./webpack ./*.ts -f table --ext .ts --ext .tsx", "lint:scss": "stylelint ./src/**/*.scss", - "lint": "npm run lint:js && npm run lint:ts && npm run lint:scss", - "prepublishOnly": "npm run type-check && npm run build", + "lint": "npm run lint:js && npm run lint:scss", + "prepublishOnly": "npm run lint && npm run build", "postpublish": "echo 'Package published successfully! View at: https://www.npmjs.com/package/adminator-admin-dashboard'" }, "devDependencies": { - "@babel/core": "^7.27.4", - "@babel/eslint-parser": "^7.27.5", - "@babel/plugin-transform-runtime": "^7.27.4", - "@babel/preset-env": "^7.27.2", - "@babel/runtime": "^7.27.6", - "@eslint/js": "^9.29.0", - "@types/lodash": "^4.17.20", - "@types/masonry-layout": "^4.2.8", - "@types/node": "^24.0.12", - "@typescript-eslint/eslint-plugin": "^8.36.0", - "@typescript-eslint/parser": "^8.36.0", + "@babel/core": "^7.28.0", + "@babel/eslint-parser": "^7.28.0", + "@babel/plugin-transform-runtime": "^7.28.0", + "@babel/preset-env": "^7.28.0", + "@eslint/js": "^9.33.0", "babel-loader": "^10.0.0", "case-sensitive-paths-webpack-plugin": "^2.4.0", "copy-webpack-plugin": "^13.0.0", - "cross-env": "^7.0.3", + "cross-env": "^10.0.0", "css-loader": "^7.1.2", "css-minimizer-webpack-plugin": "^7.0.2", - "eslint": "^9.29.0", + "eslint": "^9.33.0", "eslint-formatter-table": "^7.32.1", - "globals": "^16.2.0", + "globals": "^16.3.0", "html-webpack-plugin": "^5.6.3", - "mini-css-extract-plugin": "^2.9.2", + "mini-css-extract-plugin": "^2.9.3", "postcss": "^8.5.6", "postcss-loader": "^8.1.1", - "postcss-preset-env": "^10.2.3", - "sass": "^1.89.2", + "postcss-preset-env": "^10.2.4", + "sass": "^1.90.0", "sass-loader": "^16.0.5", "shx": "^0.4.0", "style-loader": "^4.0.0", - "stylelint": "^16.21.0", + "stylelint": "^16.23.1", "stylelint-config-standard": "^38.0.0", - "ts-loader": "^9.5.2", - "typescript": "^5.8.3", - "webpack": "^5.99.9", + "webpack": "^5.101.0", "webpack-cli": "^6.0.1", "webpack-dashboard": "^3.3.8", "webpack-dev-server": "^5.2.2" }, "dependencies": { - "@fullcalendar/core": "^6.1.17", - "@fullcalendar/daygrid": "^6.1.17", - "@fullcalendar/interaction": "^6.1.17", - "@fullcalendar/list": "^6.1.17", - "@fullcalendar/timegrid": "^6.1.17", + "@babel/runtime": "^7.28.2", + "@fullcalendar/core": "^6.1.19", + "@fullcalendar/daygrid": "^6.1.19", + "@fullcalendar/interaction": "^6.1.19", + "@fullcalendar/list": "^6.1.19", + "@fullcalendar/timegrid": "^6.1.19", "@popperjs/core": "^2.11.8", "bootstrap": "^5.3.7", "brand-colors": "^2.1.1", "chart.js": "^4.5.0", "dayjs": "^1.11.13", - "file-loader": "^6.2.0", "jsvectormap": "^1.6.0", "load-google-maps-api": "^2.0.2", "lodash": "^4.17.21", diff --git a/src/assets/scripts/app.js b/src/assets/scripts/app.js index ccf80d6..794cd7b 100644 --- a/src/assets/scripts/app.js +++ b/src/assets/scripts/app.js @@ -7,9 +7,9 @@ // Bootstrap JS components removed to eliminate jQuery dependency import { DOM } from './utils/dom'; import DateUtils from './utils/date'; -import { ThemeManager } from './utils/theme'; -import { Sidebar } from './components/Sidebar'; -import { ChartComponent } from './components/Chart'; +import ThemeManager from './utils/theme'; +import Sidebar from './components/Sidebar'; +import ChartComponent from './components/Chart'; // Import styles import '../styles/index.scss'; diff --git a/src/assets/scripts/app.ts b/src/assets/scripts/app.ts deleted file mode 100644 index 142f8a8..0000000 --- a/src/assets/scripts/app.ts +++ /dev/null @@ -1,757 +0,0 @@ -/** - * Modern Adminator Application with TypeScript - * Main application entry point with enhanced mobile support and type safety - */ - -import { DOM } from './utils/dom'; -import { ThemeManager } from './utils/theme'; -import { Sidebar } from './components/Sidebar'; -import { ChartComponent } from './components/Chart'; -import UIComponents from './ui'; -import DataTable from './datatable'; -import DatePicker from './datepicker'; -import VectorMaps from './vectorMaps'; -import type { ComponentInterface } from '../../types'; - -// Import styles -import '../styles/index.scss'; - -// Import other modules that don't need immediate modernization -import './fullcalendar'; -import './masonry'; -import './popover'; -import './scrollbar'; -import './search'; -import './skycons'; -import './chat'; -import './email'; -import './googleMaps'; - -// Type definitions for the application -export interface AdminatorAppOptions { - autoInit?: boolean; - theme?: 'light' | 'dark' | 'auto'; - mobile?: { - enhanced?: boolean; - fullWidthSearch?: boolean; - disableDropdowns?: boolean; - }; - debug?: boolean; -} - -export interface AdminatorAppState { - isInitialized: boolean; - isMobile: boolean; - currentTheme: 'light' | 'dark' | 'auto'; - components: Map; -} - -export interface AdminatorAppEvents { - ready: CustomEvent<{ app: AdminatorApp }>; - themeChanged: CustomEvent<{ theme: string; previousTheme: string }>; - mobileStateChanged: CustomEvent<{ isMobile: boolean }>; - componentAdded: CustomEvent<{ name: string; component: ComponentInterface }>; - componentRemoved: CustomEvent<{ name: string }>; -} - -declare global { - interface Window { - AdminatorApp?: AdminatorApp; - } -} - -export class AdminatorApp { - public options: AdminatorAppOptions; - public state: AdminatorAppState; - - private resizeTimeout: number | null = null; - private eventHandlers: Map = new Map(); - private themeManager: typeof ThemeManager; - - constructor(options: AdminatorAppOptions = {}) { - this.options = { - autoInit: true, - theme: 'auto', - mobile: { - enhanced: true, - fullWidthSearch: true, - disableDropdowns: false, - }, - debug: false, - ...options, - }; - - this.themeManager = ThemeManager; - - this.state = { - isInitialized: false, - isMobile: this.checkMobileState(), - currentTheme: 'light', - components: new Map(), - }; - - if (this.options.autoInit) { - // Initialize when DOM is ready - DOM.ready(() => { - this.init(); - }); - } - } - - /** - * Initialize the application - */ - public init(): void { - if (this.state.isInitialized) return; - - this.log('Initializing Adminator App...'); - - try { - // Initialize core components - this.initSidebar(); - this.initCharts(); - this.initDataTables(); - this.initDatePickers(); - this.initUIComponents(); - this.initVectorMaps(); - this.initTheme(); - this.initMobileEnhancements(); - - // Setup global event listeners - this.setupGlobalEvents(); - - this.state.isInitialized = true; - this.log('Adminator App initialized successfully'); - - // Dispatch custom event for other scripts - this.dispatchEvent('ready', { app: this }); - - } catch (error) { - console.error('Error initializing Adminator App:', error); - } - } - - /** - * Initialize Sidebar component - */ - private initSidebar(): void { - if (DOM.exists('.sidebar')) { - const sidebar = new Sidebar(); - this.addComponent('sidebar', sidebar); - this.log('Sidebar component initialized'); - } - } - - /** - * Initialize Chart components - */ - private initCharts(): void { - // Check if we have any chart elements - const hasCharts = DOM.exists('#sparklinedash') || - DOM.exists('.sparkline') || - DOM.exists('.sparkbar') || - DOM.exists('.sparktri') || - DOM.exists('.sparkdisc') || - DOM.exists('.sparkbull') || - DOM.exists('.sparkbox') || - DOM.exists('.easy-pie-chart') || - DOM.exists('#line-chart') || - DOM.exists('#area-chart') || - DOM.exists('#scatter-chart') || - DOM.exists('#bar-chart'); - - if (hasCharts) { - const charts = new ChartComponent(); - this.addComponent('charts', charts); - this.log('Chart components initialized'); - } - } - - /** - * Initialize DataTables - */ - private initDataTables(): void { - const dataTableElement = DOM.select('#dataTable'); - if (dataTableElement) { - DataTable.init(); - this.log('DataTable initialized'); - } - } - - /** - * Initialize Date Pickers - */ - private initDatePickers(): void { - const startDatePickers = DOM.selectAll('.start-date'); - const endDatePickers = DOM.selectAll('.end-date'); - - if (startDatePickers.length > 0 || endDatePickers.length > 0) { - DatePicker.init(); - this.log('Date pickers initialized'); - } - } - - /** - * Initialize UI Components - */ - private initUIComponents(): void { - UIComponents.init(); - this.log('UI components initialized'); - } - - /** - * Initialize Vector Maps - */ - private initVectorMaps(): void { - if (DOM.exists('#world-map-marker')) { - VectorMaps.init(); - this.log('Vector maps initialized'); - } - } - - /** - * Initialize theme system with toggle - */ - private initTheme(): void { - this.log('Initializing theme system...'); - - // Initialize theme system first - this.themeManager.init(); - this.state.currentTheme = this.themeManager.current(); - - // Inject theme toggle if missing - setTimeout(() => { - this.injectThemeToggle(); - }, 100); - } - - /** - * Inject theme toggle button - */ - private injectThemeToggle(): void { - const navRight = DOM.select('.nav-right'); - - if (navRight && !DOM.exists('#theme-toggle')) { - const li = document.createElement('li'); - li.className = 'theme-toggle d-flex ai-c'; - li.innerHTML = ` -
- - - -
- `; - - // Insert before user dropdown (last item) - const lastItem = navRight.querySelector('li:last-child'); - if (lastItem && lastItem.parentNode === navRight) { - navRight.insertBefore(li, lastItem); - } else { - navRight.appendChild(li); - } - - this.setupThemeToggle(); - this.log('Theme toggle injected'); - } - } - - /** - * Setup theme toggle functionality - */ - private setupThemeToggle(): void { - const toggle = DOM.select('#theme-toggle') as HTMLInputElement; - if (!toggle) return; - - // Set initial state - toggle.checked = this.state.currentTheme === 'dark'; - - // Add change handler - const changeHandler = (): void => { - const newTheme = toggle.checked ? 'dark' : 'light'; - const previousTheme = this.state.currentTheme; - - this.themeManager.apply(newTheme); - this.state.currentTheme = newTheme; - - this.dispatchEvent('themeChanged', { theme: newTheme, previousTheme }); - }; - - DOM.on(toggle, 'change', changeHandler); - this.eventHandlers.set('theme-toggle', changeHandler); - - // Listen for theme changes from other sources - const themeChangeHandler = (event: CustomEvent): void => { - const newTheme = event.detail.theme; - toggle.checked = newTheme === 'dark'; - this.state.currentTheme = newTheme; - - // Update charts when theme changes - const charts = this.getComponent('charts') as ChartComponent; - if (charts && typeof charts.redrawCharts === 'function') { - charts.redrawCharts(); - } - }; - - window.addEventListener('adminator:themeChanged', themeChangeHandler as EventListener); - this.eventHandlers.set('theme-change', themeChangeHandler as EventListener); - } - - /** - * Initialize mobile-specific enhancements - */ - private initMobileEnhancements(): void { - if (!this.options.mobile?.enhanced) return; - - this.log('Initializing mobile enhancements...'); - this.enhanceMobileDropdowns(); - this.enhanceMobileSearch(); - - // Prevent horizontal scroll on mobile - if (this.state.isMobile) { - document.body.style.overflowX = 'hidden'; - } - } - - /** - * Setup global event listeners - */ - private setupGlobalEvents(): void { - // Global click handler - const globalClickHandler = (event: Event): void => { - this.handleGlobalClick(event); - }; - DOM.on(document, 'click', globalClickHandler); - this.eventHandlers.set('global-click', globalClickHandler); - - // Window resize handler with debouncing - const resizeHandler = (): void => { - if (this.resizeTimeout) { - clearTimeout(this.resizeTimeout); - } - this.resizeTimeout = window.setTimeout(() => { - this.handleResize(); - }, 250); - }; - DOM.on(window, 'resize', resizeHandler); - this.eventHandlers.set('resize', resizeHandler); - - this.log('Global event listeners set up'); - } - - /** - * Handle window resize events - */ - private handleResize(): void { - const wasMobile = this.state.isMobile; - this.state.isMobile = this.checkMobileState(); - - if (wasMobile !== this.state.isMobile) { - this.dispatchEvent('mobileStateChanged', { isMobile: this.state.isMobile }); - } - - this.log('Window resized, updating mobile features'); - - // Close all mobile-specific overlays when switching to desktop - if (!this.state.isMobile) { - document.body.style.overflow = ''; - document.body.style.overflowX = ''; - - // Close dropdowns - const dropdowns = DOM.selectAll('.nav-right .dropdown'); - dropdowns.forEach(dropdown => { - dropdown.classList.remove('show'); - const menu = dropdown.querySelector('.dropdown-menu'); - if (menu) menu.classList.remove('show'); - }); - - // Close search - this.closeSearch(); - } else { - // Re-enable mobile overflow protection - document.body.style.overflowX = 'hidden'; - } - - // Re-apply mobile enhancements - if (this.options.mobile?.enhanced) { - this.enhanceMobileDropdowns(); - this.enhanceMobileSearch(); - } - } - - /** - * Handle global click events - */ - private handleGlobalClick(event: Event): void { - const target = event.target as HTMLElement; - - // Close mobile dropdowns when clicking outside - if (!target.closest('.dropdown')) { - const dropdowns = DOM.selectAll('.nav-right .dropdown'); - dropdowns.forEach(dropdown => { - dropdown.classList.remove('show'); - const menu = dropdown.querySelector('.dropdown-menu'); - if (menu) menu.classList.remove('show'); - }); - document.body.style.overflow = ''; - } - - // Close search when clicking outside - if (!target.closest('.search-box') && !target.closest('.search-input')) { - this.closeSearch(); - } - } - - /** - * Check if we're on a mobile device - */ - private checkMobileState(): boolean { - return window.innerWidth <= 768; - } - - /** - * Enhanced mobile dropdown handling - */ - private enhanceMobileDropdowns(): void { - if (!this.state.isMobile || this.options.mobile?.disableDropdowns) return; - - const dropdowns = DOM.selectAll('.nav-right .dropdown'); - - dropdowns.forEach(dropdown => { - const toggle = dropdown.querySelector('.dropdown-toggle') as HTMLElement; - const menu = dropdown.querySelector('.dropdown-menu') as HTMLElement; - - if (toggle && menu) { - // Remove existing listeners to prevent duplicates - const newToggle = toggle.cloneNode(true) as HTMLElement; - toggle.replaceWith(newToggle); - - // Add click functionality for mobile dropdowns - DOM.on(newToggle, 'click', (e: Event) => { - e.preventDefault(); - e.stopPropagation(); - - // Close search if open - this.closeSearch(); - - // Close other dropdowns first - dropdowns.forEach(otherDropdown => { - if (otherDropdown !== dropdown) { - otherDropdown.classList.remove('show'); - const otherMenu = otherDropdown.querySelector('.dropdown-menu'); - if (otherMenu) otherMenu.classList.remove('show'); - } - }); - - // Toggle current dropdown - const isOpen = dropdown.classList.contains('show'); - if (isOpen) { - dropdown.classList.remove('show'); - menu.classList.remove('show'); - document.body.style.overflow = ''; - document.body.classList.remove('mobile-menu-open'); - } else { - dropdown.classList.add('show'); - menu.classList.add('show'); - document.body.style.overflow = 'hidden'; - document.body.classList.add('mobile-menu-open'); - } - }); - - // Enhanced mobile close button functionality - DOM.on(menu, 'click', (e: Event) => { - const rect = menu.getBoundingClientRect(); - const clickY = (e as MouseEvent).clientY - rect.top; - - // If clicked in top 50px (close button area) - if (clickY <= 50) { - dropdown.classList.remove('show'); - menu.classList.remove('show'); - document.body.style.overflow = ''; - document.body.classList.remove('mobile-menu-open'); - e.preventDefault(); - e.stopPropagation(); - } - }); - } - }); - - // Close dropdowns on escape key - const escapeHandler = (e: Event): void => { - const keyEvent = e as KeyboardEvent; - if (keyEvent.key === 'Escape') { - dropdowns.forEach(dropdown => { - dropdown.classList.remove('show'); - const menu = dropdown.querySelector('.dropdown-menu'); - if (menu) menu.classList.remove('show'); - }); - document.body.style.overflow = ''; - document.body.classList.remove('mobile-menu-open'); - } - }; - - DOM.on(document, 'keydown', escapeHandler); - } - - /** - * Enhanced mobile search handling - */ - private enhanceMobileSearch(): void { - if (!this.options.mobile?.fullWidthSearch) return; - - const searchBox = DOM.select('.search-box') as HTMLElement; - const searchInput = DOM.select('.search-input') as HTMLElement; - - if (searchBox && searchInput) { - const searchToggle = searchBox.querySelector('a') as HTMLAnchorElement; - const searchField = searchInput.querySelector('input') as HTMLInputElement; - - if (searchToggle && searchField) { - // Remove existing listeners to prevent duplication - const newSearchToggle = searchToggle.cloneNode(true) as HTMLAnchorElement; - searchToggle.replaceWith(newSearchToggle); - - DOM.on(newSearchToggle, 'click', (e: Event) => { - e.preventDefault(); - e.stopPropagation(); - - // Close any open dropdowns first - const dropdowns = DOM.selectAll('.nav-right .dropdown'); - dropdowns.forEach(dropdown => { - dropdown.classList.remove('show'); - const menu = dropdown.querySelector('.dropdown-menu'); - if (menu) menu.classList.remove('show'); - }); - - // Toggle search state - const isActive = searchInput.classList.contains('active'); - const searchIcon = newSearchToggle.querySelector('i') as HTMLElement; - - if (isActive) { - this.closeSearch(); - } else { - this.openSearch(searchField, searchIcon); - } - }); - - // Handle search input - DOM.on(searchField, 'keypress', (e: Event) => { - const keyEvent = e as KeyboardEvent; - if (keyEvent.key === 'Enter') { - keyEvent.preventDefault(); - const query = searchField.value.trim(); - if (query) { - this.handleSearch(query); - } - } - }); - } - } - } - - /** - * Open search interface - */ - private openSearch(searchField: HTMLInputElement, searchIcon: HTMLElement): void { - const searchInput = DOM.select('.search-input') as HTMLElement; - - searchInput.classList.add('active'); - document.body.classList.add('search-open'); - - // Change icon to close - if (searchIcon) { - searchIcon.className = 'ti-close'; - } - - // Focus the input after a short delay - setTimeout(() => { - searchField.focus(); - }, 100); - } - - /** - * Close search interface - */ - private closeSearch(): void { - const searchBox = DOM.select('.search-box') as HTMLElement; - const searchInput = DOM.select('.search-input') as HTMLElement; - - if (searchBox && searchInput) { - searchInput.classList.remove('active'); - document.body.classList.remove('search-open'); - document.body.classList.remove('mobile-menu-open'); - - // Reset icon - const searchIcon = searchBox.querySelector('i') as HTMLElement; - if (searchIcon) { - searchIcon.className = 'ti-search'; - } - - // Clear input - const searchField = searchInput.querySelector('input') as HTMLInputElement; - if (searchField) { - searchField.value = ''; - searchField.blur(); - } - } - } - - /** - * Handle search query - */ - private handleSearch(query: string): void { - this.log(`Search query: ${query}`); - - // Implement your search logic here - // For demo, close search after "searching" - this.closeSearch(); - } - - /** - * Add component to the application - */ - public addComponent(name: string, component: ComponentInterface): void { - this.state.components.set(name, component); - this.dispatchEvent('componentAdded', { name, component }); - this.log(`Component added: ${name}`); - } - - /** - * Remove component from the application - */ - public removeComponent(name: string): void { - const component = this.state.components.get(name); - if (component) { - if (typeof component.destroy === 'function') { - component.destroy(); - } - this.state.components.delete(name); - this.dispatchEvent('componentRemoved', { name }); - this.log(`Component removed: ${name}`); - } - } - - /** - * Get a component by name - */ - public getComponent(name: string): ComponentInterface | undefined { - return this.state.components.get(name); - } - - /** - * Get all components - */ - public getComponents(): Map { - return new Map(this.state.components); - } - - /** - * Check if app is ready - */ - public isReady(): boolean { - return this.state.isInitialized; - } - - /** - * Get current application state - */ - public getState(): Readonly { - return { - ...this.state, - components: new Map(this.state.components), - }; - } - - /** - * Update application options - */ - public updateOptions(newOptions: Partial): void { - this.options = { ...this.options, ...newOptions }; - this.log('Options updated'); - } - - /** - * Dispatch custom event - */ - private dispatchEvent( - type: T, - detail: AdminatorAppEvents[T]['detail'] - ): void { - const event = new CustomEvent(`adminator:${type}`, { - detail, - bubbles: true, - }); - window.dispatchEvent(event); - } - - /** - * Log message if debugging is enabled - */ - private log(message: string): void { - if (this.options.debug) { - console.log(`[AdminatorApp] ${message}`); - } - } - - /** - * Destroy the application - */ - public destroy(): void { - this.log('Destroying Adminator App'); - - // Destroy all components - this.state.components.forEach((component, name) => { - if (typeof component.destroy === 'function') { - component.destroy(); - } - this.log(`Component destroyed: ${name}`); - }); - - // Remove event listeners - this.eventHandlers.forEach((_, name) => { - // Note: We'd need to track which element each handler was attached to - // For now, we'll rely on the browser's garbage collection - this.log(`Event handler removed: ${name}`); - }); - - // Clear state - this.state.components.clear(); - this.eventHandlers.clear(); - this.state.isInitialized = false; - - // Clear timeout - if (this.resizeTimeout) { - clearTimeout(this.resizeTimeout); - this.resizeTimeout = null; - } - } - - /** - * Refresh/reinitialize the application - */ - public refresh(): void { - this.log('Refreshing Adminator App'); - - if (this.state.isInitialized) { - this.destroy(); - } - - setTimeout(() => { - this.init(); - }, 100); - } -} - -// Initialize the application -const app = new AdminatorApp({ - debug: process.env.NODE_ENV === 'development', -}); - -// Make app globally available for debugging -window.AdminatorApp = app; - -// Export for module usage -export default app; \ No newline at end of file diff --git a/src/assets/scripts/components/Chart.ts b/src/assets/scripts/components/Chart.ts deleted file mode 100644 index 0f6799a..0000000 --- a/src/assets/scripts/components/Chart.ts +++ /dev/null @@ -1,1350 +0,0 @@ -/** - * Modern Chart Component with TypeScript - * Replaces jQuery Sparkline with Chart.js - */ - -import { Chart, ChartConfiguration, registerables, ChartType as ChartJSType } from 'chart.js'; -import type { ComponentInterface } from '../../../types'; -import { COLORS } from '../constants/colors'; - -// Register Chart.js components -Chart.register(...registerables); - -export interface SparklineConfig { - id: string; - data: number[]; - color: string; -} - -export interface ChartComponentOptions { - enableResize?: boolean; - resizeDebounceMs?: number; - enableAnimation?: boolean; -} - -export interface ChartDimensions { - width: number; - height: number; -} - -export type ChartElementType = 'sparkline' | 'sparkbar' | 'sparktri' | 'sparkdisc' | 'sparkbull' | 'sparkbox' | 'easypie'; - -export class ChartComponent implements ComponentInterface { - public name: string = 'ChartComponent'; - public element: HTMLElement; - public options: ChartComponentOptions; - public isInitialized: boolean = false; - - private charts: Map = new Map(); - private debounceTimer: number | null = null; - - constructor(element?: HTMLElement, options: ChartComponentOptions = {}) { - this.element = element || document.body; - this.options = { - enableResize: true, - resizeDebounceMs: 150, - enableAnimation: true, - ...options, - }; - - this.init(); - } - - /** - * Initialize the chart component - */ - public init(): void { - // Only disable resizing for small sparkline charts - this.createSparklines(); - this.createOtherCharts(); - - if (this.options.enableResize) { - this.setupResizeHandler(); - } - - this.isInitialized = true; - } - - /** - * Destroy the chart component - */ - public destroy(): void { - this.charts.forEach(chart => { - chart.destroy(); - }); - this.charts.clear(); - - if (this.debounceTimer) { - clearTimeout(this.debounceTimer); - this.debounceTimer = null; - } - - this.isInitialized = false; - } - - /** - * Create sparklines (only for dashboard page) - */ - private createSparklines(): void { - // Only create sparklines if we're on a page that has them - const sparklineExists = document.getElementById('sparklinedash'); - if (!sparklineExists) { - return; - } - - const sparklineConfigs: SparklineConfig[] = [ - { - id: 'sparklinedash', - data: [0, 5, 6, 10, 9, 12, 4, 9], - color: '#4caf50', - }, - { - id: 'sparklinedash2', - data: [0, 5, 6, 10, 9, 12, 4, 9], - color: '#9675ce', - }, - { - id: 'sparklinedash3', - data: [0, 5, 6, 10, 9, 12, 4, 9], - color: '#03a9f3', - }, - { - id: 'sparklinedash4', - data: [0, 5, 6, 10, 9, 12, 4, 9], - color: '#f96262', - }, - ]; - - sparklineConfigs.forEach(config => { - // Only create if the target element exists - if (document.getElementById(config.id)) { - this.createSparklineChart(config); - } - }); - } - - /** - * Create sparkline chart from configuration - */ - private createSparklineChart(config: SparklineConfig): void { - let canvas = document.getElementById(config.id) as HTMLCanvasElement; - - // Only proceed if we have a valid target element - if (!canvas) { - return; - } - - // If element exists but isn't a canvas, replace it with canvas - if (canvas.tagName !== 'CANVAS') { - const parent = canvas.parentNode; - if (!parent) { - return; - } - - // Create new canvas element - const newCanvas = document.createElement('canvas'); - newCanvas.id = config.id; - this.setCanvasDimensions(newCanvas, { width: 100, height: 20 }); - - // Replace the span with canvas - parent.replaceChild(newCanvas, canvas); - canvas = newCanvas; - } else { - // Set canvas dimensions to match original sparkline - this.setCanvasDimensions(canvas, { width: 100, height: 20 }); - } - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - const chartConfig: ChartConfiguration = { - type: 'bar', - data: { - labels: config.data.map((_, i) => i.toString()), - datasets: [{ - data: config.data, - backgroundColor: config.color, - borderColor: config.color, - borderWidth: 0, - barPercentage: 0.6, - categoryPercentage: 0.8, - }], - }, - options: { - responsive: false, - maintainAspectRatio: false, - animation: this.options.enableAnimation ? {} : false, - events: [], - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - plugins: { - legend: { - display: false, - }, - tooltip: { - enabled: false, - }, - }, - elements: { - bar: { - borderRadius: 1, - }, - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(config.id, chart); - } - - /** - * Set canvas dimensions - */ - private setCanvasDimensions(canvas: HTMLCanvasElement, dimensions: ChartDimensions): void { - canvas.width = dimensions.width; - canvas.height = dimensions.height; - canvas.style.width = `${dimensions.width}px`; - canvas.style.height = `${dimensions.height}px`; - } - - /** - * Create other chart types (only if they exist on the page) - */ - private createOtherCharts(): void { - // Determine if we're on the dashboard or charts page - const isChartsPage = document.getElementById('area-chart') !== null; - const isDashboard = !isChartsPage && document.getElementById('line-chart') !== null; - - // Create Monthly Stats chart with enhanced dual-line data (dashboard only) - if (isDashboard) { - this.createMonthlyStatsChart(); - } - - // Charts page specific charts (only on charts page) - if (isChartsPage) { - this.createChartsPageCharts(); - } - - // Only create charts if their target elements exist - if (document.getElementById('sparkline')) { - this.createLineChart('sparkline', [5, 6, 7, 9, 9, 5, 3, 2, 2, 4, 6, 7]); - } - - if (document.getElementById('compositebar')) { - this.createCompositeChart('compositebar', [4, 1, 5, 7, 9, 9, 8, 7, 6, 6, 4, 7, 8, 4, 3, 2, 2, 5, 6, 7]); - } - - // Regular sparklines with custom colors (only on pages that have them) - this.createCustomSparklines(); - - // Easy Pie Charts (only if they exist) - this.createEasyPieCharts(); - } - - /** - * Create enhanced Monthly Stats chart with dual lines and more data - */ - private createMonthlyStatsChart(): void { - const canvas = document.getElementById('line-chart') as HTMLCanvasElement; - if (!canvas) return; - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - // Enhanced data for monthly stats - const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; - const salesData = [120, 135, 145, 165, 180, 195, 210, 225, 240, 220, 200, 185]; - const profitData = [45, 52, 58, 62, 68, 75, 82, 88, 92, 85, 78, 72]; - - const chartConfig: ChartConfiguration = { - type: 'line', - data: { - labels: months, - datasets: [ - { - label: 'Sales ($K)', - data: salesData, - borderColor: '#4caf50', - backgroundColor: 'rgba(76, 175, 80, 0.1)', - borderWidth: 3, - pointRadius: 5, - pointHoverRadius: 7, - pointBackgroundColor: '#4caf50', - pointBorderColor: '#ffffff', - pointBorderWidth: 2, - tension: 0.4, - fill: false, - }, - { - label: 'Profit ($K)', - data: profitData, - borderColor: '#2196f3', - backgroundColor: 'rgba(33, 150, 243, 0.1)', - borderWidth: 3, - pointRadius: 5, - pointHoverRadius: 7, - pointBackgroundColor: '#2196f3', - pointBorderColor: '#ffffff', - pointBorderWidth: 2, - tension: 0.4, - fill: false, - }, - ], - }, - options: { - responsive: true, - maintainAspectRatio: false, - plugins: { - legend: { - display: true, - position: 'top', - labels: { - padding: 20, - font: { - size: 12, - weight: 600, - }, - }, - }, - tooltip: { - enabled: true, - cornerRadius: 8, - displayColors: true, - intersect: false, - mode: 'index', - callbacks: { - label(context) { - return `${context.dataset.label}: $${context.parsed.y}K`; - }, - }, - }, - }, - scales: { - x: { - grid: { - display: false, - }, - ticks: { - font: { - size: 11, - }, - }, - }, - y: { - beginAtZero: true, - grid: { - borderDash: [5, 5] as [number, number], - }, - ticks: { - font: { - size: 11, - }, - callback(value) { - return `$${value}K`; - }, - }, - }, - }, - interaction: { - intersect: false, - mode: 'index', - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set('line-chart', chart); - } - - /** - * Create line chart (only if target exists) - */ - private createLineChart(id: string, data: number[]): void { - let canvas = document.getElementById(id) as HTMLCanvasElement; - - // Only proceed if target element exists - if (!canvas) { - return; - } - - // If element exists but isn't a canvas, replace it with canvas - if (canvas.tagName !== 'CANVAS') { - const parent = canvas.parentNode; - if (!parent) { - return; - } - - // Create new canvas element - const newCanvas = document.createElement('canvas'); - newCanvas.id = id; - this.setCanvasDimensions(newCanvas, { width: 100, height: 20 }); - - // Replace element with canvas - parent.replaceChild(newCanvas, canvas); - canvas = newCanvas; - } else { - this.setCanvasDimensions(canvas, { width: 100, height: 20 }); - } - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - const chartConfig: ChartConfiguration = { - type: 'line', - data: { - labels: data.map((_, i) => i.toString()), - datasets: [{ - data, - borderColor: COLORS['blue-500'], - backgroundColor: 'transparent', - borderWidth: 1, - pointRadius: 0, - tension: 0.4, - }], - }, - options: { - responsive: false, - maintainAspectRatio: false, - animation: false, - events: [], - scales: { - x: { display: false }, - y: { display: false }, - }, - plugins: { - legend: { display: false }, - tooltip: { enabled: false }, - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(id, chart); - } - - /** - * Create composite chart (only if target exists) - */ - private createCompositeChart(id: string, data: number[]): void { - let canvas = document.getElementById(id) as HTMLCanvasElement; - - // Only proceed if target element exists - if (!canvas) { - return; - } - - // If element exists but isn't a canvas, replace it with canvas - if (canvas.tagName !== 'CANVAS') { - const parent = canvas.parentNode; - if (!parent) { - return; - } - - // Create new canvas element - const newCanvas = document.createElement('canvas'); - newCanvas.id = id; - this.setCanvasDimensions(newCanvas, { width: 100, height: 20 }); - - // Replace element with canvas - parent.replaceChild(newCanvas, canvas); - canvas = newCanvas; - } else { - this.setCanvasDimensions(canvas, { width: 100, height: 20 }); - } - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - const chartConfig: ChartConfiguration = { - type: 'bar', - data: { - labels: data.map((_, i) => i.toString()), - datasets: [ - { - type: 'bar', - data, - backgroundColor: '#aaf', - borderColor: '#aaf', - borderWidth: 0, - }, - { - type: 'line', - data, - borderColor: 'red', - backgroundColor: 'transparent', - borderWidth: 1, - pointRadius: 0, - tension: 0.4, - } as any, // Type assertion needed for mixed chart types - ], - }, - options: { - responsive: false, - maintainAspectRatio: false, - animation: false, - events: [], - scales: { - x: { display: false }, - y: { display: false }, - }, - plugins: { - legend: { display: false }, - tooltip: { enabled: false }, - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(id, chart); - } - - /** - * Create custom sparklines for different elements (only if they exist) - */ - private createCustomSparklines(): void { - const sparklineElements = document.querySelectorAll('.sparkline'); - const sparkbarElements = document.querySelectorAll('.sparkbar'); - const sparktriElements = document.querySelectorAll('.sparktri'); - const sparkdiscElements = document.querySelectorAll('.sparkdisc'); - const sparkbullElements = document.querySelectorAll('.sparkbull'); - const sparkboxElements = document.querySelectorAll('.sparkbox'); - - // Only create if we have elements - if (sparklineElements.length === 0 && sparkbarElements.length === 0 && - sparktriElements.length === 0 && sparkdiscElements.length === 0 && - sparkbullElements.length === 0 && sparkboxElements.length === 0) { - return; - } - - const values = [5, 4, 5, -2, 0, 3, -5, 6, 7, 9, 9, 5, -3, -2, 2, -4]; - const valuesAlt = [1, 1, 0, 1, -1, -1, 1, -1, 0, 0, 1, 1]; - - sparklineElements.forEach((element, index) => { - this.createCustomLineChart(element as HTMLElement, values, `sparkline-${index}`); - }); - - sparkbarElements.forEach((element, index) => { - this.createCustomBarChart(element as HTMLElement, values, `sparkbar-${index}`); - }); - - sparktriElements.forEach((element, index) => { - this.createTristateChart(element as HTMLElement, valuesAlt, `sparktri-${index}`); - }); - - sparkdiscElements.forEach((element, index) => { - this.createDiscreteChart(element as HTMLElement, values, `sparkdisc-${index}`); - }); - - sparkbullElements.forEach((element, index) => { - this.createBulletChart(element as HTMLElement, values, `sparkbull-${index}`); - }); - - sparkboxElements.forEach((element, index) => { - this.createBoxChart(element as HTMLElement, values, `sparkbox-${index}`); - }); - } - - /** - * Create custom line chart for sparkline elements - */ - private createCustomLineChart(element: HTMLElement, data: number[], id: string): void { - // Create canvas if it doesn't exist - let canvas = element.querySelector('canvas') as HTMLCanvasElement; - if (!canvas) { - canvas = document.createElement('canvas'); - this.setCanvasDimensions(canvas, { width: 100, height: 20 }); - element.appendChild(canvas); - } - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - const chartConfig: ChartConfiguration = { - type: 'line', - data: { - labels: data.map((_, i) => i.toString()), - datasets: [{ - data, - borderColor: COLORS['red-500'], - backgroundColor: 'transparent', - borderWidth: 2, - pointRadius: 3, - pointBackgroundColor: COLORS['red-500'], - tension: 0.4, - }], - }, - options: { - responsive: false, - maintainAspectRatio: false, - animation: false, // Disable animations to prevent resize triggers - events: [], // Disable all events to prevent resize - scales: { - x: { display: false }, - y: { display: false }, - }, - plugins: { - legend: { display: false }, - tooltip: { enabled: false }, // Disable tooltip to prevent events - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(id, chart); - } - - /** - * Create custom bar chart for sparkbar elements - */ - private createCustomBarChart(element: HTMLElement, data: number[], id: string): void { - // Create canvas if it doesn't exist - let canvas = element.querySelector('canvas') as HTMLCanvasElement; - if (!canvas) { - canvas = document.createElement('canvas'); - this.setCanvasDimensions(canvas, { width: 100, height: 20 }); - element.appendChild(canvas); - } - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - const chartConfig: ChartConfiguration = { - type: 'bar', - data: { - labels: data.map((_, i) => i.toString()), - datasets: [{ - data, - backgroundColor: data.map(val => val < 0 ? COLORS['deep-purple-500'] : '#39f'), - borderColor: data.map(val => val < 0 ? COLORS['deep-purple-500'] : '#39f'), - borderWidth: 1, - barPercentage: 0.8, - }], - }, - options: { - responsive: false, - maintainAspectRatio: false, - scales: { - x: { display: false }, - y: { display: false }, - }, - plugins: { - legend: { display: false }, - tooltip: { - enabled: true, - callbacks: { - label: (context) => `${context.parsed.y}°Celsius`, - }, - }, - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(id, chart); - } - - /** - * Setup resize handler for charts - */ - private setupResizeHandler(): void { - // Setup responsive resize for large charts only - window.addEventListener('resize', () => { - this.debounceResize(); - }); - - // Listen for sidebar toggle events - window.addEventListener('sidebar:toggle', () => { - this.debounceResize(); - }); - } - - /** - * Debounced resize handler - */ - private debounceResize(): void { - if (this.debounceTimer) { - clearTimeout(this.debounceTimer); - } - this.debounceTimer = window.setTimeout(() => { - this.redrawLargeChartsOnly(); - }, this.options.resizeDebounceMs || 150); - } - - /** - * Redraw only large charts, not sparklines - */ - private redrawLargeChartsOnly(): void { - const largeChartIds = [ - 'line-chart', 'area-chart', 'scatter-chart', 'bar-chart', - 'doughnut-chart', 'polar-chart', 'radar-chart', 'mixed-chart', 'bubble-chart', - ]; - - largeChartIds.forEach(id => { - const chart = this.charts.get(id); - if (chart && chart.options.responsive) { - chart.resize(); - } - }); - } - - /** - * Redraw all charts (used sparingly) - */ - public redrawCharts(): void { - this.charts.forEach((chart) => { - if (chart.options.responsive) { - chart.resize(); - } - }); - } - - /** - * Update chart data - */ - public updateChart(id: string, newData: number[]): void { - const chart = this.charts.get(id); - if (chart && chart.data.datasets[0]) { - chart.data.datasets[0].data = newData; - chart.update(); - } - } - - /** - * Get chart instance by id - */ - public getChart(id: string): Chart | undefined { - return this.charts.get(id); - } - - /** - * Get all chart instances - */ - public getAllCharts(): Map { - return new Map(this.charts); - } - - /** - * Create charts for the charts.html page - */ - private createChartsPageCharts(): void { - // Line Chart - this.createLargeChart('line-chart', 'line', { - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [{ - label: 'Dataset 1', - data: [65, 59, 80, 81, 56, 55, 40], - borderColor: 'rgb(75, 192, 192)', - backgroundColor: 'rgba(75, 192, 192, 0.2)', - tension: 0.4, - }], - }); - - // Area Chart - this.createLargeChart('area-chart', 'line', { - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [{ - label: 'Dataset 1', - data: [65, 59, 80, 81, 56, 55, 40], - borderColor: 'rgb(54, 162, 235)', - backgroundColor: 'rgba(54, 162, 235, 0.4)', - fill: true, - tension: 0.4, - }], - }); - - // Scatter Chart with more data points - this.createLargeChart('scatter-chart', 'scatter', { - datasets: [{ - label: 'Dataset 1', - data: [ - {x: -15, y: 8}, {x: -12, y: 12}, {x: -8, y: 3}, {x: -5, y: 15}, - {x: -2, y: 7}, {x: 0, y: 10}, {x: 3, y: 18}, {x: 6, y: 5}, - {x: 9, y: 22}, {x: 12, y: 8}, {x: 15, y: 14}, {x: 18, y: 19}, - {x: -10, y: 0}, {x: 10, y: 5}, {x: 0.5, y: 5.5}, {x: 7, y: 12}, - {x: -7, y: 17}, {x: 4, y: 9}, {x: 11, y: 16}, {x: -3, y: 11}, - ], - backgroundColor: 'rgba(255, 99, 132, 0.7)', - borderColor: 'rgb(255, 99, 132)', - borderWidth: 1, - }], - }); - - // Continue with other chart types... - this.createBarChart(); - this.createDoughnutChart(); - this.createPolarChart(); - this.createRadarChart(); - this.createMixedChart(); - this.createBubbleChart(); - } - - /** - * Create large chart for charts page - */ - private createLargeChart(id: string, type: ChartJSType, data: any): void { - const canvas = document.getElementById(id) as HTMLCanvasElement; - if (!canvas) return; - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - // Define chart-specific options - const chartOptions = this.getChartOptions(type); - - const chartConfig: ChartConfiguration = { - type, - data, - options: chartOptions, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(id, chart); - } - - /** - * Get chart-specific options based on chart type - */ - private getChartOptions(type: ChartJSType): any { - const baseOptions = { - responsive: true, - maintainAspectRatio: false, - plugins: { - legend: { - display: true, - position: 'top' as const, - labels: { - padding: 20, - font: { - size: 12, - weight: '600' as const, - }, - }, - }, - tooltip: { - enabled: true, - cornerRadius: 8, - displayColors: true, - }, - }, - }; - - // Chart type specific configurations - switch (type) { - case 'doughnut': - case 'pie': - return { - ...baseOptions, - plugins: { - ...baseOptions.plugins, - legend: { - ...baseOptions.plugins.legend, - position: 'right' as const, - }, - }, - interaction: { - intersect: false, - }, - }; - - case 'polarArea': - return { - ...baseOptions, - scales: { - r: { - pointLabels: { - display: true, - centerPointLabels: true, - font: { - size: 10, - }, - }, - grid: {}, - }, - }, - }; - - case 'radar': - return { - ...baseOptions, - scales: { - r: { - angleLines: { - display: true, - }, - grid: {}, - pointLabels: { - font: { - size: 11, - }, - }, - ticks: { - display: true, - font: { - size: 10, - }, - }, - }, - }, - }; - - case 'bubble': - return { - ...baseOptions, - scales: { - x: { - type: 'linear' as const, - position: 'bottom' as const, - grid: { - borderDash: [5, 5] as [number, number], - }, - ticks: { - font: { - size: 11, - }, - }, - }, - y: { - beginAtZero: true, - grid: { - borderDash: [5, 5] as [number, number], - }, - ticks: { - font: { - size: 11, - }, - }, - }, - }, - }; - - case 'scatter': - return { - ...baseOptions, - scales: { - x: { - type: 'linear' as const, - position: 'bottom' as const, - grid: { - borderDash: [5, 5] as [number, number], - }, - ticks: { - font: { - size: 11, - }, - }, - }, - y: { - grid: { - borderDash: [5, 5] as [number, number], - }, - ticks: { - font: { - size: 11, - }, - }, - }, - }, - }; - - default: - // For line, bar, area, mixed charts - return { - ...baseOptions, - scales: { - x: { - grid: { - borderDash: [5, 5] as [number, number], - }, - ticks: { - font: { - size: 11, - }, - }, - }, - y: { - beginAtZero: true, - grid: { - borderDash: [5, 5] as [number, number], - }, - ticks: { - font: { - size: 11, - }, - }, - }, - }, - }; - } - } - - // Additional chart creation methods... - private createBarChart(): void { - this.createLargeChart('bar-chart', 'bar', { - labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], - datasets: [{ - label: '# of Votes', - data: [12, 19, 3, 5, 2, 3], - backgroundColor: [ - 'rgba(255, 99, 132, 0.6)', - 'rgba(54, 162, 235, 0.6)', - 'rgba(255, 205, 86, 0.6)', - 'rgba(75, 192, 192, 0.6)', - 'rgba(153, 102, 255, 0.6)', - 'rgba(255, 159, 64, 0.6)', - ], - borderColor: [ - 'rgba(255, 99, 132, 1)', - 'rgba(54, 162, 235, 1)', - 'rgba(255, 205, 86, 1)', - 'rgba(75, 192, 192, 1)', - 'rgba(153, 102, 255, 1)', - 'rgba(255, 159, 64, 1)', - ], - borderWidth: 1, - }], - }); - } - - private createDoughnutChart(): void { - this.createLargeChart('doughnut-chart', 'doughnut', { - labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], - datasets: [{ - label: 'My First Dataset', - data: [300, 50, 100, 75, 120, 60], - backgroundColor: [ - 'rgba(255, 99, 132, 0.8)', - 'rgba(54, 162, 235, 0.8)', - 'rgba(255, 205, 86, 0.8)', - 'rgba(75, 192, 192, 0.8)', - 'rgba(153, 102, 255, 0.8)', - 'rgba(255, 159, 64, 0.8)', - ], - borderWidth: 2, - hoverOffset: 10, - }], - }); - } - - private createPolarChart(): void { - this.createLargeChart('polar-chart', 'polarArea', { - labels: ['Red', 'Green', 'Yellow', 'Grey', 'Blue'], - datasets: [{ - label: 'My First Dataset', - data: [11, 16, 7, 3, 14], - backgroundColor: [ - 'rgba(255, 99, 132, 0.7)', - 'rgba(75, 192, 192, 0.7)', - 'rgba(255, 205, 86, 0.7)', - 'rgba(201, 203, 207, 0.7)', - 'rgba(54, 162, 235, 0.7)', - ], - borderWidth: 2, - }], - }); - } - - private createRadarChart(): void { - this.createLargeChart('radar-chart', 'radar', { - labels: ['Speed', 'Reliability', 'Comfort', 'Safety', 'Efficiency', 'Innovation'], - datasets: [{ - label: 'Product A', - data: [65, 59, 90, 81, 56, 55], - fill: true, - backgroundColor: 'rgba(54, 162, 235, 0.2)', - borderColor: 'rgb(54, 162, 235)', - borderWidth: 2, - }], - }); - } - - private createMixedChart(): void { - this.createLargeChart('mixed-chart', 'bar', { - labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], - datasets: [{ - type: 'bar', - label: 'Sales', - data: [12, 19, 3, 5, 2, 3], - backgroundColor: 'rgba(54, 162, 235, 0.7)', - }, { - type: 'line', - label: 'Revenue', - data: [18, 25, 8, 15, 12, 18], - borderColor: 'rgb(255, 99, 132)', - tension: 0.4, - }], - }); - } - - private createBubbleChart(): void { - this.createLargeChart('bubble-chart', 'bubble', { - datasets: [{ - label: 'First Dataset', - data: [ - {x: 20, y: 30, r: 15}, - {x: 40, y: 10, r: 10}, - {x: 30, y: 40, r: 20}, - ], - backgroundColor: 'rgba(54, 162, 235, 0.6)', - borderColor: 'rgb(54, 162, 235)', - borderWidth: 2, - }], - }); - } - - /** - * Create tristate chart (for .sparktri elements) - */ - private createTristateChart(element: HTMLElement, data: number[], id: string): void { - let canvas = element.querySelector('canvas') as HTMLCanvasElement; - if (!canvas) { - canvas = document.createElement('canvas'); - this.setCanvasDimensions(canvas, { width: 100, height: 20 }); - element.appendChild(canvas); - } - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - const chartConfig: ChartConfiguration = { - type: 'bar', - data: { - labels: data.map((_, i) => i.toString()), - datasets: [{ - data: data.map(val => Math.abs(val)), - backgroundColor: data.map(val => { - if (val > 0) return COLORS['light-blue-500']; - if (val < 0) return '#f90'; - return '#000'; - }), - borderWidth: 1, - barPercentage: 0.8, - }], - }, - options: { - responsive: false, - maintainAspectRatio: false, - scales: { - x: { display: false }, - y: { display: false }, - }, - plugins: { - legend: { display: false }, - tooltip: { enabled: false }, - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(id, chart); - } - - /** - * Create discrete chart (for .sparkdisc elements) - */ - private createDiscreteChart(element: HTMLElement, data: number[], id: string): void { - let canvas = element.querySelector('canvas') as HTMLCanvasElement; - if (!canvas) { - canvas = document.createElement('canvas'); - this.setCanvasDimensions(canvas, { width: 100, height: 20 }); - element.appendChild(canvas); - } - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - const chartConfig: ChartConfiguration = { - type: 'scatter', - data: { - datasets: [{ - data: data.map((val, index) => ({x: index, y: val})), - backgroundColor: '#9f0', - borderColor: '#9f0', - pointRadius: 2, - showLine: false, - }], - }, - options: { - responsive: false, - maintainAspectRatio: false, - scales: { - x: { display: false }, - y: { display: false }, - }, - plugins: { - legend: { display: false }, - tooltip: { enabled: false }, - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(id, chart); - } - - /** - * Create bullet chart (for .sparkbull elements) - */ - private createBulletChart(element: HTMLElement, data: number[], id: string): void { - let canvas = element.querySelector('canvas') as HTMLCanvasElement; - if (!canvas) { - canvas = document.createElement('canvas'); - this.setCanvasDimensions(canvas, { width: 100, height: 20 }); - element.appendChild(canvas); - } - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - const chartConfig: ChartConfiguration = { - type: 'bar', - data: { - labels: [''], - datasets: [{ - data: [Math.max(...data)], - backgroundColor: COLORS['amber-500'], - borderColor: COLORS['amber-500'], - borderWidth: 1, - barPercentage: 0.6, - }], - }, - options: { - responsive: false, - maintainAspectRatio: false, - indexAxis: 'y', - scales: { - x: { display: false }, - y: { display: false }, - }, - plugins: { - legend: { display: false }, - tooltip: { enabled: false }, - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(id, chart); - } - - /** - * Create box chart (for .sparkbox elements) - */ - private createBoxChart(element: HTMLElement, data: number[], id: string): void { - let canvas = element.querySelector('canvas') as HTMLCanvasElement; - if (!canvas) { - canvas = document.createElement('canvas'); - this.setCanvasDimensions(canvas, { width: 100, height: 20 }); - element.appendChild(canvas); - } - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - // Box plot simplified as bar chart showing quartiles - const sortedData = [...data].sort((a, b) => a - b); - const q1 = sortedData[Math.floor(sortedData.length * 0.25)]; - const median = sortedData[Math.floor(sortedData.length * 0.5)]; - const q3 = sortedData[Math.floor(sortedData.length * 0.75)]; - - const chartConfig: ChartConfiguration = { - type: 'bar', - data: { - labels: ['Q1', 'Med', 'Q3'], - datasets: [{ - data: [q1, median, q3], - backgroundColor: '#9f0', - borderColor: '#9f0', - borderWidth: 1, - barPercentage: 0.8, - }], - }, - options: { - responsive: false, - maintainAspectRatio: false, - scales: { - x: { display: false }, - y: { display: false }, - }, - plugins: { - legend: { display: false }, - tooltip: { enabled: false }, - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(id, chart); - } - - /** - * Create Easy Pie Charts (replaces jQuery Easy Pie Chart) - */ - private createEasyPieCharts(): void { - const easyPieElements = document.querySelectorAll('.easy-pie-chart'); - - easyPieElements.forEach((element, index) => { - const htmlElement = element as HTMLElement; - const size = parseInt(htmlElement.dataset.size || '80'); - const percent = parseInt(htmlElement.dataset.percent || '0'); - const barColor = htmlElement.dataset.barColor || '#f44336'; - - // Create canvas for the pie chart - let canvas = element.querySelector('canvas') as HTMLCanvasElement; - if (!canvas) { - canvas = document.createElement('canvas'); - this.setCanvasDimensions(canvas, { width: size, height: size }); - element.appendChild(canvas); - } - - // Create percentage display - const percentDisplay = element.querySelector('span') as HTMLSpanElement; - if (percentDisplay) { - percentDisplay.textContent = `${percent}%`; - percentDisplay.style.position = 'absolute'; - percentDisplay.style.top = '50%'; - percentDisplay.style.left = '50%'; - percentDisplay.style.transform = 'translate(-50%, -50%)'; - percentDisplay.style.fontSize = '14px'; - percentDisplay.style.fontWeight = 'bold'; - } - - // Set element position to relative for absolute positioning of text - htmlElement.style.position = 'relative'; - htmlElement.style.display = 'inline-block'; - - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - const chartConfig: ChartConfiguration = { - type: 'doughnut', - data: { - datasets: [{ - data: [percent, 100 - percent], - backgroundColor: [barColor, '#f0f0f0'], - borderWidth: 0, - }], - }, - options: { - responsive: false, - maintainAspectRatio: false, - cutout: '70%', - plugins: { - legend: { display: false }, - tooltip: { enabled: false }, - }, - }, - }; - - const chart = new Chart(ctx, chartConfig); - this.charts.set(`easy-pie-${index}`, chart); - }); - } -} - -export default ChartComponent; \ No newline at end of file diff --git a/src/assets/scripts/components/Sidebar.ts b/src/assets/scripts/components/Sidebar.ts deleted file mode 100644 index ca9da26..0000000 --- a/src/assets/scripts/components/Sidebar.ts +++ /dev/null @@ -1,388 +0,0 @@ -/** - * Modern Sidebar Component with TypeScript - * Replaces jQuery-based sidebar functionality with vanilla JavaScript - */ - -import type { ComponentInterface, SidebarOptions, SidebarState, AnimationOptions } from '../../../types'; - -export interface SidebarEventDetail { - collapsed: boolean; -} - -export interface SidebarToggleEvent extends CustomEvent { - detail: SidebarEventDetail; -} - -declare global { - interface Window { - EVENT?: Event; - } -} - -export class Sidebar implements ComponentInterface { - public name: string = 'Sidebar'; - public element: HTMLElement; - public options: SidebarOptions; - public isInitialized: boolean = false; - - private sidebar: HTMLElement | null; - private sidebarMenu: HTMLElement | null; - private sidebarToggleLinks: NodeListOf; - private sidebarToggleById: HTMLElement | null; - private app: HTMLElement | null; - private state: SidebarState; - - constructor(element?: HTMLElement, options: SidebarOptions = {}) { - this.element = element || document.body; - this.options = { - breakpoint: 768, - collapsible: true, - autoHide: true, - animation: true, - animationDuration: 200, - ...options, - }; - - this.sidebar = document.querySelector('.sidebar'); - this.sidebarMenu = document.querySelector('.sidebar .sidebar-menu'); - this.sidebarToggleLinks = document.querySelectorAll('.sidebar-toggle a'); - this.sidebarToggleById = document.querySelector('#sidebar-toggle'); - this.app = document.querySelector('.app'); - - this.state = { - isCollapsed: false, - isMobile: false, - activeMenu: null, - }; - - this.init(); - } - - /** - * Initialize the sidebar component - */ - public init(): void { - if (!this.sidebar || !this.sidebarMenu) { - console.warn('Sidebar: Required elements not found'); - return; - } - - this.setupMenuToggle(); - this.setupSidebarToggle(); - this.setActiveLink(); - this.handleResize(); - this.setupEventListeners(); - - this.isInitialized = true; - } - - /** - * Destroy the sidebar component - */ - public destroy(): void { - this.removeEventListeners(); - this.isInitialized = false; - } - - /** - * Setup dropdown menu functionality - */ - private setupMenuToggle(): void { - if (!this.sidebarMenu) return; - - const menuLinks = this.sidebarMenu.querySelectorAll('li a'); - - menuLinks.forEach(link => { - link.addEventListener('click', this.handleMenuClick.bind(this)); - }); - } - - /** - * Handle menu item click - */ - private handleMenuClick(e: Event): void { - const link = e.target as HTMLAnchorElement; - const listItem = link.parentElement as HTMLLIElement; - const dropdownMenu = listItem?.querySelector('.dropdown-menu') as HTMLElement; - - // If this is a regular navigation link (not dropdown), allow normal navigation - if (!dropdownMenu) { - return; - } - - // Only prevent default for dropdown toggles - e.preventDefault(); - - if (listItem.classList.contains('open')) { - this.closeDropdown(listItem, dropdownMenu); - } else { - this.closeAllDropdowns(); - this.openDropdown(listItem, dropdownMenu); - } - } - - /** - * Open dropdown with smooth animation - */ - private openDropdown(listItem: HTMLLIElement, dropdownMenu: HTMLElement): void { - listItem.classList.add('open'); - dropdownMenu.style.display = 'block'; - dropdownMenu.style.height = '0px'; - dropdownMenu.style.overflow = 'hidden'; - - // Get the natural height - const height = dropdownMenu.scrollHeight; - - // Animate to full height - const animation = dropdownMenu.animate([ - { height: '0px' }, - { height: `${height}px` }, - ], { - duration: this.options.animationDuration, - easing: 'ease-out', - }); - - animation.onfinish = (): void => { - dropdownMenu.style.height = 'auto'; - dropdownMenu.style.overflow = 'visible'; - }; - } - - /** - * Close dropdown with smooth animation - */ - private closeDropdown(listItem: HTMLLIElement, dropdownMenu: HTMLElement): void { - const height = dropdownMenu.scrollHeight; - - dropdownMenu.style.height = `${height}px`; - dropdownMenu.style.overflow = 'hidden'; - - const animation = dropdownMenu.animate([ - { height: `${height}px` }, - { height: '0px' }, - ], { - duration: this.options.animationDuration, - easing: 'ease-in', - }); - - animation.onfinish = (): void => { - listItem.classList.remove('open'); - dropdownMenu.style.display = 'none'; - dropdownMenu.style.height = ''; - dropdownMenu.style.overflow = ''; - }; - } - - /** - * Close all open dropdowns - */ - private closeAllDropdowns(): void { - if (!this.sidebarMenu) return; - - const openItems = this.sidebarMenu.querySelectorAll('li.open'); - - openItems.forEach(item => { - const dropdownMenu = item.querySelector('.dropdown-menu') as HTMLElement; - if (dropdownMenu) { - this.closeDropdown(item as HTMLLIElement, dropdownMenu); - } - - // Also remove the has-active-child class - item.classList.remove('has-active-child'); - }); - } - - /** - * Setup sidebar toggle functionality - */ - private setupSidebarToggle(): void { - // Handle mobile sidebar toggle links (inside .sidebar-toggle divs) - this.sidebarToggleLinks.forEach(link => { - if (link && this.app) { - link.addEventListener('click', this.handleSidebarToggle.bind(this)); - } - }); - - // Handle the main topbar sidebar toggle - if (this.sidebarToggleById && this.app) { - this.sidebarToggleById.addEventListener('click', this.handleSidebarToggle.bind(this)); - } - } - - /** - * Handle sidebar toggle click - */ - private handleSidebarToggle(e: Event): void { - e.preventDefault(); - this.toggleSidebar(); - } - - /** - * Toggle sidebar and handle resize events properly - */ - private toggleSidebar(): void { - if (!this.app) return; - - const wasCollapsed = this.state.isCollapsed; - this.state.isCollapsed = !wasCollapsed; - - this.app.classList.toggle('is-collapsed'); - - // Dispatch custom event with proper typing - setTimeout(() => { - const event: SidebarToggleEvent = new CustomEvent('sidebar:toggle', { - detail: { collapsed: this.state.isCollapsed }, - }) as SidebarToggleEvent; - - window.dispatchEvent(event); - - // Still trigger resize for masonry but with a specific check - if (window.EVENT) { - window.dispatchEvent(window.EVENT); - } - }, this.options.animationDuration || 300); - } - - /** - * Set active link based on current URL - */ - private setActiveLink(): void { - if (!this.sidebar) return; - - // Remove active class from all nav items (including dropdown items) - const allNavItems = this.sidebar.querySelectorAll('.nav-item'); - allNavItems.forEach(item => { - item.classList.remove('actived'); - }); - - // Close all dropdowns first - this.closeAllDropdowns(); - - // Get current page filename - const currentPath = window.location.pathname; - const currentPage = currentPath.split('/').pop() || 'index.html'; - - // Find and activate the correct nav item - const allLinks = this.sidebar.querySelectorAll('a[href]'); - - allLinks.forEach(link => { - const href = link.getAttribute('href'); - if (!href || href === 'javascript:void(0);' || href === 'javascript:void(0)') return; - - // Extract filename from href - const linkPage = href.split('/').pop(); - - if (linkPage === currentPage) { - const navItem = link.closest('.nav-item') as HTMLElement; - if (navItem) { - navItem.classList.add('actived'); - this.state.activeMenu = linkPage || null; - - // If this is inside a dropdown, handle parent dropdown specially - const parentDropdown = navItem.closest('.dropdown-menu') as HTMLElement; - if (parentDropdown) { - const parentDropdownItem = parentDropdown.closest('.nav-item.dropdown') as HTMLElement; - if (parentDropdownItem) { - // Open the parent dropdown - parentDropdownItem.classList.add('open'); - parentDropdown.style.display = 'block'; - - // Add special styling to indicate parent has active child - parentDropdownItem.classList.add('has-active-child'); - } - } - } - } - }); - } - - /** - * Handle window resize - */ - private handleResize(): void { - this.state.isMobile = window.innerWidth <= (this.options.breakpoint || 768); - - if (this.options.autoHide && this.state.isMobile) { - // Auto-hide logic for mobile - this.collapse(); - } - } - - /** - * Setup event listeners - */ - private setupEventListeners(): void { - window.addEventListener('resize', this.handleResize.bind(this)); - } - - /** - * Remove event listeners - */ - private removeEventListeners(): void { - window.removeEventListener('resize', this.handleResize.bind(this)); - } - - /** - * Public method to refresh active links (useful for SPA navigation) - */ - public refreshActiveLink(): void { - this.setActiveLink(); - } - - /** - * Public method to toggle sidebar programmatically - */ - public toggle(): void { - this.toggleSidebar(); - } - - /** - * Public method to collapse sidebar - */ - public collapse(): void { - if (!this.app || this.state.isCollapsed) return; - - this.state.isCollapsed = true; - this.app.classList.add('is-collapsed'); - } - - /** - * Public method to expand sidebar - */ - public expand(): void { - if (!this.app || !this.state.isCollapsed) return; - - this.state.isCollapsed = false; - this.app.classList.remove('is-collapsed'); - } - - /** - * Public method to check if sidebar is collapsed - */ - public isCollapsed(): boolean { - return this.state.isCollapsed; - } - - /** - * Get current sidebar state - */ - public getState(): SidebarState { - return { ...this.state }; - } - - /** - * Update sidebar options - */ - public updateOptions(newOptions: Partial): void { - this.options = { ...this.options, ...newOptions }; - } - - /** - * Get current options - */ - public getOptions(): SidebarOptions { - return { ...this.options }; - } -} - -export default Sidebar; \ No newline at end of file diff --git a/src/assets/scripts/datatable/index.ts b/src/assets/scripts/datatable/index.ts deleted file mode 100644 index 3c5c3dc..0000000 --- a/src/assets/scripts/datatable/index.ts +++ /dev/null @@ -1,707 +0,0 @@ -/** - * DataTable Implementation with TypeScript - * Vanilla JavaScript DataTable with sorting, searching, and pagination - */ - -import type { ComponentInterface } from '../../types'; - -// Type definitions for DataTable -export interface DataTableOptions { - sortable?: boolean; - searchable?: boolean; - pagination?: boolean; - pageSize?: number; - responsive?: boolean; - striped?: boolean; - bordered?: boolean; - hover?: boolean; -} - -export interface DataTableColumn { - title: string; - data: string | number; - sortable?: boolean; - searchable?: boolean; - width?: string; - className?: string; - render?: (data: any, row: any[], index: number) => string; -} - -export interface DataTableData { - columns: DataTableColumn[]; - rows: any[][]; -} - -export interface DataTableState { - currentPage: number; - sortColumn: number | null; - sortDirection: 'asc' | 'desc'; - searchQuery: string; - filteredData: any[][]; - totalPages: number; -} - -export type SortDirection = 'asc' | 'desc'; - -declare global { - interface HTMLTableElement { - dataTableInstance?: VanillaDataTable; - } -} - -// Enhanced DataTable implementation -export class VanillaDataTable implements ComponentInterface { - public name: string = 'VanillaDataTable'; - public element: HTMLTableElement; - public options: DataTableOptions; - public isInitialized: boolean = false; - - private originalData: any[][] = []; - private filteredData: any[][] = []; - private state: DataTableState; - private wrapper: HTMLElement | null = null; - private searchInput: HTMLInputElement | null = null; - private infoElement: HTMLElement | null = null; - private paginationElement: HTMLElement | null = null; - - constructor(element: HTMLTableElement, options: DataTableOptions = {}) { - this.element = element; - this.options = { - sortable: true, - searchable: true, - pagination: true, - pageSize: 10, - responsive: true, - striped: true, - bordered: true, - hover: true, - ...options, - }; - - this.state = { - currentPage: 1, - sortColumn: null, - sortDirection: 'asc', - searchQuery: '', - filteredData: [], - totalPages: 0, - }; - - this.init(); - } - - public init(): void { - this.extractData(); - this.createControls(); - this.applyStyles(); - this.bindEvents(); - this.render(); - this.isInitialized = true; - } - - public destroy(): void { - if (this.wrapper && this.wrapper.parentNode) { - this.wrapper.parentNode.replaceChild(this.element, this.wrapper); - } - this.isInitialized = false; - } - - private extractData(): void { - const tbody = this.element.querySelector('tbody'); - if (!tbody) return; - - const rows = tbody.querySelectorAll('tr'); - this.originalData = Array.from(rows).map(row => { - const cells = row.querySelectorAll('td'); - return Array.from(cells).map(cell => cell.textContent?.trim() || ''); - }); - this.filteredData = [...this.originalData]; - this.state.filteredData = this.filteredData; - } - - private createControls(): void { - const wrapper = document.createElement('div'); - wrapper.className = 'datatable-wrapper'; - - // Create top controls container - const topControls = document.createElement('div'); - topControls.className = 'datatable-top-controls'; - - // Create search input - if (this.options.searchable) { - const searchWrapper = document.createElement('div'); - searchWrapper.className = 'datatable-search'; - - const searchLabel = document.createElement('label'); - searchLabel.textContent = 'Search: '; - - this.searchInput = document.createElement('input'); - this.searchInput.type = 'text'; - this.searchInput.className = 'form-control'; - this.searchInput.placeholder = 'Search...'; - - searchLabel.appendChild(this.searchInput); - searchWrapper.appendChild(searchLabel); - topControls.appendChild(searchWrapper); - } - - // Create info display - if (this.options.pagination) { - this.infoElement = document.createElement('div'); - this.infoElement.className = 'datatable-info'; - topControls.appendChild(this.infoElement); - } - - wrapper.appendChild(topControls); - - // Wrap the table - if (this.element.parentNode) { - this.element.parentNode.insertBefore(wrapper, this.element); - } - wrapper.appendChild(this.element); - - // Create pagination controls - if (this.options.pagination) { - this.paginationElement = document.createElement('div'); - this.paginationElement.className = 'datatable-pagination'; - wrapper.appendChild(this.paginationElement); - } - - this.wrapper = wrapper; - } - - private applyStyles(): void { - // Apply Bootstrap-like styles - const classes = ['table']; - if (this.options.striped) classes.push('table-striped'); - if (this.options.bordered) classes.push('table-bordered'); - if (this.options.hover) classes.push('table-hover'); - if (this.options.responsive) { - const responsiveWrapper = document.createElement('div'); - responsiveWrapper.className = 'table-responsive'; - if (this.element.parentNode) { - this.element.parentNode.insertBefore(responsiveWrapper, this.element); - responsiveWrapper.appendChild(this.element); - } - } - - this.element.className = classes.join(' '); - - // Add custom styles - this.injectStyles(); - } - - private injectStyles(): void { - const styleId = 'datatable-styles'; - if (document.getElementById(styleId)) return; - - const style = document.createElement('style'); - style.id = styleId; - style.textContent = ` - .datatable-wrapper { - margin: 20px 0; - } - - .datatable-top-controls { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 15px; - flex-wrap: wrap; - gap: 10px; - } - - .datatable-search { - display: flex; - align-items: center; - gap: 8px; - } - - .datatable-search label { - margin: 0; - font-weight: 500; - } - - .datatable-search input { - width: 250px; - padding: 6px 12px; - border: 1px solid var(--c-border, #dee2e6); - border-radius: 4px; - font-size: 14px; - } - - .datatable-info { - color: var(--c-text-muted, #6c757d); - font-size: 14px; - margin: 0; - } - - .datatable-pagination { - margin-top: 15px; - display: flex; - justify-content: center; - align-items: center; - gap: 4px; - flex-wrap: wrap; - } - - .datatable-pagination button { - background: var(--c-bkg-card, #fff); - border: 1px solid var(--c-border, #dee2e6); - color: var(--c-text-base, #333); - padding: 8px 12px; - cursor: pointer; - border-radius: 4px; - font-size: 14px; - transition: all 0.2s ease; - min-width: 40px; - } - - .datatable-pagination button:hover:not(:disabled) { - background: var(--c-primary, #007bff); - border-color: var(--c-primary, #007bff); - color: white; - } - - .datatable-pagination button.active { - background: var(--c-primary, #007bff); - border-color: var(--c-primary, #007bff); - color: white; - } - - .datatable-pagination button:disabled { - opacity: 0.6; - cursor: not-allowed; - background: var(--c-bkg-muted, #f8f9fa); - } - - .datatable-sort { - cursor: pointer; - user-select: none; - position: relative; - padding-right: 20px !important; - transition: background-color 0.2s ease; - } - - .datatable-sort:hover { - background: var(--c-bkg-hover, #f8f9fa); - } - - .datatable-sort::after { - content: '↕'; - position: absolute; - right: 8px; - top: 50%; - transform: translateY(-50%); - opacity: 0.5; - font-size: 12px; - } - - .datatable-sort.asc::after { - content: '↑'; - opacity: 1; - color: var(--c-primary, #007bff); - } - - .datatable-sort.desc::after { - content: '↓'; - opacity: 1; - color: var(--c-primary, #007bff); - } - - .datatable-no-results { - text-align: center; - color: var(--c-text-muted, #6c757d); - font-style: italic; - padding: 20px; - } - - @media (max-width: 768px) { - .datatable-top-controls { - flex-direction: column; - align-items: stretch; - } - - .datatable-search input { - width: 100%; - } - - .datatable-pagination { - justify-content: center; - } - - .datatable-pagination button { - padding: 6px 10px; - font-size: 13px; - } - } - `; - document.head.appendChild(style); - } - - private bindEvents(): void { - // Search functionality - if (this.options.searchable && this.searchInput) { - this.searchInput.addEventListener('input', (e) => { - const target = e.target as HTMLInputElement; - this.search(target.value); - }); - } - - // Sorting functionality - if (this.options.sortable) { - const headers = this.element.querySelectorAll('thead th'); - headers.forEach((header, index) => { - header.classList.add('datatable-sort'); - header.addEventListener('click', () => { - this.sort(index); - }); - header.setAttribute('tabindex', '0'); - header.setAttribute('role', 'button'); - header.setAttribute('aria-label', `Sort by ${header.textContent}`); - }); - } - } - - public search(query: string): void { - this.state.searchQuery = query; - - if (!query.trim()) { - this.filteredData = [...this.originalData]; - } else { - const searchTerm = query.toLowerCase().trim(); - this.filteredData = this.originalData.filter(row => - row.some(cell => - cell.toString().toLowerCase().includes(searchTerm) - ) - ); - } - - this.state.filteredData = this.filteredData; - this.state.currentPage = 1; - this.render(); - } - - public sort(columnIndex: number): void { - if (this.state.sortColumn === columnIndex) { - this.state.sortDirection = this.state.sortDirection === 'asc' ? 'desc' : 'asc'; - } else { - this.state.sortColumn = columnIndex; - this.state.sortDirection = 'asc'; - } - - this.filteredData.sort((a, b) => { - const aVal = a[columnIndex]; - const bVal = b[columnIndex]; - - // Try to parse as numbers - const aNum = parseFloat(aVal); - const bNum = parseFloat(bVal); - - let comparison = 0; - if (!isNaN(aNum) && !isNaN(bNum)) { - comparison = aNum - bNum; - } else { - // Try to parse as dates - const aDate = new Date(aVal); - const bDate = new Date(bVal); - - if (aDate.getTime() && bDate.getTime()) { - comparison = aDate.getTime() - bDate.getTime(); - } else { - comparison = aVal.toString().localeCompare(bVal.toString()); - } - } - - return this.state.sortDirection === 'asc' ? comparison : -comparison; - }); - - this.updateSortHeaders(); - this.render(); - } - - private updateSortHeaders(): void { - const headers = this.element.querySelectorAll('thead th'); - headers.forEach((header, index) => { - header.classList.remove('asc', 'desc'); - if (index === this.state.sortColumn) { - header.classList.add(this.state.sortDirection); - } - }); - } - - public render(): void { - const tbody = this.element.querySelector('tbody'); - if (!tbody) return; - - const startIndex = (this.state.currentPage - 1) * this.options.pageSize!; - const endIndex = startIndex + this.options.pageSize!; - const pageData = this.filteredData.slice(startIndex, endIndex); - - // Clear tbody - tbody.innerHTML = ''; - - if (pageData.length === 0) { - // Show no results message - const noResultsRow = document.createElement('tr'); - const noResultsCell = document.createElement('td'); - noResultsCell.colSpan = this.getColumnCount(); - noResultsCell.className = 'datatable-no-results'; - noResultsCell.textContent = this.state.searchQuery ? - 'No matching records found' : 'No data available'; - noResultsRow.appendChild(noResultsCell); - tbody.appendChild(noResultsRow); - } else { - // Add rows - pageData.forEach((rowData, rowIndex) => { - const row = document.createElement('tr'); - rowData.forEach((cellData, colIndex) => { - const cell = document.createElement('td'); - cell.textContent = cellData.toString(); - row.appendChild(cell); - }); - tbody.appendChild(row); - }); - } - - // Update pagination - if (this.options.pagination) { - this.updatePagination(); - } - - // Update info - this.updateInfo(); - } - - private getColumnCount(): number { - const headerRow = this.element.querySelector('thead tr'); - return headerRow ? headerRow.querySelectorAll('th').length : 0; - } - - private updatePagination(): void { - if (!this.paginationElement) return; - - this.state.totalPages = Math.ceil(this.filteredData.length / this.options.pageSize!); - this.paginationElement.innerHTML = ''; - - if (this.state.totalPages <= 1) return; - - // Previous button - const prevBtn = this.createPaginationButton('Previous', () => { - if (this.state.currentPage > 1) { - this.state.currentPage--; - this.render(); - } - }); - prevBtn.disabled = this.state.currentPage === 1; - this.paginationElement.appendChild(prevBtn); - - // Calculate page range to show - const maxButtons = 5; - let startPage = Math.max(1, this.state.currentPage - Math.floor(maxButtons / 2)); - let endPage = Math.min(this.state.totalPages, startPage + maxButtons - 1); - - // Adjust if we're at the end - if (endPage - startPage + 1 < maxButtons) { - startPage = Math.max(1, endPage - maxButtons + 1); - } - - // First page if not in range - if (startPage > 1) { - const firstBtn = this.createPaginationButton('1', () => { - this.state.currentPage = 1; - this.render(); - }); - this.paginationElement.appendChild(firstBtn); - - if (startPage > 2) { - const ellipsis = document.createElement('span'); - ellipsis.textContent = '...'; - ellipsis.className = 'pagination-ellipsis'; - this.paginationElement.appendChild(ellipsis); - } - } - - // Page numbers - for (let i = startPage; i <= endPage; i++) { - const pageBtn = this.createPaginationButton(i.toString(), () => { - this.state.currentPage = i; - this.render(); - }); - pageBtn.classList.toggle('active', i === this.state.currentPage); - this.paginationElement.appendChild(pageBtn); - } - - // Last page if not in range - if (endPage < this.state.totalPages) { - if (endPage < this.state.totalPages - 1) { - const ellipsis = document.createElement('span'); - ellipsis.textContent = '...'; - ellipsis.className = 'pagination-ellipsis'; - this.paginationElement.appendChild(ellipsis); - } - - const lastBtn = this.createPaginationButton(this.state.totalPages.toString(), () => { - this.state.currentPage = this.state.totalPages; - this.render(); - }); - this.paginationElement.appendChild(lastBtn); - } - - // Next button - const nextBtn = this.createPaginationButton('Next', () => { - if (this.state.currentPage < this.state.totalPages) { - this.state.currentPage++; - this.render(); - } - }); - nextBtn.disabled = this.state.currentPage === this.state.totalPages; - this.paginationElement.appendChild(nextBtn); - } - - private createPaginationButton(text: string, onClick: () => void): HTMLButtonElement { - const button = document.createElement('button'); - button.textContent = text; - button.addEventListener('click', onClick); - return button; - } - - private updateInfo(): void { - if (!this.infoElement) return; - - const startIndex = (this.state.currentPage - 1) * this.options.pageSize! + 1; - const endIndex = Math.min(startIndex + this.options.pageSize! - 1, this.filteredData.length); - const total = this.filteredData.length; - const originalTotal = this.originalData.length; - - if (total === 0) { - this.infoElement.textContent = 'No entries to show'; - } else if (total === originalTotal) { - this.infoElement.textContent = `Showing ${startIndex} to ${endIndex} of ${total} entries`; - } else { - this.infoElement.textContent = `Showing ${startIndex} to ${endIndex} of ${total} entries (filtered from ${originalTotal} total entries)`; - } - } - - // Public API methods - public goToPage(page: number): void { - if (page >= 1 && page <= this.state.totalPages) { - this.state.currentPage = page; - this.render(); - } - } - - public setPageSize(size: number): void { - this.options.pageSize = size; - this.state.currentPage = 1; - this.render(); - } - - public getState(): Readonly { - return { ...this.state }; - } - - public refresh(): void { - this.extractData(); - this.state.currentPage = 1; - this.render(); - } - - public clear(): void { - this.originalData = []; - this.filteredData = []; - this.state.currentPage = 1; - this.render(); - } -} - -// DataTable Manager -export class DataTableManager { - private instances: Map = new Map(); - - public initialize(selector: string = '#dataTable', options: DataTableOptions = {}): VanillaDataTable | null { - const element = document.querySelector(selector); - if (!element) { - // Silently return null if element doesn't exist (normal for pages without tables) - return null; - } - - // Clean up existing instance - if (element.dataTableInstance) { - element.dataTableInstance.destroy(); - } - - // Create new instance - const dataTable = new VanillaDataTable(element, options); - element.dataTableInstance = dataTable; - - // Store in manager - this.instances.set(selector, dataTable); - - return dataTable; - } - - public getInstance(selector: string): VanillaDataTable | undefined { - return this.instances.get(selector); - } - - public destroyInstance(selector: string): void { - const instance = this.instances.get(selector); - if (instance) { - instance.destroy(); - this.instances.delete(selector); - } - } - - public destroyAll(): void { - this.instances.forEach((instance, selector) => { - instance.destroy(); - }); - this.instances.clear(); - } -} - -// Create singleton manager -const dataTableManager = new DataTableManager(); - -// Initialize DataTable -const initializeDataTable = (): void => { - // Only initialize if the table exists - if (document.querySelector('#dataTable')) { - dataTableManager.initialize('#dataTable', { - sortable: true, - searchable: true, - pagination: true, - pageSize: 10, - responsive: true, - striped: true, - bordered: true, - hover: true, - }); - } -}; - -// Initialize on load -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initializeDataTable); -} else { - initializeDataTable(); -} - -// Reinitialize on theme change -window.addEventListener('adminator:themeChanged', () => { - setTimeout(initializeDataTable, 100); -}); - -// Cleanup on page unload -window.addEventListener('beforeunload', () => { - dataTableManager.destroyAll(); -}); - -// Export default for compatibility -export default { - init: initializeDataTable, - manager: dataTableManager, - VanillaDataTable, - DataTableManager, -}; \ No newline at end of file diff --git a/src/assets/scripts/datepicker/index.ts b/src/assets/scripts/datepicker/index.ts deleted file mode 100644 index 85fd091..0000000 --- a/src/assets/scripts/datepicker/index.ts +++ /dev/null @@ -1,699 +0,0 @@ -/** - * Enhanced HTML5 DatePicker with TypeScript - * Modern date picker implementation using native HTML5 input[type="date"] - */ - -import DateUtils from '../utils/date'; -import type { ComponentInterface } from '../../types'; - -// Type definitions for DatePicker -export interface DatePickerOptions { - format?: string; - autoclose?: boolean; - todayHighlight?: boolean; - minDate?: string; - maxDate?: string; - startDate?: string; - endDate?: string; - daysOfWeekDisabled?: number[]; - datesDisabled?: string[]; - weekStart?: number; - language?: string; -} - -export interface DatePickerEvent { - date: string; - formattedDate: string; - dateObject: Date; - isValid: boolean; -} - -export interface DatePickerValidation { - isValid: boolean; - errors: string[]; -} - -declare global { - interface HTMLInputElement { - vanillaDatePicker?: VanillaDatePicker; - showPicker?: () => void; - } -} - -// Enhanced HTML5 date picker with vanilla JS -export class VanillaDatePicker implements ComponentInterface { - public name: string = 'VanillaDatePicker'; - public element: HTMLInputElement; - public options: DatePickerOptions; - public isInitialized: boolean = false; - - private wrapper: HTMLElement | null = null; - private todayIndicator: HTMLElement | null = null; - private validationErrors: string[] = []; - - constructor(element: HTMLInputElement, options: DatePickerOptions = {}) { - this.element = element; - this.options = { - format: 'yyyy-mm-dd', - autoclose: true, - todayHighlight: true, - weekStart: 0, - language: 'en', - ...options, - }; - - this.init(); - } - - public init(): void { - this.convertToHTML5(); - this.enhanceInput(); - this.applyStyles(); - this.bindEvents(); - this.validateConstraints(); - this.addTodayHighlight(); - this.isInitialized = true; - } - - public destroy(): void { - if (this.wrapper && this.wrapper.parentNode) { - this.wrapper.parentNode.replaceChild(this.element, this.wrapper); - } - this.isInitialized = false; - } - - private convertToHTML5(): void { - // Convert input to HTML5 date type - this.element.type = 'date'; - this.element.classList.add('form-control', 'vanilla-datepicker'); - - // Remove placeholder since HTML5 date inputs don't need it - this.element.removeAttribute('placeholder'); - - // Set constraints - if (this.options.minDate) { - this.element.min = this.options.minDate; - } - if (this.options.maxDate) { - this.element.max = this.options.maxDate; - } - - // Set default value if no value is set - if (!this.element.value) { - if (this.options.startDate) { - this.element.value = this.options.startDate; - } else if (this.options.todayHighlight) { - this.element.value = DateUtils.formatters.inputDate(DateUtils.now()); - } - } - - // Ensure proper styling - this.element.style.minHeight = '38px'; - this.element.style.lineHeight = '1.5'; - this.element.style.cursor = 'pointer'; - - // Add ARIA attributes - this.element.setAttribute('aria-label', 'Select date'); - this.element.setAttribute('role', 'textbox'); - this.element.setAttribute('aria-expanded', 'false'); - } - - private enhanceInput(): void { - // Create wrapper for enhanced functionality - const wrapper = document.createElement('div'); - wrapper.className = 'vanilla-datepicker-wrapper'; - wrapper.style.position = 'relative'; - - // Wrap the input - const parent = this.element.parentNode; - if (parent) { - parent.insertBefore(wrapper, this.element); - wrapper.appendChild(this.element); - } - - // Add calendar icon if input is in an input group - const inputGroup = this.element.closest('.input-group'); - if (inputGroup) { - const calendarIcon = inputGroup.querySelector('.input-group-text i.ti-calendar'); - if (calendarIcon) { - calendarIcon.addEventListener('click', this.handleIconClick.bind(this)); - calendarIcon.style.cursor = 'pointer'; - calendarIcon.setAttribute('tabindex', '0'); - calendarIcon.setAttribute('role', 'button'); - calendarIcon.setAttribute('aria-label', 'Open calendar'); - } - } - - this.wrapper = wrapper; - } - - private applyStyles(): void { - const styleId = 'vanilla-datepicker-styles'; - if (document.getElementById(styleId)) return; - - const style = document.createElement('style'); - style.id = styleId; - style.textContent = ` - .vanilla-datepicker-wrapper { - position: relative; - display: inline-block; - width: 100%; - } - - .vanilla-datepicker { - width: 100%; - padding: 8px 12px; - border: 1px solid var(--c-border, #ced4da); - border-radius: 4px; - background-color: var(--c-bkg-card, #fff); - color: var(--c-text-base, #495057); - font-size: 14px; - font-family: inherit; - transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - } - - .vanilla-datepicker:focus { - outline: none; - border-color: var(--c-primary, #007bff); - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); - } - - .vanilla-datepicker:invalid { - border-color: var(--c-danger, #dc3545); - } - - .vanilla-datepicker:invalid:focus { - border-color: var(--c-danger, #dc3545); - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); - } - - .vanilla-datepicker::-webkit-calendar-picker-indicator { - cursor: pointer; - border-radius: 4px; - margin-right: 2px; - opacity: 0.6; - transition: opacity 0.15s ease-in-out; - filter: var(--datepicker-icon-filter, none); - } - - .vanilla-datepicker::-webkit-calendar-picker-indicator:hover { - opacity: 1; - } - - .vanilla-datepicker::-webkit-datetime-edit-fields-wrapper { - padding: 0; - } - - .vanilla-datepicker::-webkit-datetime-edit-month-field, - .vanilla-datepicker::-webkit-datetime-edit-day-field, - .vanilla-datepicker::-webkit-datetime-edit-year-field { - color: var(--c-text-base, #495057); - } - - .vanilla-datepicker::-webkit-datetime-edit-text { - color: var(--c-text-muted, #6c757d); - } - - /* Dark mode support */ - [data-theme="dark"] .vanilla-datepicker { - background-color: var(--c-bkg-card, #1f2937); - color: var(--c-text-base, #f9fafb); - border-color: var(--c-border, #374151); - --datepicker-icon-filter: invert(1); - } - - .datepicker-today-indicator { - position: absolute; - top: 4px; - right: 12px; - width: 6px; - height: 6px; - background-color: var(--c-primary, #007bff); - border-radius: 50%; - opacity: 0.8; - pointer-events: none; - z-index: 1; - } - - .datepicker-animation { - animation: datepicker-highlight 0.3s ease-in-out; - } - - @keyframes datepicker-highlight { - 0% { transform: scale(1); } - 50% { transform: scale(1.02); } - 100% { transform: scale(1); } - } - - .datepicker-error { - border-color: var(--c-danger, #dc3545) !important; - } - - .datepicker-error:focus { - border-color: var(--c-danger, #dc3545) !important; - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25) !important; - } - - .datepicker-validation-feedback { - display: block; - width: 100%; - margin-top: 0.25rem; - font-size: 0.875rem; - color: var(--c-danger, #dc3545); - } - - /* Responsive design */ - @media (max-width: 768px) { - .vanilla-datepicker { - padding: 10px 12px; - font-size: 16px; /* Prevent zoom on iOS */ - } - - .vanilla-datepicker::-webkit-calendar-picker-indicator { - width: 20px; - height: 20px; - } - } - `; - - document.head.appendChild(style); - } - - private bindEvents(): void { - // Handle click events - this.element.addEventListener('click', this.handleClick.bind(this)); - - // Handle keyboard events - this.element.addEventListener('keydown', this.handleKeydown.bind(this)); - - // Handle change events - this.element.addEventListener('change', this.handleChange.bind(this)); - - // Handle focus events - this.element.addEventListener('focus', this.handleFocus.bind(this)); - - // Handle blur events - this.element.addEventListener('blur', this.handleBlur.bind(this)); - - // Handle input events for real-time validation - this.element.addEventListener('input', this.handleInput.bind(this)); - } - - private handleClick(): void { - this.openPicker(); - } - - private handleKeydown(e: KeyboardEvent): void { - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault(); - this.openPicker(); - } - } - - private handleChange(e: Event): void { - const target = e.target as HTMLInputElement; - this.handleDateChange(target.value); - } - - private handleFocus(): void { - this.element.classList.add('datepicker-animation'); - this.element.setAttribute('aria-expanded', 'true'); - setTimeout(() => { - this.element.classList.remove('datepicker-animation'); - }, 300); - } - - private handleBlur(): void { - this.element.setAttribute('aria-expanded', 'false'); - this.validateInput(); - } - - private handleInput(): void { - this.validateInput(); - } - - private handleIconClick(e: Event): void { - e.preventDefault(); - e.stopPropagation(); - this.openPicker(); - } - - private openPicker(): void { - this.element.focus(); - - // Try to open the native date picker - if (this.element.showPicker && typeof this.element.showPicker === 'function') { - try { - this.element.showPicker(); - } catch (error) { - console.warn('DatePicker: showPicker not supported', error); - } - } - } - - private handleDateChange(selectedDate: string): void { - if (selectedDate) { - // Add visual feedback - this.element.classList.add('datepicker-animation'); - setTimeout(() => { - this.element.classList.remove('datepicker-animation'); - }, 300); - - // Validate the date - const validation = this.validateDate(selectedDate); - - // Create event data - const eventData: DatePickerEvent = { - date: selectedDate, - formattedDate: this.formatDate(selectedDate), - dateObject: new Date(selectedDate), - isValid: validation.isValid, - }; - - // Trigger custom event - const changeEvent = new CustomEvent('datepicker:change', { - detail: eventData, - bubbles: true, - }); - this.element.dispatchEvent(changeEvent); - - // Update validation state - this.updateValidationState(validation); - } - } - - private validateConstraints(): void { - // Set up date constraints based on options - if (this.options.datesDisabled && this.options.datesDisabled.length > 0) { - this.element.addEventListener('input', (e) => { - const target = e.target as HTMLInputElement; - if (this.options.datesDisabled!.includes(target.value)) { - this.addValidationError('This date is disabled'); - } - }); - } - - if (this.options.daysOfWeekDisabled && this.options.daysOfWeekDisabled.length > 0) { - this.element.addEventListener('input', (e) => { - const target = e.target as HTMLInputElement; - const date = new Date(target.value); - const dayOfWeek = date.getDay(); - if (this.options.daysOfWeekDisabled!.includes(dayOfWeek)) { - this.addValidationError('This day of the week is disabled'); - } - }); - } - } - - private validateDate(dateString: string): DatePickerValidation { - const errors: string[] = []; - const date = new Date(dateString); - - // Check if date is valid - if (isNaN(date.getTime())) { - errors.push('Invalid date format'); - } - - // Check min/max constraints - if (this.options.minDate) { - const minDate = new Date(this.options.minDate); - if (date < minDate) { - errors.push(`Date must be after ${this.formatDate(this.options.minDate)}`); - } - } - - if (this.options.maxDate) { - const maxDate = new Date(this.options.maxDate); - if (date > maxDate) { - errors.push(`Date must be before ${this.formatDate(this.options.maxDate)}`); - } - } - - // Check disabled dates - if (this.options.datesDisabled && this.options.datesDisabled.includes(dateString)) { - errors.push('This date is disabled'); - } - - // Check disabled days of week - if (this.options.daysOfWeekDisabled && this.options.daysOfWeekDisabled.includes(date.getDay())) { - errors.push('This day of the week is disabled'); - } - - return { - isValid: errors.length === 0, - errors, - }; - } - - private validateInput(): void { - const value = this.element.value; - if (value) { - const validation = this.validateDate(value); - this.updateValidationState(validation); - } else { - this.clearValidationState(); - } - } - - private updateValidationState(validation: DatePickerValidation): void { - this.validationErrors = validation.errors; - - // Remove existing validation feedback - this.clearValidationFeedback(); - - if (!validation.isValid) { - // Add error class - this.element.classList.add('datepicker-error'); - - // Add validation feedback - const feedback = document.createElement('div'); - feedback.className = 'datepicker-validation-feedback'; - feedback.textContent = validation.errors.join(', '); - - if (this.wrapper) { - this.wrapper.appendChild(feedback); - } - - // Set ARIA attributes - this.element.setAttribute('aria-invalid', 'true'); - this.element.setAttribute('aria-describedby', 'datepicker-error'); - feedback.id = 'datepicker-error'; - } else { - this.clearValidationState(); - } - } - - private clearValidationState(): void { - this.element.classList.remove('datepicker-error'); - this.element.setAttribute('aria-invalid', 'false'); - this.element.removeAttribute('aria-describedby'); - this.validationErrors = []; - this.clearValidationFeedback(); - } - - private clearValidationFeedback(): void { - if (this.wrapper) { - const existingFeedback = this.wrapper.querySelector('.datepicker-validation-feedback'); - if (existingFeedback) { - existingFeedback.remove(); - } - } - } - - private addValidationError(error: string): void { - if (!this.validationErrors.includes(error)) { - this.validationErrors.push(error); - } - } - - private addTodayHighlight(): void { - if (this.options.todayHighlight) { - const today = DateUtils.formatters.inputDate(DateUtils.now()); - if (this.element.value === today) { - this.todayIndicator = document.createElement('div'); - this.todayIndicator.className = 'datepicker-today-indicator'; - this.todayIndicator.title = 'Today'; - - if (this.wrapper) { - this.wrapper.appendChild(this.todayIndicator); - } - } - } - } - - private formatDate(dateString: string): string { - try { - const date = new Date(dateString); - return DateUtils.format(date, this.options.format || 'yyyy-mm-dd'); - } catch (error) { - return dateString; - } - } - - // Public API methods - public setDate(dateString: string): void { - this.element.value = dateString; - this.handleDateChange(dateString); - } - - public getDate(): string { - return this.element.value; - } - - public getFormattedDate(): string { - return this.formatDate(this.element.value); - } - - public getDateObject(): Date | null { - return this.element.value ? new Date(this.element.value) : null; - } - - public isValid(): boolean { - return this.validationErrors.length === 0; - } - - public getValidationErrors(): string[] { - return [...this.validationErrors]; - } - - public setMinDate(dateString: string): void { - this.options.minDate = dateString; - this.element.min = dateString; - this.validateInput(); - } - - public setMaxDate(dateString: string): void { - this.options.maxDate = dateString; - this.element.max = dateString; - this.validateInput(); - } - - public reset(): void { - this.element.value = ''; - this.clearValidationState(); - if (this.todayIndicator) { - this.todayIndicator.remove(); - this.todayIndicator = null; - } - } - - public enable(): void { - this.element.disabled = false; - } - - public disable(): void { - this.element.disabled = true; - } - - public updateOptions(newOptions: Partial): void { - this.options = { ...this.options, ...newOptions }; - this.validateConstraints(); - this.validateInput(); - } -} - -// DatePicker Manager -export class DatePickerManager { - private instances: Map = new Map(); - - public initialize(selector: string, options: DatePickerOptions = {}): VanillaDatePicker[] { - const elements = document.querySelectorAll(selector); - const instances: VanillaDatePicker[] = []; - - elements.forEach((element, index) => { - // Clean up existing instance - if (element.vanillaDatePicker) { - element.vanillaDatePicker.destroy(); - } - - // Create new instance - const datePicker = new VanillaDatePicker(element, options); - element.vanillaDatePicker = datePicker; - - // Store in manager - const key = `${selector}-${index}`; - this.instances.set(key, datePicker); - instances.push(datePicker); - }); - - return instances; - } - - public getInstances(selector: string): VanillaDatePicker[] { - const instances: VanillaDatePicker[] = []; - this.instances.forEach((instance, key) => { - if (key.startsWith(selector)) { - instances.push(instance); - } - }); - return instances; - } - - public destroyInstances(selector: string): void { - const keysToDelete: string[] = []; - this.instances.forEach((instance, key) => { - if (key.startsWith(selector)) { - instance.destroy(); - keysToDelete.push(key); - } - }); - keysToDelete.forEach(key => this.instances.delete(key)); - } - - public destroyAll(): void { - this.instances.forEach(instance => instance.destroy()); - this.instances.clear(); - } -} - -// Create singleton manager -const datePickerManager = new DatePickerManager(); - -// Initialize date pickers -const initializeDatePickers = (): void => { - // Start date pickers - datePickerManager.initialize('.start-date', { - format: 'yyyy-mm-dd', - autoclose: true, - todayHighlight: true, - }); - - // End date pickers - datePickerManager.initialize('.end-date', { - format: 'yyyy-mm-dd', - autoclose: true, - todayHighlight: true, - }); - - // Generic date pickers - datePickerManager.initialize('input[type="date"]:not(.start-date):not(.end-date)', { - format: 'yyyy-mm-dd', - autoclose: true, - todayHighlight: true, - }); -}; - -// Initialize on load -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initializeDatePickers); -} else { - initializeDatePickers(); -} - -// Reinitialize on theme change -window.addEventListener('adminator:themeChanged', () => { - setTimeout(initializeDatePickers, 100); -}); - -// Cleanup on page unload -window.addEventListener('beforeunload', () => { - datePickerManager.destroyAll(); -}); - -// Export default for compatibility -export default { - init: initializeDatePickers, - manager: datePickerManager, - VanillaDatePicker, - DatePickerManager, -}; \ No newline at end of file diff --git a/src/assets/scripts/ui/index.ts b/src/assets/scripts/ui/index.ts deleted file mode 100644 index cee82d4..0000000 --- a/src/assets/scripts/ui/index.ts +++ /dev/null @@ -1,740 +0,0 @@ -/** - * UI Bootstrap Components with TypeScript - * Vanilla JavaScript implementations for Bootstrap components - */ - -import type { ComponentInterface } from '../../types'; - -// Type definitions for UI components -export interface UIComponentOptions { - autoInit?: boolean; - selector?: string; -} - -export interface TooltipOptions { - placement?: 'top' | 'bottom' | 'left' | 'right'; - delay?: number; - animation?: boolean; -} - -export interface PopoverOptions { - placement?: 'top' | 'bottom' | 'left' | 'right'; - trigger?: 'click' | 'hover' | 'focus' | 'manual'; - html?: boolean; - animation?: boolean; -} - -export interface ModalOptions { - backdrop?: boolean | 'static'; - keyboard?: boolean; - focus?: boolean; - show?: boolean; -} - -export interface AccordionOptions { - parent?: string; - toggle?: boolean; -} - -export interface DropdownOptions { - offset?: [number, number]; - flip?: boolean; - boundary?: 'clippingParents' | 'viewport' | HTMLElement; -} - -// Modal functionality -export class VanillaModal implements ComponentInterface { - public name: string = 'VanillaModal'; - public element: HTMLElement; - public options: ModalOptions; - public isInitialized: boolean = false; - - private modal: HTMLElement | null = null; - private backdrop: HTMLElement | null = null; - private isOpen: boolean = false; - private escapeHandler: ((e: KeyboardEvent) => void) | null = null; - - constructor(element: HTMLElement, options: ModalOptions = {}) { - this.element = element; - this.options = { - backdrop: true, - keyboard: true, - focus: true, - show: false, - ...options, - }; - this.init(); - } - - public init(): void { - const targetSelector = this.element.getAttribute('data-bs-target'); - if (!targetSelector) { - console.warn('Modal: Missing data-bs-target attribute'); - return; - } - - this.modal = document.querySelector(targetSelector); - if (!this.modal) { - console.warn(`Modal: Target element ${targetSelector} not found`); - return; - } - - this.element.addEventListener('click', this.handleElementClick.bind(this)); - - // Close button functionality - const closeButtons = this.modal.querySelectorAll('[data-bs-dismiss="modal"]'); - closeButtons.forEach(btn => { - btn.addEventListener('click', this.hide.bind(this)); - }); - - // Close on backdrop click - if (this.options.backdrop !== false) { - this.modal.addEventListener('click', this.handleBackdropClick.bind(this)); - } - - this.isInitialized = true; - } - - public destroy(): void { - if (this.escapeHandler) { - document.removeEventListener('keydown', this.escapeHandler); - this.escapeHandler = null; - } - this.hide(); - this.isInitialized = false; - } - - private handleElementClick(e: Event): void { - e.preventDefault(); - this.show(); - } - - private handleBackdropClick(e: Event): void { - if (e.target === this.modal && this.options.backdrop !== 'static') { - this.hide(); - } - } - - public show(): void { - if (this.isOpen || !this.modal) return; - - // Create backdrop - if (this.options.backdrop !== false) { - this.backdrop = document.createElement('div'); - this.backdrop.className = 'modal-backdrop fade show'; - document.body.appendChild(this.backdrop); - } - - // Show modal - this.modal.style.display = 'block'; - this.modal.classList.add('show'); - document.body.classList.add('modal-open'); - - this.isOpen = true; - - // Focus the modal - if (this.options.focus) { - this.modal.setAttribute('tabindex', '-1'); - this.modal.focus(); - } - - // Escape key handler - if (this.options.keyboard) { - this.escapeHandler = this.handleEscapeKey.bind(this); - document.addEventListener('keydown', this.escapeHandler); - } - } - - public hide(): void { - if (!this.isOpen || !this.modal) return; - - // Hide modal - this.modal.classList.remove('show'); - this.modal.style.display = 'none'; - document.body.classList.remove('modal-open'); - - // Remove backdrop - if (this.backdrop) { - this.backdrop.remove(); - this.backdrop = null; - } - - this.isOpen = false; - - // Remove escape handler - if (this.escapeHandler) { - document.removeEventListener('keydown', this.escapeHandler); - this.escapeHandler = null; - } - } - - private handleEscapeKey(e: KeyboardEvent): void { - if (e.key === 'Escape') { - this.hide(); - } - } - - public toggle(): void { - if (this.isOpen) { - this.hide(); - } else { - this.show(); - } - } - - public isVisible(): boolean { - return this.isOpen; - } -} - -// Dropdown functionality -export class VanillaDropdown implements ComponentInterface { - public name: string = 'VanillaDropdown'; - public element: HTMLElement; - public options: DropdownOptions; - public isInitialized: boolean = false; - - private menu: HTMLElement | null = null; - private isOpen: boolean = false; - private outsideClickHandler: ((e: Event) => void) | null = null; - private escapeHandler: ((e: KeyboardEvent) => void) | null = null; - - constructor(element: HTMLElement, options: DropdownOptions = {}) { - this.element = element; - this.options = { - offset: [0, 2], - flip: true, - boundary: 'clippingParents', - ...options, - }; - this.init(); - } - - public init(): void { - const parent = this.element.parentNode as HTMLElement; - if (!parent) return; - - this.menu = parent.querySelector('.dropdown-menu'); - if (!this.menu) return; - - this.element.addEventListener('click', this.handleElementClick.bind(this)); - - // Setup event handlers - this.outsideClickHandler = this.handleOutsideClick.bind(this); - this.escapeHandler = this.handleEscapeKey.bind(this); - - this.isInitialized = true; - } - - public destroy(): void { - this.hide(); - if (this.outsideClickHandler) { - document.removeEventListener('click', this.outsideClickHandler); - this.outsideClickHandler = null; - } - if (this.escapeHandler) { - document.removeEventListener('keydown', this.escapeHandler); - this.escapeHandler = null; - } - this.isInitialized = false; - } - - private handleElementClick(e: Event): void { - e.preventDefault(); - e.stopPropagation(); - this.toggle(); - } - - private handleOutsideClick(e: Event): void { - const parent = this.element.parentNode as HTMLElement; - if (parent && !parent.contains(e.target as Node)) { - this.hide(); - } - } - - private handleEscapeKey(e: KeyboardEvent): void { - if (e.key === 'Escape' && this.isOpen) { - this.hide(); - } - } - - public toggle(): void { - if (this.isOpen) { - this.hide(); - } else { - this.show(); - } - } - - public show(): void { - if (this.isOpen || !this.menu) return; - - // Close other dropdowns - document.querySelectorAll('.dropdown-menu.show').forEach(menu => { - menu.classList.remove('show'); - }); - - this.menu.classList.add('show'); - this.element.setAttribute('aria-expanded', 'true'); - this.isOpen = true; - - // Add event listeners - if (this.outsideClickHandler) { - document.addEventListener('click', this.outsideClickHandler); - } - if (this.escapeHandler) { - document.addEventListener('keydown', this.escapeHandler); - } - } - - public hide(): void { - if (!this.isOpen || !this.menu) return; - - this.menu.classList.remove('show'); - this.element.setAttribute('aria-expanded', 'false'); - this.isOpen = false; - - // Remove event listeners - if (this.outsideClickHandler) { - document.removeEventListener('click', this.outsideClickHandler); - } - if (this.escapeHandler) { - document.removeEventListener('keydown', this.escapeHandler); - } - } -} - -// Popover functionality -export class VanillaPopover implements ComponentInterface { - public name: string = 'VanillaPopover'; - public element: HTMLElement; - public options: PopoverOptions; - public isInitialized: boolean = false; - - private popover: HTMLElement | null = null; - private isOpen: boolean = false; - private outsideClickHandler: ((e: Event) => void) | null = null; - - constructor(element: HTMLElement, options: PopoverOptions = {}) { - this.element = element; - this.options = { - placement: 'top', - trigger: 'click', - html: false, - animation: true, - ...options, - }; - this.init(); - } - - public init(): void { - if (this.options.trigger === 'click') { - this.element.addEventListener('click', this.handleElementClick.bind(this)); - } else if (this.options.trigger === 'hover') { - this.element.addEventListener('mouseenter', this.show.bind(this)); - this.element.addEventListener('mouseleave', this.hide.bind(this)); - } else if (this.options.trigger === 'focus') { - this.element.addEventListener('focus', this.show.bind(this)); - this.element.addEventListener('blur', this.hide.bind(this)); - } - - this.outsideClickHandler = this.handleOutsideClick.bind(this); - this.isInitialized = true; - } - - public destroy(): void { - this.hide(); - if (this.outsideClickHandler) { - document.removeEventListener('click', this.outsideClickHandler); - this.outsideClickHandler = null; - } - this.isInitialized = false; - } - - private handleElementClick(e: Event): void { - e.preventDefault(); - this.toggle(); - } - - private handleOutsideClick(e: Event): void { - if (!this.element.contains(e.target as Node) && - (!this.popover || !this.popover.contains(e.target as Node))) { - this.hide(); - } - } - - public toggle(): void { - if (this.isOpen) { - this.hide(); - } else { - this.show(); - } - } - - public show(): void { - if (this.isOpen) return; - - // Close other popovers - document.querySelectorAll('.popover').forEach(popover => { - popover.remove(); - }); - - const title = this.element.getAttribute('title') || this.element.getAttribute('data-bs-title'); - const content = this.element.getAttribute('data-bs-content'); - - if (!content) return; - - this.popover = document.createElement('div'); - this.popover.className = `popover bs-popover-${this.options.placement} show`; - this.popover.style.position = 'absolute'; - this.popover.style.zIndex = '1070'; - this.popover.style.maxWidth = '276px'; - this.popover.style.backgroundColor = '#fff'; - this.popover.style.border = '1px solid rgba(0,0,0,.2)'; - this.popover.style.borderRadius = '6px'; - this.popover.style.boxShadow = '0 5px 10px rgba(0,0,0,.2)'; - - let popoverContent = ''; - if (title) { - popoverContent += `
${title}
`; - } - popoverContent += `
${content}
`; - - this.popover.innerHTML = popoverContent; - document.body.appendChild(this.popover); - - // Position popover - this.positionPopover(); - - this.isOpen = true; - - // Add outside click handler - if (this.outsideClickHandler) { - document.addEventListener('click', this.outsideClickHandler); - } - } - - public hide(): void { - if (!this.isOpen) return; - - if (this.popover) { - this.popover.remove(); - this.popover = null; - } - this.isOpen = false; - - // Remove outside click handler - if (this.outsideClickHandler) { - document.removeEventListener('click', this.outsideClickHandler); - } - } - - private positionPopover(): void { - if (!this.popover) return; - - const rect = this.element.getBoundingClientRect(); - const popoverRect = this.popover.getBoundingClientRect(); - - switch (this.options.placement) { - case 'top': - this.popover.style.left = `${rect.left + (rect.width / 2) - (popoverRect.width / 2)}px`; - this.popover.style.top = `${rect.top - popoverRect.height - 10}px`; - break; - case 'bottom': - this.popover.style.left = `${rect.left + (rect.width / 2) - (popoverRect.width / 2)}px`; - this.popover.style.top = `${rect.bottom + 10}px`; - break; - case 'left': - this.popover.style.left = `${rect.left - popoverRect.width - 10}px`; - this.popover.style.top = `${rect.top + (rect.height / 2) - (popoverRect.height / 2)}px`; - break; - case 'right': - this.popover.style.left = `${rect.right + 10}px`; - this.popover.style.top = `${rect.top + (rect.height / 2) - (popoverRect.height / 2)}px`; - break; - } - } -} - -// Tooltip functionality -export class VanillaTooltip implements ComponentInterface { - public name: string = 'VanillaTooltip'; - public element: HTMLElement; - public options: TooltipOptions; - public isInitialized: boolean = false; - - private tooltip: HTMLElement | null = null; - private showTimeout: number | null = null; - private hideTimeout: number | null = null; - - constructor(element: HTMLElement, options: TooltipOptions = {}) { - this.element = element; - this.options = { - placement: 'top', - delay: 0, - animation: true, - ...options, - }; - this.init(); - } - - public init(): void { - this.element.addEventListener('mouseenter', this.handleMouseEnter.bind(this)); - this.element.addEventListener('mouseleave', this.handleMouseLeave.bind(this)); - this.element.addEventListener('focus', this.handleFocus.bind(this)); - this.element.addEventListener('blur', this.handleBlur.bind(this)); - this.isInitialized = true; - } - - public destroy(): void { - this.hide(); - this.clearTimeouts(); - this.isInitialized = false; - } - - private handleMouseEnter(): void { - this.clearTimeouts(); - this.showTimeout = window.setTimeout(() => this.show(), this.options.delay); - } - - private handleMouseLeave(): void { - this.clearTimeouts(); - this.hideTimeout = window.setTimeout(() => this.hide(), this.options.delay); - } - - private handleFocus(): void { - this.show(); - } - - private handleBlur(): void { - this.hide(); - } - - private clearTimeouts(): void { - if (this.showTimeout) { - clearTimeout(this.showTimeout); - this.showTimeout = null; - } - if (this.hideTimeout) { - clearTimeout(this.hideTimeout); - this.hideTimeout = null; - } - } - - public show(): void { - if (this.tooltip) return; - - const title = this.element.getAttribute('title') || this.element.getAttribute('data-bs-title'); - if (!title) return; - - this.tooltip = document.createElement('div'); - this.tooltip.className = `tooltip bs-tooltip-${this.options.placement} show`; - this.tooltip.style.position = 'absolute'; - this.tooltip.style.zIndex = '1070'; - this.tooltip.style.maxWidth = '200px'; - this.tooltip.style.padding = '4px 8px'; - this.tooltip.style.fontSize = '12px'; - this.tooltip.style.backgroundColor = '#000'; - this.tooltip.style.color = '#fff'; - this.tooltip.style.borderRadius = '4px'; - this.tooltip.style.pointerEvents = 'none'; - this.tooltip.style.whiteSpace = 'nowrap'; - - this.tooltip.innerHTML = `
${title}
`; - document.body.appendChild(this.tooltip); - - // Position tooltip - this.positionTooltip(); - } - - public hide(): void { - if (this.tooltip) { - this.tooltip.remove(); - this.tooltip = null; - } - } - - private positionTooltip(): void { - if (!this.tooltip) return; - - const rect = this.element.getBoundingClientRect(); - const tooltipRect = this.tooltip.getBoundingClientRect(); - - switch (this.options.placement) { - case 'top': - this.tooltip.style.left = `${rect.left + (rect.width / 2) - (tooltipRect.width / 2)}px`; - this.tooltip.style.top = `${rect.top - tooltipRect.height - 5}px`; - break; - case 'bottom': - this.tooltip.style.left = `${rect.left + (rect.width / 2) - (tooltipRect.width / 2)}px`; - this.tooltip.style.top = `${rect.bottom + 5}px`; - break; - case 'left': - this.tooltip.style.left = `${rect.left - tooltipRect.width - 5}px`; - this.tooltip.style.top = `${rect.top + (rect.height / 2) - (tooltipRect.height / 2)}px`; - break; - case 'right': - this.tooltip.style.left = `${rect.right + 5}px`; - this.tooltip.style.top = `${rect.top + (rect.height / 2) - (tooltipRect.height / 2)}px`; - break; - } - } -} - -// Accordion functionality -export class VanillaAccordion implements ComponentInterface { - public name: string = 'VanillaAccordion'; - public element: HTMLElement; - public options: AccordionOptions; - public isInitialized: boolean = false; - - private accordion: HTMLElement | null = null; - private target: HTMLElement | null = null; - private isOpen: boolean = false; - - constructor(element: HTMLElement, options: AccordionOptions = {}) { - this.element = element; - this.options = { - toggle: true, - ...options, - }; - this.init(); - } - - public init(): void { - this.accordion = this.element.closest('.accordion'); - const targetSelector = this.element.getAttribute('data-bs-target'); - if (!targetSelector) return; - - this.target = document.querySelector(targetSelector); - if (!this.target) return; - - this.isOpen = !this.element.classList.contains('collapsed'); - this.element.addEventListener('click', this.handleElementClick.bind(this)); - this.isInitialized = true; - } - - public destroy(): void { - this.isInitialized = false; - } - - private handleElementClick(e: Event): void { - e.preventDefault(); - this.toggle(); - } - - public toggle(): void { - if (this.isOpen) { - this.hide(); - } else { - this.show(); - } - } - - public show(): void { - if (this.isOpen || !this.target) return; - - // Close other accordion items in the same parent - if (this.accordion) { - const otherItems = this.accordion.querySelectorAll('.accordion-collapse.show'); - otherItems.forEach(item => { - if (item !== this.target) { - item.classList.remove('show'); - const button = this.accordion!.querySelector(`[data-bs-target="#${item.id}"]`); - if (button) { - button.classList.add('collapsed'); - button.setAttribute('aria-expanded', 'false'); - } - } - }); - } - - // Show this item - this.target.classList.add('show'); - this.element.classList.remove('collapsed'); - this.element.setAttribute('aria-expanded', 'true'); - this.isOpen = true; - } - - public hide(): void { - if (!this.isOpen || !this.target) return; - - this.target.classList.remove('show'); - this.element.classList.add('collapsed'); - this.element.setAttribute('aria-expanded', 'false'); - this.isOpen = false; - } -} - -// UI Manager Class -export class UIManager { - private components: Map = new Map(); - - public initializeComponents(): void { - // Initialize modals - document.querySelectorAll('[data-bs-toggle="modal"]').forEach(element => { - const modal = new VanillaModal(element); - this.components.set(`modal-${element.id || Date.now()}`, modal); - }); - - // Initialize dropdowns - document.querySelectorAll('[data-bs-toggle="dropdown"]').forEach(element => { - const dropdown = new VanillaDropdown(element); - this.components.set(`dropdown-${element.id || Date.now()}`, dropdown); - }); - - // Initialize popovers - document.querySelectorAll('[data-bs-toggle="popover"]').forEach(element => { - const popover = new VanillaPopover(element); - this.components.set(`popover-${element.id || Date.now()}`, popover); - }); - - // Initialize tooltips - document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(element => { - const tooltip = new VanillaTooltip(element); - this.components.set(`tooltip-${element.id || Date.now()}`, tooltip); - }); - - // Initialize accordions - document.querySelectorAll('[data-bs-toggle="collapse"]').forEach(element => { - const accordion = new VanillaAccordion(element); - this.components.set(`accordion-${element.id || Date.now()}`, accordion); - }); - } - - public destroyComponents(): void { - this.components.forEach(component => { - component.destroy(); - }); - this.components.clear(); - } - - public getComponent(id: string): ComponentInterface | undefined { - return this.components.get(id); - } -} - -// Create and export singleton instance -const uiManager = new UIManager(); - -// Initialize when DOM is ready -const initializeUI = (): void => { - uiManager.initializeComponents(); -}; - -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initializeUI); -} else { - initializeUI(); -} - -// Export default object for compatibility -export default { - init: initializeUI, - manager: uiManager, - Modal: VanillaModal, - Dropdown: VanillaDropdown, - Popover: VanillaPopover, - Tooltip: VanillaTooltip, - Accordion: VanillaAccordion, -}; \ No newline at end of file diff --git a/src/assets/scripts/utils/date.ts b/src/assets/scripts/utils/date.ts deleted file mode 100644 index e6eafd7..0000000 --- a/src/assets/scripts/utils/date.ts +++ /dev/null @@ -1,363 +0,0 @@ -/** - * Modern Date Utilities with TypeScript - * Using Day.js (2KB) instead of Moment.js (67KB) - 97% size reduction - * Provides consistent date formatting and manipulation across the application - */ - -import dayjs, { Dayjs, ConfigType, UnitType, ManipulateType } from 'dayjs'; -import utc from 'dayjs/plugin/utc'; -import timezone from 'dayjs/plugin/timezone'; -import relativeTime from 'dayjs/plugin/relativeTime'; -import customParseFormat from 'dayjs/plugin/customParseFormat'; -import advancedFormat from 'dayjs/plugin/advancedFormat'; -import isBetween from 'dayjs/plugin/isBetween'; - -// Enable Day.js plugins -dayjs.extend(utc); -dayjs.extend(timezone); -dayjs.extend(relativeTime); -dayjs.extend(customParseFormat); -dayjs.extend(advancedFormat); -dayjs.extend(isBetween); - -// Type definitions -export interface CalendarDay { - date: string; - day: number; - isCurrentMonth: boolean; - isToday: boolean; - dayjs: Dayjs; -} - -export interface CalendarMonth { - month: string; - year: number; - monthIndex: number; - days: CalendarDay[]; -} - -export interface WeekDay { - date: string; - day: number; - dayName: string; - shortDayName: string; - isToday: boolean; - dayjs: Dayjs; -} - -export interface WeekData { - weekStart: string; - weekEnd: string; - days: WeekDay[]; -} - -export interface ChartDatePoint { - date: string; - label: string; - value: string; - dayjs: Dayjs; -} - -export type DateInput = ConfigType; -export type DateUnit = UnitType; -export type DateManipulateUnit = ManipulateType; - -export interface DateFormatters { - shortDate: (date: DateInput) => string; - longDate: (date: DateInput) => string; - dateTime: (date: DateInput) => string; - calendarDate: (date: DateInput) => string; - calendarDateTime: (date: DateInput) => string; - inputDate: (date: DateInput) => string; - inputDateTime: (date: DateInput) => string; - timeOnly: (date: DateInput) => string; - monthYear: (date: DateInput) => string; - dayMonth: (date: DateInput) => string; - relative: (date: DateInput) => string; - relativeCalendar: (date: DateInput) => string; -} - -export interface DateCalendarUtils { - getMonthData: (date?: DateInput) => CalendarMonth; - getWeekData: (date?: DateInput) => WeekData; -} - -export interface DateFormUtils { - toInputValue: (date: DateInput) => string; - toDateTimeInputValue: (date: DateInput) => string; - fromInputValue: (value: string) => Dayjs; - validateDateInput: (value: string) => boolean; -} - -export interface DateChartUtils { - generateDateRange: (start: DateInput, end: DateInput, interval?: DateManipulateUnit) => ChartDatePoint[]; - getChartLabels: (period?: 'week' | 'month' | 'year') => string[]; -} - -export interface DateTimezoneUtils { - convert: (date: DateInput, tz: string) => Dayjs; - utc: (date: DateInput) => Dayjs; - local: (date: DateInput) => Dayjs; - guess: () => string; -} - -export interface DateUtilsInterface { - now: () => Dayjs; - parse: (input: DateInput, format?: string) => Dayjs; - format: (date: DateInput, format?: string) => string; - formatters: DateFormatters; - add: (date: DateInput, amount: number, unit: DateManipulateUnit) => Dayjs; - subtract: (date: DateInput, amount: number, unit: DateManipulateUnit) => Dayjs; - startOf: (date: DateInput, unit: DateUnit) => Dayjs; - endOf: (date: DateInput, unit: DateUnit) => Dayjs; - isBefore: (date1: DateInput, date2: DateInput) => boolean; - isAfter: (date1: DateInput, date2: DateInput) => boolean; - isSame: (date1: DateInput, date2: DateInput, unit?: DateUnit) => boolean; - isBetween: (date: DateInput, start: DateInput, end: DateInput) => boolean; - isValid: (date: DateInput) => boolean; - timezone: DateTimezoneUtils; - calendar: DateCalendarUtils; - form: DateFormUtils; - charts: DateChartUtils; -} - -export const DateUtils: DateUtilsInterface = { - /** - * Get current date/time - */ - now: (): Dayjs => dayjs(), - - /** - * Parse date from string or Date object - */ - parse: (input: DateInput, format?: string): Dayjs => { - return format ? dayjs(input, format) : dayjs(input); - }, - - /** - * Format date for display - */ - format: (date: DateInput, format: string = 'YYYY-MM-DD'): string => { - return dayjs(date).format(format); - }, - - /** - * Common date formatting presets - */ - formatters: { - // Dashboard display formats - shortDate: (date: DateInput): string => dayjs(date).format('MMM DD, YYYY'), - longDate: (date: DateInput): string => dayjs(date).format('MMMM DD, YYYY'), - dateTime: (date: DateInput): string => dayjs(date).format('MMM DD, YYYY h:mm A'), - - // Calendar formats - calendarDate: (date: DateInput): string => dayjs(date).format('YYYY-MM-DD'), - calendarDateTime: (date: DateInput): string => dayjs(date).format('YYYY-MM-DD HH:mm:ss'), - - // Form input formats - inputDate: (date: DateInput): string => dayjs(date).format('YYYY-MM-DD'), - inputDateTime: (date: DateInput): string => dayjs(date).format('YYYY-MM-DDTHH:mm'), - - // Display formats - timeOnly: (date: DateInput): string => dayjs(date).format('h:mm A'), - monthYear: (date: DateInput): string => dayjs(date).format('MMMM YYYY'), - dayMonth: (date: DateInput): string => dayjs(date).format('DD MMM'), - - // Relative time - relative: (date: DateInput): string => dayjs(date).fromNow(), - relativeCalendar: (date: DateInput): string => { - const now = dayjs(); - const target = dayjs(date); - const diffDays = now.diff(target, 'day'); - - if (diffDays === 0) return 'Today'; - if (diffDays === 1) return 'Yesterday'; - if (diffDays === -1) return 'Tomorrow'; - if (diffDays > 1 && diffDays < 7) return `${diffDays} days ago`; - if (diffDays < -1 && diffDays > -7) return `In ${Math.abs(diffDays)} days`; - return target.format('MMM DD, YYYY'); - }, - }, - - /** - * Date manipulation - */ - add: (date: DateInput, amount: number, unit: DateManipulateUnit): Dayjs => - dayjs(date).add(amount, unit), - - subtract: (date: DateInput, amount: number, unit: DateManipulateUnit): Dayjs => - dayjs(date).subtract(amount, unit), - - startOf: (date: DateInput, unit: DateUnit): Dayjs => - dayjs(date).startOf(unit), - - endOf: (date: DateInput, unit: DateUnit): Dayjs => - dayjs(date).endOf(unit), - - /** - * Date comparison - */ - isBefore: (date1: DateInput, date2: DateInput): boolean => - dayjs(date1).isBefore(dayjs(date2)), - - isAfter: (date1: DateInput, date2: DateInput): boolean => - dayjs(date1).isAfter(dayjs(date2)), - - isSame: (date1: DateInput, date2: DateInput, unit: DateUnit = 'day'): boolean => - dayjs(date1).isSame(dayjs(date2), unit), - - isBetween: (date: DateInput, start: DateInput, end: DateInput): boolean => - dayjs(date).isBetween(dayjs(start), dayjs(end)), - - /** - * Date validation - */ - isValid: (date: DateInput): boolean => dayjs(date).isValid(), - - /** - * Timezone utilities - */ - timezone: { - convert: (date: DateInput, tz: string): Dayjs => dayjs(date).tz(tz), - utc: (date: DateInput): Dayjs => dayjs(date).utc(), - local: (date: DateInput): Dayjs => dayjs(date).local(), - guess: (): string => dayjs.tz.guess(), - }, - - /** - * Calendar utilities - */ - calendar: { - // Get calendar month data for building calendar views - getMonthData: (date?: DateInput): CalendarMonth => { - const target = date ? dayjs(date) : dayjs(); - const startOfMonth = target.startOf('month'); - const endOfMonth = target.endOf('month'); - const startOfCalendar = startOfMonth.startOf('week'); - const endOfCalendar = endOfMonth.endOf('week'); - - const days: CalendarDay[] = []; - let current = startOfCalendar; - - while (current.isBefore(endOfCalendar) || current.isSame(endOfCalendar, 'day')) { - days.push({ - date: current.format('YYYY-MM-DD'), - day: current.date(), - isCurrentMonth: current.isSame(target, 'month'), - isToday: current.isSame(dayjs(), 'day'), - dayjs: current.clone(), - }); - current = current.add(1, 'day'); - } - - return { - month: target.format('MMMM YYYY'), - year: target.year(), - monthIndex: target.month(), - days, - }; - }, - - // Get week data - getWeekData: (date?: DateInput): WeekData => { - const target = date ? dayjs(date) : dayjs(); - const startOfWeek = target.startOf('week'); - const endOfWeek = target.endOf('week'); - - const days: WeekDay[] = []; - let current = startOfWeek; - - while (current.isBefore(endOfWeek) || current.isSame(endOfWeek, 'day')) { - days.push({ - date: current.format('YYYY-MM-DD'), - day: current.date(), - dayName: current.format('dddd'), - shortDayName: current.format('ddd'), - isToday: current.isSame(dayjs(), 'day'), - dayjs: current.clone(), - }); - current = current.add(1, 'day'); - } - - return { - weekStart: startOfWeek.format('MMM DD'), - weekEnd: endOfWeek.format('MMM DD, YYYY'), - days, - }; - }, - }, - - /** - * Form utilities - */ - form: { - // Convert date to HTML5 input format - toInputValue: (date: DateInput): string => dayjs(date).format('YYYY-MM-DD'), - toDateTimeInputValue: (date: DateInput): string => dayjs(date).format('YYYY-MM-DDTHH:mm'), - - // Parse from HTML5 input - fromInputValue: (value: string): Dayjs => dayjs(value), - - // Validate date input - validateDateInput: (value: string): boolean => { - const parsed = dayjs(value); - return parsed.isValid() && value.length >= 8; // Basic validation - }, - }, - - /** - * Chart/Data utilities - */ - charts: { - // Generate date ranges for charts - generateDateRange: ( - start: DateInput, - end: DateInput, - interval: DateManipulateUnit = 'day' - ): ChartDatePoint[] => { - const dates: ChartDatePoint[] = []; - let current = dayjs(start); - const endDate = dayjs(end); - - while (current.isBefore(endDate) || current.isSame(endDate, interval)) { - dates.push({ - date: current.format('YYYY-MM-DD'), - label: current.format('MMM DD'), - value: current.toISOString(), - dayjs: current.clone(), - }); - current = current.add(1, interval); - } - - return dates; - }, - - // Get common chart date labels - getChartLabels: (period: 'week' | 'month' | 'year' = 'week'): string[] => { - const now = dayjs(); - - switch (period) { - case 'week': - return Array.from({ length: 7 }, (_, i) => - now.subtract(6 - i, 'day').format('ddd') - ); - case 'month': - return Array.from({ length: 30 }, (_, i) => - now.subtract(29 - i, 'day').format('DD') - ); - case 'year': - return Array.from({ length: 12 }, (_, i) => - now.subtract(11 - i, 'month').format('MMM') - ); - default: - return []; - } - }, - }, -}; - -// Export dayjs instance for direct use when needed -export { dayjs }; - -// Default export -export default DateUtils; \ No newline at end of file diff --git a/src/assets/scripts/utils/dom.ts b/src/assets/scripts/utils/dom.ts deleted file mode 100644 index 9661ed4..0000000 --- a/src/assets/scripts/utils/dom.ts +++ /dev/null @@ -1,513 +0,0 @@ -/** - * DOM Utility Functions - * Provides jQuery-like functionality using vanilla JavaScript with TypeScript support - */ - -import type { DOMUtilities, AnimationOptions } from '../../../types'; - -export type ElementSelector = string | Element | null; - -interface ElementDimensions { - width: number; - height: number; - top: number; - left: number; - bottom: number; - right: number; -} - -interface SlideAnimationKeyframes { - height: string; -} - -interface FadeAnimationKeyframes { - opacity: number; -} - -/** - * Convert string selector to element or return element as-is - */ -function getElement(element: ElementSelector): Element | null { - if (typeof element === 'string') { - return document.querySelector(element); - } - return element; -} - -/** - * DOM Utility object with type-safe methods - */ -export const DOM: DOMUtilities = { - /** - * Document ready (replaces $(document).ready()) - */ - ready: (callback: () => void): void => { - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', callback); - } else { - callback(); - } - }, - - /** - * Select single element (replaces $('selector')) - */ - select: (selector: string, context: Element | Document = document): HTMLElement | null => { - return context.querySelector(selector); - }, - - /** - * Select multiple elements (replaces $('selector')) - */ - selectAll: (selector: string, context: Element | Document = document): HTMLElement[] => { - return Array.from(context.querySelectorAll(selector)); - }, - - /** - * Check if element exists - */ - exists: (selector: string, context: Element | Document = document): boolean => { - return context.querySelector(selector) !== null; - }, - - /** - * Add event listener (replaces $.on()) - */ - on: ( - element: Element | Window | Document, - event: string, - handler: (event: Event) => void, - options: AddEventListenerOptions = {} - ): void => { - if (element) { - element.addEventListener(event, handler, options); - } - }, - - /** - * Remove event listener (replaces $.off()) - */ - off: ( - element: Element | Window | Document, - event: string, - handler: (event: Event) => void - ): void => { - if (element) { - element.removeEventListener(event, handler); - } - }, - - /** - * Add class (replaces $.addClass()) - */ - addClass: (element: Element, className: string): void => { - const el = getElement(element); - if (el) { - el.classList.add(className); - } - }, - - /** - * Remove class (replaces $.removeClass()) - */ - removeClass: (element: Element, className: string): void => { - const el = getElement(element); - if (el) { - el.classList.remove(className); - } - }, - - /** - * Toggle class (replaces $.toggleClass()) - */ - toggleClass: (element: Element, className: string): void => { - const el = getElement(element); - if (el) { - el.classList.toggle(className); - } - }, - - /** - * Check if element has class (replaces $.hasClass()) - */ - hasClass: (element: Element, className: string): boolean => { - const el = getElement(element); - return el ? el.classList.contains(className) : false; - }, - - /** - * Get/Set attribute (replaces $.attr()) - */ - attr: (element: Element, name: string, value?: string): string | void => { - const el = getElement(element); - if (!el) return; - - if (value === undefined) { - return el.getAttribute(name) || ''; - } else { - el.setAttribute(name, value); - } - }, - - /** - * Get/Set data attribute (replaces $.data()) - */ - data: (element: Element, name: string, value?: any): any => { - const el = getElement(element); - if (!el) return null; - - const dataName = `data-${name}`; - - if (value === undefined) { - const attrValue = el.getAttribute(dataName); - // Try to parse JSON for complex data - if (attrValue) { - try { - return JSON.parse(attrValue); - } catch { - return attrValue; - } - } - return null; - } else { - const stringValue = typeof value === 'object' ? JSON.stringify(value) : String(value); - el.setAttribute(dataName, stringValue); - } - }, -}; - -/** - * Extended DOM utilities with additional functionality - */ -export const DOMExtended = { - ...DOM, - - /** - * Get/Set text content (replaces $.text()) - */ - text: (element: ElementSelector, content?: string): string | void => { - const el = getElement(element); - if (!el) return; - - if (content === undefined) { - return el.textContent || ''; - } else { - el.textContent = content; - } - }, - - /** - * Get/Set HTML content (replaces $.html()) - */ - html: (element: ElementSelector, content?: string): string | void => { - const el = getElement(element); - if (!el) return; - - if (content === undefined) { - return (el as HTMLElement).innerHTML; - } else { - (el as HTMLElement).innerHTML = content; - } - }, - - /** - * Hide element (replaces $.hide()) - */ - hide: (element: ElementSelector): void => { - const el = getElement(element) as HTMLElement; - if (el) { - el.style.display = 'none'; - } - }, - - /** - * Show element (replaces $.show()) - */ - show: (element: ElementSelector, display: string = 'block'): void => { - const el = getElement(element) as HTMLElement; - if (el) { - el.style.display = display; - } - }, - - /** - * Toggle visibility (replaces $.toggle()) - */ - toggle: (element: ElementSelector, display: string = 'block'): void => { - const el = getElement(element) as HTMLElement; - if (el) { - if (el.style.display === 'none') { - el.style.display = display; - } else { - el.style.display = 'none'; - } - } - }, - - /** - * Slide up animation (replaces $.slideUp()) - */ - slideUp: (element: ElementSelector, duration: number = 300): Promise => { - const el = getElement(element) as HTMLElement; - if (!el) return Promise.resolve(); - - return new Promise((resolve) => { - const height = el.scrollHeight; - el.style.height = `${height}px`; - el.style.overflow = 'hidden'; - - const animation = el.animate([ - { height: `${height}px` } as SlideAnimationKeyframes, - { height: '0px' } as SlideAnimationKeyframes, - ], { - duration, - easing: 'ease-in-out', - }); - - animation.onfinish = (): void => { - el.style.display = 'none'; - el.style.height = ''; - el.style.overflow = ''; - resolve(); - }; - }); - }, - - /** - * Slide down animation (replaces $.slideDown()) - */ - slideDown: (element: ElementSelector, duration: number = 300): Promise => { - const el = getElement(element) as HTMLElement; - if (!el) return Promise.resolve(); - - return new Promise((resolve) => { - el.style.display = 'block'; - el.style.height = '0px'; - el.style.overflow = 'hidden'; - - const height = el.scrollHeight; - - const animation = el.animate([ - { height: '0px' } as SlideAnimationKeyframes, - { height: `${height}px` } as SlideAnimationKeyframes, - ], { - duration, - easing: 'ease-in-out', - }); - - animation.onfinish = (): void => { - el.style.height = 'auto'; - el.style.overflow = 'visible'; - resolve(); - }; - }); - }, - - /** - * Fade in animation (replaces $.fadeIn()) - */ - fadeIn: (element: ElementSelector, duration: number = 300): Promise => { - const el = getElement(element) as HTMLElement; - if (!el) return Promise.resolve(); - - return new Promise((resolve) => { - el.style.opacity = '0'; - el.style.display = 'block'; - - const animation = el.animate([ - { opacity: 0 } as FadeAnimationKeyframes, - { opacity: 1 } as FadeAnimationKeyframes, - ], { - duration, - easing: 'ease-in-out', - }); - - animation.onfinish = (): void => { - el.style.opacity = ''; - resolve(); - }; - }); - }, - - /** - * Fade out animation (replaces $.fadeOut()) - */ - fadeOut: (element: ElementSelector, duration: number = 300): Promise => { - const el = getElement(element) as HTMLElement; - if (!el) return Promise.resolve(); - - return new Promise((resolve) => { - const animation = el.animate([ - { opacity: 1 } as FadeAnimationKeyframes, - { opacity: 0 } as FadeAnimationKeyframes, - ], { - duration, - easing: 'ease-in-out', - }); - - animation.onfinish = (): void => { - el.style.display = 'none'; - el.style.opacity = ''; - resolve(); - }; - }); - }, - - /** - * Get element dimensions and position - */ - dimensions: (element: ElementSelector): ElementDimensions | null => { - const el = getElement(element); - if (!el) return null; - - const rect = el.getBoundingClientRect(); - return { - width: rect.width, - height: rect.height, - top: rect.top, - left: rect.left, - bottom: rect.bottom, - right: rect.right, - }; - }, - - /** - * Wait for DOM to be ready (replaces $(document).ready()) - */ - ready: (callback: () => void): void => { - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', callback); - } else { - callback(); - } - }, - - /** - * Create element with attributes and content - */ - create: (tagName: string, attributes?: Record, content?: string): HTMLElement => { - const element = document.createElement(tagName); - - if (attributes) { - Object.entries(attributes).forEach(([key, value]) => { - element.setAttribute(key, value); - }); - } - - if (content) { - element.textContent = content; - } - - return element; - }, - - /** - * Append element to parent - */ - append: (parent: ElementSelector, child: Element): void => { - const parentEl = getElement(parent); - if (parentEl) { - parentEl.appendChild(child); - } - }, - - /** - * Remove element from DOM - */ - remove: (element: ElementSelector): void => { - const el = getElement(element); - if (el && el.parentNode) { - el.parentNode.removeChild(el); - } - }, - - /** - * Get/Set CSS styles - */ - css: (element: ElementSelector, property: string, value?: string): string | void => { - const el = getElement(element) as HTMLElement; - if (!el) return; - - if (value === undefined) { - return window.getComputedStyle(el).getPropertyValue(property); - } else { - el.style.setProperty(property, value); - } - }, - - /** - * Get/Set element value (for form elements) - */ - val: (element: ElementSelector, value?: string): string | void => { - const el = getElement(element) as HTMLInputElement; - if (!el) return; - - if (value === undefined) { - return el.value; - } else { - el.value = value; - } - }, - - /** - * Trigger custom event - */ - trigger: (element: ElementSelector, eventName: string, detail?: any): void => { - const el = getElement(element); - if (el) { - const event = new CustomEvent(eventName, { detail }); - el.dispatchEvent(event); - } - }, - - /** - * Check if element is visible - */ - isVisible: (element: ElementSelector): boolean => { - const el = getElement(element) as HTMLElement; - if (!el) return false; - - const style = window.getComputedStyle(el); - return style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0'; - }, - - /** - * Get element offset relative to document - */ - offset: (element: ElementSelector): { top: number; left: number } | null => { - const el = getElement(element); - if (!el) return null; - - const rect = el.getBoundingClientRect(); - return { - top: rect.top + window.pageYOffset, - left: rect.left + window.pageXOffset, - }; - }, - - /** - * Delegate event handling - */ - delegate: ( - parent: ElementSelector, - selector: string, - event: string, - handler: (event: Event) => void - ): void => { - const parentEl = getElement(parent); - if (parentEl) { - parentEl.addEventListener(event, (e) => { - const target = e.target as Element; - if (target && target.matches(selector)) { - handler(e); - } - }); - } - }, -}; - -// Export both the basic DOM utilities and extended version -export { DOM as default, DOMExtended }; - -// Re-export types for convenience -export type { DOMUtilities, ElementSelector, ElementDimensions }; \ No newline at end of file diff --git a/src/assets/scripts/utils/theme.ts b/src/assets/scripts/utils/theme.ts deleted file mode 100644 index ad09aa2..0000000 --- a/src/assets/scripts/utils/theme.ts +++ /dev/null @@ -1,313 +0,0 @@ -/** - * Theme Management Utilities - * Handles light/dark mode switching with Chart.js integration - */ - -import type { Theme, ThemeConfig, ThemeColors, ThemeChangeEvent } from '../../../types'; - -declare global { - interface Window { - Chart?: any; // Chart.js global object - } -} - -interface VectorMapColors { - backgroundColor: string; - borderColor: string; - regionColor: string; - markerFill: string; - markerStroke: string; - hoverColor: string; - selectedColor: string; - scaleStart: string; - scaleEnd: string; - scaleLight: string; - scaleDark: string; -} - -interface SparklineColors { - success: string; - purple: string; - info: string; - danger: string; - light: string; -} - -interface ChartThemeColors { - textColor: string; - mutedColor: string; - borderColor: string; - gridColor: string; - tooltipBg: string; -} - -const THEME_KEY = 'adminator-theme'; - -/** - * Theme Management Class - */ -class ThemeManager { - private currentTheme: Theme = 'light'; - private config: ThemeConfig; - - constructor(config?: Partial) { - this.config = { - theme: 'light', - autoDetect: true, - persistChoice: true, - ...config, - }; - } - - /** - * Apply theme to the application - */ - apply(theme: Theme): void { - const previousTheme = this.currentTheme; - this.currentTheme = theme; - - // Set theme attribute on document element - document.documentElement.setAttribute('data-theme', theme); - - // Update Chart.js defaults if Chart is available - this.updateChartDefaults(theme); - - // Persist theme choice if enabled - if (this.config.persistChoice) { - this.persistTheme(theme); - } - - // Dispatch theme change event - this.dispatchThemeChange(theme, previousTheme); - } - - /** - * Toggle between light and dark themes - */ - toggle(): void { - const nextTheme: Theme = this.currentTheme === 'dark' ? 'light' : 'dark'; - this.apply(nextTheme); - } - - /** - * Get current theme - */ - current(): Theme { - return this.currentTheme; - } - - /** - * Initialize theme system - */ - init(): void { - let initialTheme: Theme = 'light'; - - // Try to load persisted theme - if (this.config.persistChoice) { - const persistedTheme = this.getPersistedTheme(); - if (persistedTheme) { - initialTheme = persistedTheme; - } else if (this.config.autoDetect) { - // Detect OS preference on first visit - initialTheme = this.detectOSPreference(); - } - } - - this.apply(initialTheme); - } - - /** - * Get CSS custom property value - */ - getCSSVar(varName: string): string { - return getComputedStyle(document.documentElement) - .getPropertyValue(varName) - .trim(); - } - - /** - * Get vector map theme colors - */ - getVectorMapColors(): VectorMapColors { - return { - backgroundColor: this.getCSSVar('--vmap-bg-color'), - borderColor: this.getCSSVar('--vmap-border-color'), - regionColor: this.getCSSVar('--vmap-region-color'), - markerFill: this.getCSSVar('--vmap-marker-fill'), - markerStroke: this.getCSSVar('--vmap-marker-stroke'), - hoverColor: this.getCSSVar('--vmap-hover-color'), - selectedColor: this.getCSSVar('--vmap-selected-color'), - scaleStart: this.getCSSVar('--vmap-scale-start'), - scaleEnd: this.getCSSVar('--vmap-scale-end'), - scaleLight: this.getCSSVar('--vmap-scale-light'), - scaleDark: this.getCSSVar('--vmap-scale-dark'), - }; - } - - /** - * Get sparkline theme colors - */ - getSparklineColors(): SparklineColors { - return { - success: this.getCSSVar('--sparkline-success'), - purple: this.getCSSVar('--sparkline-purple'), - info: this.getCSSVar('--sparkline-info'), - danger: this.getCSSVar('--sparkline-danger'), - light: this.getCSSVar('--sparkline-light'), - }; - } - - /** - * Get chart theme colors - */ - getChartColors(): ChartThemeColors { - const isDark = this.currentTheme === 'dark'; - return { - textColor: isDark ? '#FFFFFF' : '#212529', - mutedColor: isDark ? '#D1D5DB' : '#6C757D', - borderColor: isDark ? '#374151' : '#E2E5E8', - gridColor: isDark ? 'rgba(209, 213, 219, 0.15)' : 'rgba(0, 0, 0, 0.05)', - tooltipBg: isDark ? '#1F2937' : 'rgba(255, 255, 255, 0.95)', - }; - } - - /** - * Update configuration - */ - updateConfig(config: Partial): void { - this.config = { ...this.config, ...config }; - } - - /** - * Get current configuration - */ - getConfig(): ThemeConfig { - return { ...this.config }; - } - - /** - * Private method: Update Chart.js defaults - */ - private updateChartDefaults(theme: Theme): void { - if (!window.Chart || !window.Chart.defaults) { - return; - } - - const isDark = theme === 'dark'; - const colors = this.getChartColors(); - - try { - // Set global defaults - window.Chart.defaults.color = colors.textColor; - window.Chart.defaults.borderColor = colors.borderColor; - window.Chart.defaults.backgroundColor = colors.tooltipBg; - - // Set plugin defaults - if (window.Chart.defaults.plugins?.legend?.labels) { - window.Chart.defaults.plugins.legend.labels.color = colors.textColor; - } - - if (window.Chart.defaults.plugins?.tooltip) { - window.Chart.defaults.plugins.tooltip.backgroundColor = colors.tooltipBg; - window.Chart.defaults.plugins.tooltip.titleColor = colors.textColor; - window.Chart.defaults.plugins.tooltip.bodyColor = colors.textColor; - window.Chart.defaults.plugins.tooltip.borderColor = colors.borderColor; - } - - // Set scale defaults - const scaleDefaults = window.Chart.defaults.scales; - if (scaleDefaults) { - Object.keys(scaleDefaults).forEach(scaleType => { - const scale = scaleDefaults[scaleType]; - if (scale?.ticks) { - scale.ticks.color = colors.mutedColor; - } - if (scale?.grid) { - scale.grid.color = colors.gridColor; - } - if (scale?.pointLabels) { - scale.pointLabels.color = colors.mutedColor; - } - if (scale?.angleLines) { - scale.angleLines.color = colors.gridColor; - } - }); - } - } catch (error) { - console.warn('Error updating Chart.js defaults:', error); - } - } - - /** - * Private method: Persist theme to localStorage - */ - private persistTheme(theme: Theme): void { - try { - localStorage.setItem(THEME_KEY, theme); - } catch (error) { - console.warn('Unable to persist theme:', error); - } - } - - /** - * Private method: Get persisted theme from localStorage - */ - private getPersistedTheme(): Theme | null { - try { - const theme = localStorage.getItem(THEME_KEY) as Theme; - return ['light', 'dark'].includes(theme) ? theme : null; - } catch (error) { - console.warn('Unable to get persisted theme:', error); - return null; - } - } - - /** - * Private method: Detect OS color scheme preference - */ - private detectOSPreference(): Theme { - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - return 'dark'; - } - return 'light'; - } - - /** - * Private method: Dispatch theme change event - */ - private dispatchThemeChange(theme: Theme, previousTheme: Theme): void { - const event: ThemeChangeEvent = new CustomEvent('adminator:themeChanged', { - detail: { theme, previousTheme }, - }) as ThemeChangeEvent; - - window.dispatchEvent(event); - } -} - -// Create singleton instance -const themeManager = new ThemeManager(); - -// Export legacy object interface for compatibility -export const Theme = { - apply: (theme: Theme) => themeManager.apply(theme), - toggle: () => themeManager.toggle(), - current: () => themeManager.current(), - init: () => themeManager.init(), - getCSSVar: (varName: string) => themeManager.getCSSVar(varName), - getVectorMapColors: () => themeManager.getVectorMapColors(), - getSparklineColors: () => themeManager.getSparklineColors(), - getChartColors: () => themeManager.getChartColors(), -}; - -// Export both the manager instance and legacy interface -export { themeManager as ThemeManager }; -export default Theme; - -// Export types for external use -export type { - Theme as ThemeType, - ThemeConfig, - VectorMapColors, - SparklineColors, - ChartThemeColors, -}; \ No newline at end of file diff --git a/src/assets/scripts/vectorMaps/index.ts b/src/assets/scripts/vectorMaps/index.ts deleted file mode 100644 index 0e79419..0000000 --- a/src/assets/scripts/vectorMaps/index.ts +++ /dev/null @@ -1,542 +0,0 @@ -/** - * Vector Maps Implementation with TypeScript - * Interactive world map using JSVectorMap with theme support - */ - -import jsVectorMap from 'jsvectormap'; -import 'jsvectormap/dist/jsvectormap.css'; -import 'jsvectormap/dist/maps/world.js'; -import { debounce } from 'lodash'; -import { ThemeManager } from '../utils/theme'; -import type { ComponentInterface } from '../../types'; - -// Type definitions for Vector Maps -export interface VectorMapMarker { - name: string; - coords: [number, number]; - data?: any; -} - -export interface VectorMapColors { - backgroundColor: string; - regionColor: string; - borderColor: string; - hoverColor: string; - selectedColor: string; - markerFill: string; - markerStroke: string; - scaleStart: string; - scaleEnd: string; - textColor: string; -} - -export interface VectorMapOptions { - selector: string; - map: string; - backgroundColor?: string; - regionStyle?: { - initial?: Record; - hover?: Record; - selected?: Record; - }; - markerStyle?: { - initial?: Record; - hover?: Record; - }; - markers?: VectorMapMarker[]; - series?: { - regions?: Array<{ - attribute: string; - scale: [string, string]; - normalizeFunction?: string; - values: Record; - }>; - }; - zoomOnScroll?: boolean; - zoomButtons?: boolean; - onMarkerTooltipShow?: (event: Event, tooltip: any, index: number) => void; - onRegionTooltipShow?: (event: Event, tooltip: any, code: string) => void; - onLoaded?: (map: any) => void; -} - -export interface VectorMapInstance { - destroy(): void; - updateSeries(type: string, config: any): void; - markers?: VectorMapMarker[]; - mapData?: any; - series?: any; -} - -declare global { - interface HTMLElement { - mapInstance?: VectorMapInstance; - } -} - -// Enhanced Vector Map implementation -export class VectorMapComponent implements ComponentInterface { - public name: string = 'VectorMapComponent'; - public element: HTMLElement; - public options: VectorMapOptions; - public isInitialized: boolean = false; - - private mapInstance: VectorMapInstance | null = null; - private container: HTMLElement | null = null; - private resizeObserver: ResizeObserver | null = null; - private themeChangeHandler: (() => void) | null = null; - private resizeHandler: (() => void) | null = null; - private themeManager: typeof ThemeManager; - - constructor(element: HTMLElement, options: Partial = {}) { - this.element = element; - this.options = { - selector: '#vmap', - map: 'world', - backgroundColor: 'transparent', - zoomOnScroll: false, - zoomButtons: false, - markers: [ - { - name: 'INDIA : 350', - coords: [21.00, 78.00], - }, - { - name: 'Australia : 250', - coords: [-33.00, 151.00], - }, - { - name: 'USA : 250', - coords: [36.77, -119.41], - }, - { - name: 'UK : 250', - coords: [55.37, -3.41], - }, - { - name: 'UAE : 250', - coords: [25.20, 55.27], - }, - ], - ...options, - }; - - this.themeManager = ThemeManager; - this.init(); - } - - public init(): void { - this.setupContainer(); - this.setupEventHandlers(); - this.createMap(); - this.isInitialized = true; - } - - public destroy(): void { - this.cleanup(); - this.isInitialized = false; - } - - private setupContainer(): void { - // Remove existing map - const existingMap = document.getElementById('vmap'); - if (existingMap) { - existingMap.remove(); - } - - // Create new map container - this.container = document.createElement('div'); - this.container.id = 'vmap'; - this.container.style.height = '490px'; - this.container.style.position = 'relative'; - this.container.style.overflow = 'hidden'; - this.container.style.borderRadius = '8px'; - this.container.style.border = '1px solid var(--c-border, #d3d9e3)'; - this.container.style.backgroundColor = 'var(--c-bkg-card, #f9fafb)'; - - this.element.appendChild(this.container); - } - - private setupEventHandlers(): void { - // Theme change handler - this.themeChangeHandler = debounce(this.updateMapTheme.bind(this), 150); - window.addEventListener('adminator:themeChanged', this.themeChangeHandler); - - // Resize handler - this.resizeHandler = debounce(this.handleResize.bind(this), 300); - window.addEventListener('resize', this.resizeHandler); - - // Setup ResizeObserver if available - if ('ResizeObserver' in window) { - this.resizeObserver = new ResizeObserver( - debounce(() => { - if (this.mapInstance) { - this.handleResize(); - } - }, 300) - ); - this.resizeObserver.observe(this.element); - } - } - - private createMap(): void { - if (!this.container) return; - - // Destroy existing map instance - this.destroyMapInstance(); - - const colors = this.getThemeColors(); - const mapConfig = this.buildMapConfig(colors); - - try { - this.mapInstance = jsVectorMap(mapConfig); - this.element.mapInstance = this.mapInstance; - } catch (error) { - console.error('VectorMap: Failed to initialize map', error); - this.showFallbackContent(colors); - } - } - - private getThemeColors(): VectorMapColors { - const isDark = this.themeManager.current() === 'dark'; - - return { - backgroundColor: isDark ? '#313644' : '#f9fafb', - regionColor: isDark ? '#565a5c' : '#e6eaf0', - borderColor: isDark ? '#72777a' : '#d3d9e3', - hoverColor: isDark ? '#7774e7' : '#0f9aee', - selectedColor: isDark ? '#37c936' : '#7774e7', - markerFill: isDark ? '#0f9aee' : '#7774e7', - markerStroke: isDark ? '#37c936' : '#0f9aee', - scaleStart: isDark ? '#b9c2d0' : '#e6eaf0', - scaleEnd: isDark ? '#0f9aee' : '#007bff', - textColor: isDark ? '#99abb4' : '#72777a', - }; - } - - private buildMapConfig(colors: VectorMapColors): VectorMapOptions { - return { - selector: '#vmap', - map: 'world', - backgroundColor: this.options.backgroundColor || 'transparent', - - // Region styling - regionStyle: { - initial: { - fill: colors.regionColor, - stroke: colors.borderColor, - 'stroke-width': 1, - 'stroke-opacity': 0.4, - }, - hover: { - fill: colors.hoverColor, - cursor: 'pointer', - }, - selected: { - fill: colors.selectedColor, - }, - ...this.options.regionStyle, - }, - - // Marker styling - markerStyle: { - initial: { - r: 7, - fill: colors.markerFill, - stroke: colors.markerStroke, - 'stroke-width': 2, - 'stroke-opacity': 0.4, - }, - hover: { - r: 10, - fill: colors.hoverColor, - 'stroke-opacity': 0.8, - cursor: 'pointer', - }, - ...this.options.markerStyle, - }, - - // Markers data - markers: this.options.markers || [], - - // Series configuration - series: this.options.series, - - // Interaction options - zoomOnScroll: this.options.zoomOnScroll || false, - zoomButtons: this.options.zoomButtons || false, - - // Event handlers - onMarkerTooltipShow: this.handleMarkerTooltip.bind(this), - onRegionTooltipShow: this.handleRegionTooltip.bind(this), - onLoaded: this.handleMapLoaded.bind(this), - }; - } - - private handleMarkerTooltip(event: Event, tooltip: any, index: number): void { - try { - const marker = this.mapInstance?.markers?.[index]; - const markerName = marker?.name || `Marker ${index + 1}`; - tooltip.text(markerName); - } catch (error) { - console.warn('VectorMap: Error in marker tooltip', error); - } - - // Call custom handler if provided - if (this.options.onMarkerTooltipShow) { - this.options.onMarkerTooltipShow(event, tooltip, index); - } - } - - private handleRegionTooltip(event: Event, tooltip: any, code: string): void { - try { - const mapData = this.mapInstance?.mapData; - const regionName = mapData?.paths?.[code]?.name || code; - const series = this.mapInstance?.series?.regions?.[0]; - const value = series?.values?.[code]; - - const text = value ? `${regionName}: ${value}` : regionName; - tooltip.text(text); - } catch (error) { - console.warn('VectorMap: Error in region tooltip', error); - tooltip.text(code); - } - - // Call custom handler if provided - if (this.options.onRegionTooltipShow) { - this.options.onRegionTooltipShow(event, tooltip, code); - } - } - - private handleMapLoaded(map: any): void { - console.log('VectorMap: Map loaded successfully'); - - // Call custom handler if provided - if (this.options.onLoaded) { - this.options.onLoaded(map); - } - } - - private showFallbackContent(colors: VectorMapColors): void { - if (!this.container) return; - - this.container.innerHTML = ` -
-
-
🗺️
-
World Map
-
Interactive map will load here
-
-
- `; - } - - private updateMapTheme(): void { - if (!this.mapInstance || !this.container) { - this.createMap(); - return; - } - - const colors = this.getThemeColors(); - - try { - // Update container background - this.container.style.backgroundColor = colors.backgroundColor; - this.container.style.borderColor = colors.borderColor; - - // Update series if available - if (this.mapInstance.series?.regions?.[0]) { - this.mapInstance.updateSeries('regions', { - attribute: 'fill', - scale: [colors.scaleStart, colors.scaleEnd], - values: this.mapInstance.series.regions[0].values || {}, - }); - } - } catch (error) { - console.warn('VectorMap: Theme update failed, reinitializing', error); - this.createMap(); - } - } - - private handleResize(): void { - if (this.mapInstance && this.container) { - // Force a re-render by recreating the map - this.createMap(); - } - } - - private destroyMapInstance(): void { - if (this.mapInstance) { - try { - this.mapInstance.destroy(); - } catch (error) { - console.warn('VectorMap: Error destroying map instance', error); - } - this.mapInstance = null; - } - } - - private cleanup(): void { - this.destroyMapInstance(); - - // Remove event listeners - if (this.themeChangeHandler) { - window.removeEventListener('adminator:themeChanged', this.themeChangeHandler); - this.themeChangeHandler = null; - } - - if (this.resizeHandler) { - window.removeEventListener('resize', this.resizeHandler); - this.resizeHandler = null; - } - - // Disconnect ResizeObserver - if (this.resizeObserver) { - this.resizeObserver.disconnect(); - this.resizeObserver = null; - } - - // Clear container - if (this.container && this.container.parentNode) { - this.container.parentNode.removeChild(this.container); - this.container = null; - } - } - - // Public API methods - public updateMarkers(markers: VectorMapMarker[]): void { - this.options.markers = markers; - this.createMap(); - } - - public updateSeries(type: string, config: any): void { - if (this.mapInstance) { - try { - this.mapInstance.updateSeries(type, config); - } catch (error) { - console.warn('VectorMap: Error updating series', error); - } - } - } - - public getMapInstance(): VectorMapInstance | null { - return this.mapInstance; - } - - public refresh(): void { - this.createMap(); - } - - public updateOptions(newOptions: Partial): void { - this.options = { ...this.options, ...newOptions }; - this.createMap(); - } -} - -// Vector Map Manager -export class VectorMapManager { - private instances: Map = new Map(); - - public initialize(selector: string = '#world-map-marker', options: Partial = {}): VectorMapComponent | null { - const element = document.querySelector(selector); - if (!element) { - // Silently return null if element doesn't exist (normal for pages without maps) - return null; - } - - // Clean up existing instance - const existingInstance = this.instances.get(selector); - if (existingInstance) { - existingInstance.destroy(); - } - - // Create new instance - const vectorMap = new VectorMapComponent(element, options); - this.instances.set(selector, vectorMap); - - return vectorMap; - } - - public getInstance(selector: string): VectorMapComponent | undefined { - return this.instances.get(selector); - } - - public destroyInstance(selector: string): void { - const instance = this.instances.get(selector); - if (instance) { - instance.destroy(); - this.instances.delete(selector); - } - } - - public destroyAll(): void { - this.instances.forEach((instance) => { - instance.destroy(); - }); - this.instances.clear(); - } -} - -// Create singleton manager -const vectorMapManager = new VectorMapManager(); - -// Main initialization function -const vectorMapInit = (): void => { - // Only initialize if the map container exists - if (document.querySelector('#world-map-marker')) { - vectorMapManager.initialize('#world-map-marker', { - markers: [ - { - name: 'INDIA : 350', - coords: [21.00, 78.00], - }, - { - name: 'Australia : 250', - coords: [-33.00, 151.00], - }, - { - name: 'USA : 250', - coords: [36.77, -119.41], - }, - { - name: 'UK : 250', - coords: [55.37, -3.41], - }, - { - name: 'UAE : 250', - coords: [25.20, 55.27], - }, - ], - }); - } -}; - -// Initialize map -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', vectorMapInit); -} else { - vectorMapInit(); -} - -// Cleanup on page unload -window.addEventListener('beforeunload', () => { - vectorMapManager.destroyAll(); -}); - -// Export default for compatibility -export default { - init: vectorMapInit, - manager: vectorMapManager, - VectorMapComponent, - VectorMapManager, -}; \ No newline at end of file diff --git a/src/assets/scripts/vectorMaps/jquery-jvectormap-world-mill.js b/src/assets/scripts/vectorMaps/jquery-jvectormap-world-mill.js new file mode 100755 index 0000000..cedfa55 --- /dev/null +++ b/src/assets/scripts/vectorMaps/jquery-jvectormap-world-mill.js @@ -0,0 +1 @@ +jQuery.fn.vectorMap('addMap', 'world_mill',{"insets": [{"width": 900, "top": 0, "height": 440.7063107441331, "bbox": [{"y": -12671671.123330014, "x": -20004297.151525836}, {"y": 6930392.025135122, "x": 20026572.394749384}], "left": 0}], "paths": {"BD": {"path": "M651.84,230.21l-0.6,-2.0l-1.36,-1.71l-2.31,-0.11l-0.41,0.48l0.2,0.94l-0.53,0.99l-0.72,-0.36l-0.68,0.35l-1.2,-0.36l-0.37,-2.0l-0.81,-1.86l0.39,-1.46l-0.22,-0.47l-1.14,-0.53l0.29,-0.5l1.48,-0.94l0.03,-0.65l-1.55,-1.22l0.55,-1.14l1.61,0.94l1.04,0.15l0.18,1.54l0.34,0.35l5.64,0.63l-0.84,1.64l-1.22,0.34l-0.77,1.51l0.07,0.47l1.37,1.37l0.67,-0.19l0.42,-1.39l1.21,3.84l-0.03,1.21l-0.33,-0.15l-0.4,0.28Z", "name": "Bangladesh"}, "BE": {"path": "M429.29,144.05l1.91,0.24l2.1,-0.63l2.63,1.99l-0.21,1.66l-0.69,0.4l-0.18,1.2l-1.66,-1.13l-1.39,0.15l-2.73,-2.7l-1.17,-0.18l-0.16,-0.52l1.54,-0.5Z", "name": "Belgium"}, "BF": {"path": "M421.42,247.64l-0.11,0.95l0.34,1.16l1.4,1.71l0.07,1.1l0.32,0.37l2.55,0.51l-0.04,1.28l-0.38,0.53l-1.07,0.21l-0.72,1.18l-0.63,0.21l-3.22,-0.25l-0.94,0.39l-5.4,-0.05l-0.39,0.38l0.16,2.73l-1.23,-0.43l-1.17,0.1l-0.89,0.57l-2.27,-1.72l-0.13,-1.11l0.61,-0.96l0.02,-0.93l1.87,-1.98l0.44,-1.81l0.43,-0.39l1.28,0.26l1.05,-0.52l0.47,-0.73l1.84,-1.09l0.55,-0.83l2.2,-1.0l1.15,-0.3l0.72,0.45l1.13,-0.01Z", "name": "Burkina Faso"}, "BG": {"path": "M491.65,168.18l-0.86,0.88l-0.91,2.17l0.48,1.34l-1.6,-0.24l-2.55,0.95l-0.28,1.51l-1.8,0.22l-2.0,-1.0l-1.92,0.79l-1.42,-0.07l-0.15,-1.63l-1.05,-0.97l0.0,-0.8l1.2,-1.57l0.01,-0.56l-1.14,-1.23l-0.05,-0.94l0.88,0.97l0.88,-0.2l1.91,0.47l3.68,0.16l1.42,-0.81l2.72,-0.66l2.55,1.24Z", "name": "Bulgaria"}, "BA": {"path": "M463.49,163.65l2.1,0.5l1.72,-0.03l1.52,0.68l-0.36,0.78l0.08,0.45l1.04,1.02l-0.25,0.98l-1.81,1.15l-0.38,1.38l-1.67,-0.87l-0.89,-1.2l-2.11,-1.83l-1.63,-2.22l0.23,-0.57l0.48,0.38l0.55,-0.06l0.43,-0.51l0.94,-0.06Z", "name": "Bosnia and Herz."}, "BN": {"path": "M707.48,273.58l0.68,-0.65l1.41,-0.91l-0.15,1.63l-0.81,-0.05l-0.61,0.58l-0.53,-0.6Z", "name": "Brunei"}, "BO": {"path": "M263.83,340.69l-3.09,-0.23l-0.38,0.23l-0.7,1.52l-1.31,-1.53l-3.28,-0.64l-2.37,2.4l-1.31,0.26l-0.88,-3.26l-1.3,-2.86l0.74,-2.37l-0.13,-0.43l-1.2,-1.01l-0.37,-1.89l-1.08,-1.55l1.45,-2.56l-0.96,-2.33l0.47,-1.06l-0.34,-0.73l0.91,-1.32l0.16,-3.84l0.5,-1.18l-1.81,-3.41l2.46,0.07l0.8,-0.85l3.4,-1.91l2.66,-0.35l-0.19,1.38l0.3,1.07l-0.05,1.97l2.72,2.27l2.88,0.49l0.89,0.86l1.79,0.58l0.98,0.7l1.71,0.05l1.17,0.61l0.6,2.7l-0.7,0.54l0.96,2.99l0.37,0.28l4.3,0.1l-0.25,1.2l0.27,1.02l1.43,0.9l0.5,1.35l-0.41,1.86l-0.65,1.08l0.12,1.35l-2.69,-1.65l-2.4,-0.03l-4.36,0.76l-1.49,2.5l-0.11,1.52l-0.75,2.37Z", "name": "Bolivia"}, "JP": {"path": "M781.12,166.87l1.81,0.68l1.62,-0.97l0.39,2.42l-3.35,0.75l-2.23,2.88l-3.63,-1.9l-0.56,0.2l-1.26,3.05l-2.16,0.03l-0.29,-2.51l1.08,-2.03l2.45,-0.16l0.37,-0.33l1.25,-5.94l2.47,2.71l2.03,1.12ZM773.56,187.34l-0.91,2.22l0.37,1.52l-1.14,1.75l-3.02,1.26l-4.58,0.27l-3.34,3.01l-1.25,-0.8l-0.09,-1.9l-0.46,-0.38l-4.35,0.62l-3.0,1.32l-2.85,0.05l-0.37,0.27l0.13,0.44l2.32,1.89l-1.54,4.34l-1.26,0.9l-0.79,-0.7l0.56,-2.27l-0.21,-0.45l-1.47,-0.75l-0.74,-1.4l2.12,-0.84l1.26,-1.7l2.45,-1.42l1.83,-1.91l4.78,-0.81l2.6,0.57l0.44,-0.21l2.39,-4.66l1.29,1.06l0.5,0.01l5.1,-4.02l1.69,-3.73l-0.38,-3.4l0.9,-1.61l2.14,-0.44l1.23,3.72l-0.07,2.18l-2.23,2.84l-0.04,3.16ZM757.78,196.26l0.19,0.56l-1.01,1.21l-1.16,-0.68l-1.28,0.65l-0.69,1.45l-1.02,-0.5l0.01,-0.93l1.14,-1.38l1.57,0.14l0.85,-0.98l1.4,0.46Z", "name": "Japan"}, "BI": {"path": "M495.45,295.49l-1.08,-2.99l1.14,-0.11l0.64,-1.19l0.76,0.09l0.65,1.83l-2.1,2.36Z", "name": "Burundi"}, "BJ": {"path": "M429.57,255.75l-0.05,0.8l0.5,1.34l-0.42,0.86l0.17,0.79l-1.81,2.12l-0.57,1.76l-0.08,5.42l-1.41,0.2l-0.48,-1.36l0.11,-5.71l-0.52,-0.7l-0.2,-1.35l-1.48,-1.48l0.21,-0.9l0.89,-0.43l0.42,-0.92l1.27,-0.36l1.22,-1.34l0.61,-0.0l1.62,1.24Z", "name": "Benin"}, "BT": {"path": "M650.32,213.86l0.84,0.71l-0.12,1.1l-3.76,-0.11l-1.57,0.4l-1.93,-0.87l1.48,-1.96l1.13,-0.57l1.63,0.57l1.33,0.08l0.99,0.65Z", "name": "Bhutan"}, "JM": {"path": "M228.38,239.28l-0.8,0.4l-2.26,-1.06l0.84,-0.23l2.14,0.3l1.17,0.56l-1.08,0.03Z", "name": "Jamaica"}, "BW": {"path": "M483.92,330.07l2.27,4.01l2.83,2.86l0.96,0.31l0.78,2.43l2.13,0.61l1.02,0.76l-3.0,1.64l-2.32,2.02l-1.54,2.69l-1.52,0.45l-0.64,1.94l-1.34,0.52l-1.85,-0.12l-1.21,-0.74l-1.35,-0.3l-1.22,0.62l-0.75,1.37l-2.31,1.9l-1.4,0.21l-0.35,-0.59l0.16,-1.75l-1.48,-2.54l-0.62,-0.43l-0.0,-7.1l2.08,-0.08l0.39,-0.4l0.07,-8.9l5.19,-0.93l0.8,0.89l0.51,0.07l1.5,-0.95l2.21,-0.49Z", "name": "Botswana"}, "BR": {"path": "M259.98,275.05l3.24,0.7l0.65,-0.53l4.55,-1.32l1.08,-1.06l-0.02,-0.63l0.55,-0.05l0.28,0.28l-0.26,0.87l0.22,0.48l0.73,0.32l0.4,0.81l-0.62,0.86l-0.4,2.13l0.82,2.56l1.69,1.43l1.43,0.2l3.17,-1.68l3.18,0.3l0.65,-0.75l-0.27,-0.92l1.9,-0.09l2.39,0.99l1.06,-0.61l0.84,0.78l1.2,-0.18l1.18,-1.06l0.84,-1.94l1.36,-2.11l0.37,-0.05l1.89,5.45l1.33,0.59l0.05,1.28l-1.77,1.94l0.02,0.56l1.02,0.87l4.07,0.36l0.08,2.16l0.66,0.29l1.74,-1.5l6.97,2.32l1.02,1.22l-0.35,1.18l0.49,0.5l2.81,-0.74l4.77,1.3l3.75,-0.08l3.57,2.0l3.29,2.86l1.93,0.72l2.12,0.12l0.71,0.62l1.21,4.51l-0.95,3.98l-4.72,5.06l-1.64,2.92l-1.72,2.05l-0.8,0.3l-0.72,2.03l0.18,4.75l-0.94,5.53l-0.81,1.13l-0.43,3.36l-2.55,3.5l-0.4,2.51l-1.86,1.04l-0.67,1.53l-2.54,0.01l-3.94,1.01l-1.83,1.2l-2.87,0.82l-3.03,2.19l-2.2,2.83l-0.36,2.0l0.4,1.58l-0.44,2.6l-0.51,1.2l-1.77,1.54l-2.75,4.78l-3.83,3.42l-1.24,2.74l-1.18,1.15l-0.36,-0.83l0.95,-1.14l0.01,-0.5l-1.52,-1.97l-4.56,-3.32l-1.03,-0.0l-2.38,-2.02l-0.81,-0.0l5.34,-5.45l3.77,-2.58l0.22,-2.46l-1.35,-1.81l-0.91,0.07l0.58,-2.33l0.01,-1.54l-1.11,-0.83l-1.75,0.3l-0.44,-3.11l-0.52,-0.95l-1.88,-0.88l-1.24,0.47l-2.17,-0.41l0.15,-3.21l-0.62,-1.34l0.66,-0.73l-0.22,-1.34l0.66,-1.13l0.44,-2.04l-0.61,-1.83l-1.4,-0.86l-0.2,-0.75l0.34,-1.39l-0.38,-0.5l-4.52,-0.1l-0.72,-2.22l0.59,-0.42l-0.03,-1.1l-0.5,-0.87l-0.32,-1.7l-1.45,-0.76l-1.63,-0.02l-1.05,-0.72l-1.6,-0.48l-1.13,-0.99l-2.69,-0.4l-2.47,-2.06l0.13,-4.35l-0.45,-0.45l-3.46,0.5l-3.44,1.94l-0.6,0.74l-2.9,-0.17l-1.47,0.42l-0.72,-0.18l0.15,-3.52l-0.63,-0.34l-1.94,1.41l-1.87,-0.06l-0.83,-1.18l-1.37,-0.26l0.21,-1.01l-1.35,-1.49l-0.88,-1.91l0.56,-0.6l-0.0,-0.81l1.29,-0.62l0.22,-0.43l-0.22,-1.19l0.61,-0.91l0.15,-0.99l2.65,-1.58l1.99,-0.47l0.42,-0.36l2.06,0.11l0.42,-0.33l1.19,-8.0l-0.41,-1.56l-1.1,-1.0l0.01,-1.33l1.91,-0.42l0.08,-0.96l-0.33,-0.43l-1.14,-0.2l-0.02,-0.83l4.47,0.05l0.82,-0.67l0.82,1.81l0.8,0.07l1.15,1.1l2.26,-0.05l0.71,-0.83l2.78,-0.96l0.48,-1.13l1.6,-0.64l0.24,-0.47l-0.48,-0.82l-1.83,-0.19l-0.36,-3.22Z", "name": "Brazil"}, "BS": {"path": "M226.4,223.87l-0.48,-1.15l-0.84,-0.75l0.36,-1.11l0.95,1.95l0.01,1.06ZM225.56,216.43l-1.87,0.29l-0.04,-0.22l0.74,-0.14l1.17,0.06Z", "name": "Bahamas"}, "BY": {"path": "M493.84,128.32l0.29,0.7l0.49,0.23l1.19,-0.38l2.09,0.72l0.19,1.26l-0.45,1.24l1.57,2.26l0.89,0.59l0.17,0.81l1.58,0.56l0.4,0.5l-0.53,0.41l-1.87,-0.11l-0.73,0.38l-0.13,0.52l1.04,2.74l-1.91,0.26l-0.89,0.99l-0.11,1.18l-2.73,-0.04l-0.53,-0.62l-0.52,-0.08l-0.75,0.46l-0.91,-0.42l-1.92,-0.07l-2.75,-0.79l-2.6,-0.28l-2.0,0.07l-1.5,0.92l-0.67,0.07l-0.08,-1.22l-0.59,-1.19l1.36,-0.88l0.01,-1.35l-0.7,-1.41l-0.07,-1.0l2.16,-0.02l2.72,-1.3l0.75,-2.04l1.91,-1.04l0.2,-0.41l-0.19,-1.25l3.8,-1.78l2.3,0.77Z", "name": "Belarus"}, "BZ": {"path": "M198.03,244.38l0.1,-4.49l0.69,-0.06l0.74,-1.3l0.34,0.28l-0.4,1.3l0.17,0.58l-0.34,2.25l-1.3,1.42Z", "name": "Belize"}, "RU": {"path": "M491.55,115.25l2.55,-1.85l-0.01,-0.65l-2.2,-1.5l7.32,-6.76l1.03,-2.11l-0.13,-0.49l-3.46,-2.52l0.86,-2.7l-2.11,-2.81l1.56,-3.67l-2.77,-4.52l2.15,-2.99l-0.08,-0.55l-3.65,-2.73l0.3,-2.54l1.81,-0.37l4.26,-1.77l2.42,-1.45l4.06,2.61l6.79,1.04l9.34,4.85l1.78,1.88l0.14,2.46l-2.55,2.02l-3.9,1.06l-11.07,-3.14l-2.06,0.53l-0.13,0.7l3.94,2.94l0.31,5.86l0.26,0.36l5.14,2.24l0.58,-0.29l0.32,-1.94l-1.35,-1.78l1.13,-1.09l6.13,2.42l2.11,-0.98l0.18,-0.56l-1.51,-2.67l5.41,-3.76l2.07,0.22l2.26,1.41l0.57,-0.16l1.46,-2.87l-0.05,-0.44l-1.92,-2.32l1.12,-2.32l-1.32,-2.27l5.87,1.16l1.04,1.75l-2.59,0.43l-0.33,0.4l0.02,2.36l2.46,1.83l3.87,-0.91l0.86,-2.8l13.69,-5.65l0.99,0.11l-1.92,2.06l0.23,0.67l3.11,0.45l2.0,-1.48l4.56,-0.12l3.64,-1.73l2.65,2.44l0.56,-0.01l2.85,-2.88l-0.01,-0.57l-2.35,-2.29l0.9,-1.01l7.14,1.3l3.41,1.36l9.05,4.97l0.51,-0.11l1.67,-2.27l-0.05,-0.53l-2.43,-2.21l-0.06,-0.78l-0.34,-0.36l-2.52,-0.36l0.64,-1.93l-1.32,-3.46l-0.06,-1.21l4.48,-4.06l1.69,-4.29l1.6,-0.81l6.23,1.18l0.44,2.21l-2.29,3.64l0.06,0.5l1.47,1.39l0.76,3.0l-0.56,6.03l2.69,2.82l-0.96,2.57l-4.86,5.95l0.23,0.64l2.86,0.61l0.42,-0.17l0.93,-1.4l2.64,-1.03l0.87,-2.24l2.09,-1.96l0.07,-0.5l-1.36,-2.28l1.09,-2.69l-0.32,-0.55l-2.47,-0.33l-0.5,-2.06l1.94,-4.38l-0.06,-0.42l-2.96,-3.4l4.12,-2.88l0.16,-0.4l-0.51,-2.93l0.54,-0.05l1.13,2.25l-0.96,4.35l0.27,0.47l2.68,0.84l0.5,-0.51l-1.02,-2.99l3.79,-1.66l5.01,-0.24l4.53,2.61l0.48,-0.06l0.07,-0.48l-2.18,-3.82l-0.23,-4.67l3.98,-0.9l5.97,0.21l5.49,-0.64l0.27,-0.65l-1.83,-2.31l2.56,-2.9l2.87,-0.17l4.8,-2.47l6.54,-0.67l1.03,-1.42l6.25,-0.45l2.32,1.11l5.53,-2.7l4.5,0.08l0.39,-0.28l0.66,-2.15l2.26,-2.12l5.69,-2.11l3.21,1.29l-2.46,0.94l-0.25,0.42l0.34,0.35l5.41,0.77l0.61,2.33l0.58,0.25l2.2,-1.22l7.13,0.07l5.51,2.47l1.79,1.72l-0.53,2.24l-9.16,4.15l-1.97,1.52l0.16,0.71l6.77,1.91l2.16,-0.78l1.13,2.74l0.67,0.11l1.01,-1.15l3.81,-0.73l7.7,0.77l0.54,1.99l0.36,0.29l10.47,0.71l0.43,-0.38l0.13,-3.23l4.87,0.78l3.95,-0.02l3.83,2.4l1.03,2.71l-1.35,1.79l0.02,0.5l3.15,3.64l4.07,1.96l0.53,-0.18l2.23,-4.47l3.95,1.93l4.16,-1.21l4.73,1.39l2.05,-1.26l3.94,0.62l0.43,-0.55l-1.68,-4.02l2.89,-1.8l22.31,3.03l2.16,2.75l6.55,3.51l10.29,-0.81l4.82,0.73l1.85,1.66l-0.29,3.08l0.25,0.41l3.08,1.26l3.56,-0.88l4.35,-0.11l4.8,0.87l4.57,-0.47l4.23,3.79l0.43,0.07l3.1,-1.4l0.16,-0.6l-1.88,-2.62l0.85,-1.52l7.71,1.21l5.22,-0.26l7.09,2.09l9.59,5.22l6.35,4.11l-0.2,2.38l1.88,1.41l0.6,-0.42l-0.48,-2.53l6.15,0.57l4.4,3.51l-1.97,1.43l-4.0,0.41l-0.36,0.39l-0.06,3.79l-0.74,0.62l-2.07,-0.11l-1.91,-1.39l-3.14,-1.11l-0.78,-1.85l-2.72,-0.68l-2.63,0.49l-1.04,-1.1l0.46,-1.31l-0.5,-0.51l-3.0,0.98l-0.22,0.58l0.99,1.7l-1.21,1.48l-3.04,1.68l-3.12,-0.28l-0.4,0.23l0.09,0.46l2.2,2.09l1.46,3.2l1.15,1.1l0.24,1.33l-0.42,0.67l-4.63,-0.77l-6.96,2.9l-2.19,0.44l-7.6,5.06l-0.84,1.45l-3.61,-2.37l-6.24,2.82l-0.94,-1.15l-0.53,-0.08l-2.28,1.52l-3.2,-0.49l-0.44,0.27l-0.78,2.37l-3.05,3.78l0.09,1.47l0.29,0.36l2.54,0.72l-0.29,4.53l-1.97,0.11l-0.35,0.26l-1.07,2.94l0.8,1.45l-3.91,1.58l-1.05,3.95l-3.48,0.77l-0.3,0.3l-0.72,3.29l-3.09,2.65l-0.7,-1.74l-2.44,-12.44l1.16,-4.71l2.04,-2.06l0.22,-1.64l3.8,-0.86l4.46,-4.61l4.28,-3.81l4.48,-3.01l2.17,-5.63l-0.42,-0.54l-3.04,0.33l-1.77,3.31l-5.86,3.86l-1.86,-4.25l-0.45,-0.23l-6.46,1.3l-6.47,6.44l-0.01,0.55l1.58,1.74l-8.24,1.17l0.15,-2.2l-0.34,-0.42l-3.89,-0.56l-3.25,1.81l-7.62,-0.62l-8.45,1.19l-17.71,15.41l0.22,0.7l3.74,0.41l1.36,2.17l2.43,0.76l1.88,-1.68l2.4,0.2l3.4,3.54l0.08,2.6l-1.95,3.42l-0.21,3.9l-1.1,5.06l-3.71,4.54l-0.87,2.21l-8.29,8.89l-3.19,1.7l-1.32,0.03l-1.45,-1.36l-0.49,-0.04l-2.27,1.5l0.41,-3.65l-0.59,-2.47l1.75,-0.89l2.91,0.53l0.42,-0.2l1.68,-3.03l0.87,-3.46l0.97,-1.18l1.32,-2.88l-0.45,-0.56l-4.14,0.95l-2.19,1.25l-3.41,-0.0l-1.06,-2.93l-2.97,-2.3l-4.28,-1.06l-1.75,-5.07l-2.66,-5.01l-2.29,-1.29l-3.75,-1.01l-3.44,0.08l-3.18,0.62l-2.24,1.77l0.05,0.66l1.18,0.69l0.02,1.43l-1.33,1.05l-2.26,3.51l-0.04,1.43l-3.16,1.84l-2.82,-1.16l-3.01,0.23l-1.35,-1.07l-1.5,-0.35l-3.9,2.31l-3.22,0.52l-2.27,0.79l-3.05,-0.51l-2.21,0.03l-1.48,-1.6l-2.6,-1.63l-2.63,-0.43l-5.46,1.01l-3.23,-1.25l-0.72,-2.57l-5.2,-1.24l-2.75,-1.36l-0.5,0.12l-2.59,3.45l0.84,2.1l-2.06,1.93l-3.41,-0.77l-2.42,-0.12l-1.83,-1.54l-2.53,-0.05l-2.42,-0.98l-3.86,1.57l-4.72,2.78l-3.3,0.75l-1.55,-1.92l-3.0,0.41l-1.11,-1.33l-1.62,-0.59l-1.31,-1.94l-1.38,-0.6l-3.7,0.79l-3.31,-1.83l-0.51,0.11l-0.99,1.29l-5.29,-8.05l-2.96,-2.48l0.65,-0.77l0.01,-0.51l-0.5,-0.11l-6.2,3.21l-1.84,0.15l0.15,-1.39l-0.26,-0.42l-3.22,-1.17l-2.46,0.7l-0.69,-3.16l-0.32,-0.31l-4.5,-0.75l-2.47,1.47l-6.19,1.27l-1.29,0.86l-9.51,1.3l-1.15,1.17l-0.03,0.53l1.47,1.9l-1.89,0.69l-0.22,0.56l0.31,0.6l-2.11,1.44l0.03,0.68l3.75,2.12l-0.39,0.98l-3.23,-0.13l-0.86,0.86l-3.09,-1.59l-3.97,0.07l-2.66,1.35l-8.32,-3.56l-4.07,0.06l-5.39,3.68l-0.39,2.0l-2.03,-1.5l-0.59,0.13l-2.0,3.59l0.57,0.93l-1.28,2.16l0.06,0.48l2.13,2.17l1.95,0.04l1.37,1.82l-0.23,1.46l0.25,0.43l0.83,0.33l-0.8,1.31l-2.49,0.62l-2.49,3.2l0.0,0.49l2.17,2.78l-0.15,2.18l2.5,3.24l-1.58,1.59l-0.7,-0.13l-1.63,-1.72l-2.29,-0.84l-0.94,-1.31l-2.34,-0.63l-1.48,0.4l-0.43,-0.47l-3.51,-1.48l-5.76,-1.01l-0.45,0.19l-2.89,-2.34l-2.9,-1.2l-1.53,-1.29l1.29,-0.43l2.08,-2.61l-0.05,-0.55l-0.89,-0.79l3.05,-1.06l0.27,-0.42l-0.07,-0.69l-0.49,-0.35l-1.73,0.39l0.04,-0.68l1.04,-0.72l2.66,-0.48l0.4,-1.32l-0.5,-1.6l0.92,-1.54l0.03,-1.17l-0.29,-0.37l-3.69,-1.06l-1.41,0.02l-1.42,-1.41l-2.19,0.38l-2.77,-1.01l-0.03,-0.59l-0.89,-1.43l-2.0,-0.32l-0.11,-0.54l0.49,-0.53l0.01,-0.53l-1.6,-1.9l-3.58,0.02l-0.88,0.73l-0.46,-0.07l-1.0,-2.79l2.22,-0.02l0.97,-0.74l0.07,-0.57l-0.9,-1.04l-1.35,-0.48l-0.11,-0.7l-0.95,-0.58l-1.38,-1.99l0.46,-0.98l-0.51,-1.96l-2.45,-0.84l-1.21,0.3l-0.46,-0.76l-2.46,-0.83l-0.72,-1.87l-0.21,-1.69l-0.99,-0.85l0.85,-1.17l-0.7,-3.21l1.66,-1.97l-0.16,-0.79ZM749.2,170.72l-0.6,0.4l-0.13,0.16l-0.01,-0.51l0.74,-0.05ZM871.88,65.81l2.17,-0.13l3.19,1.16l-2.39,1.09l-5.63,0.48l-0.26,-0.84l2.92,-1.76ZM797.39,48.49l-2.0,1.36l-3.8,-0.42l-4.25,-1.8l0.35,-0.97l9.69,1.83ZM783.67,46.12l-1.63,3.09l-8.98,-0.13l-4.09,1.14l-4.54,-2.97l1.16,-3.01l3.05,-0.89l6.5,0.22l8.54,2.56ZM778.2,134.98l-0.56,-0.9l0.27,-0.12l0.29,1.01ZM778.34,135.48l0.94,3.53l-0.05,3.38l1.05,3.39l2.18,5.0l-2.89,-0.83l-0.49,0.26l-1.54,4.65l2.42,3.5l-0.04,1.13l-1.24,-1.24l-0.61,0.06l-1.09,1.61l-0.28,-1.61l0.27,-3.1l-0.28,-3.4l0.58,-2.47l0.11,-4.39l-1.46,-3.36l0.21,-4.32l2.15,-1.46l0.07,-0.34ZM771.95,56.61l1.76,-1.42l2.89,-0.42l3.28,1.71l0.14,0.6l-3.27,0.03l-4.81,-0.5ZM683.76,31.09l-13.01,1.93l4.03,-6.35l1.82,-0.56l1.73,0.34l5.99,2.98l-0.56,1.66ZM670.85,27.93l-5.08,0.64l-6.86,-1.57l-3.99,-2.05l-2.1,-4.16l-2.6,-0.87l5.72,-3.5l5.2,-1.28l4.69,2.85l5.59,5.4l-0.56,4.53ZM564.15,68.94l-0.64,0.17l-7.85,-0.57l-0.86,-2.04l-4.28,-1.17l-0.28,-1.94l2.27,-0.89l0.25,-0.39l-0.08,-2.38l4.81,-3.97l-0.15,-0.7l-1.47,-0.38l5.3,-3.81l0.15,-0.44l-0.58,-1.94l5.28,-2.51l8.21,-3.27l8.28,-0.96l4.35,-1.94l4.6,-0.64l1.36,1.61l-1.34,1.28l-16.43,4.94l-7.97,4.88l-7.74,9.63l0.66,4.14l4.16,3.27ZM548.81,18.48l-5.5,1.18l-0.58,1.02l-2.59,0.84l-2.13,-1.07l1.12,-1.42l-0.3,-0.65l-2.33,-0.07l1.68,-0.36l3.47,-0.06l0.42,1.29l0.66,0.16l1.38,-1.34l2.15,-0.88l2.94,1.01l-0.39,0.36ZM477.37,133.15l-4.08,0.05l-2.56,-0.32l0.33,-0.87l3.17,-1.03l3.24,0.96l-0.09,1.23Z", "name": "Russia"}, "RW": {"path": "M497.0,288.25l0.71,1.01l-0.11,1.09l-1.63,0.03l-1.04,1.39l-0.83,-0.11l0.51,-1.2l0.08,-1.34l0.42,-0.41l0.7,0.14l1.19,-0.61Z", "name": "Rwanda"}, "RS": {"path": "M469.4,163.99l0.42,-0.5l-0.01,-0.52l-1.15,-1.63l1.43,-0.62l1.33,0.12l1.17,1.06l0.46,1.13l1.34,0.64l0.35,1.35l1.46,0.9l0.76,-0.29l0.2,0.69l-0.48,0.78l0.22,1.12l1.05,1.22l-0.77,0.8l-0.37,1.52l-1.21,0.08l0.24,-0.64l-0.39,-0.54l-2.08,-1.64l-0.9,0.05l-0.48,0.94l-2.12,-1.37l0.53,-1.6l-1.11,-1.37l0.51,-1.1l-0.41,-0.57Z", "name": "Serbia"}, "TL": {"path": "M734.55,307.93l-0.1,-0.97l4.5,-0.86l-2.82,1.28l-1.59,0.55Z", "name": "Timor-Leste"}, "TM": {"path": "M553.03,173.76l-0.04,0.34l-0.09,-0.22l0.13,-0.12ZM555.87,172.66l0.45,-0.1l1.48,0.74l2.06,2.43l4.07,-0.18l0.38,-0.51l-0.32,-1.19l1.92,-0.94l1.91,-1.59l2.94,1.39l0.43,2.47l1.19,0.67l2.58,-0.13l0.62,0.4l1.32,3.12l4.54,3.44l2.67,1.45l3.06,1.14l-0.04,1.05l-1.33,-0.75l-0.59,0.19l-0.32,0.84l-2.2,0.81l-0.46,2.13l-1.21,0.74l-1.91,0.42l-0.73,1.33l-1.56,0.31l-2.22,-0.94l-0.2,-2.17l-0.38,-0.36l-1.73,-0.09l-2.76,-2.46l-2.14,-0.4l-2.84,-1.48l-1.78,-0.27l-1.24,0.53l-1.57,-0.08l-2.0,1.69l-1.7,0.43l-0.36,-1.58l0.36,-2.98l-0.22,-0.4l-1.65,-0.84l0.54,-1.69l-0.34,-0.52l-1.22,-0.13l0.36,-1.64l2.22,0.59l2.2,-0.95l0.12,-0.65l-1.77,-1.74l-0.66,-1.57Z", "name": "Turkmenistan"}, "TJ": {"path": "M597.75,178.82l-2.54,-0.44l-0.47,0.34l-0.24,1.7l0.43,0.45l2.64,-0.22l3.18,0.95l4.39,-0.41l0.56,2.37l0.52,0.29l0.67,-0.24l1.11,0.49l0.21,2.13l-3.76,-0.21l-1.8,1.32l-1.76,0.74l-0.61,-0.58l0.21,-2.23l-0.64,-0.49l-0.07,-0.93l-1.36,-0.66l-0.45,0.07l-1.08,1.01l-0.55,1.48l-1.31,-0.05l-0.95,1.16l-0.9,-0.35l-1.86,0.74l1.26,-2.83l-0.54,-2.17l-1.67,-0.82l0.33,-0.66l2.18,-0.04l1.19,-1.63l0.76,-1.79l2.43,-0.5l-0.26,1.0l0.73,1.05Z", "name": "Tajikistan"}, "RO": {"path": "M487.53,154.23l0.6,0.24l2.87,3.98l-0.17,2.69l0.45,1.42l1.32,0.81l1.35,-0.42l0.76,0.36l0.02,0.31l-0.83,0.45l-0.59,-0.22l-0.54,0.3l-0.62,3.3l-1.0,-0.22l-2.07,-1.13l-2.95,0.71l-1.25,0.76l-3.51,-0.15l-1.89,-0.47l-0.87,0.16l-0.82,-1.3l0.29,-0.26l-0.06,-0.64l-1.09,-0.34l-0.56,0.5l-1.05,-0.64l-0.39,-1.39l-1.36,-0.65l-0.35,-1.0l-0.83,-0.75l1.54,-0.54l2.66,-4.21l2.4,-1.24l2.96,0.34l1.48,0.73l0.79,-0.45l1.78,-0.3l0.75,-0.74l0.79,0.0Z", "name": "Romania"}, "GW": {"path": "M386.23,253.6l-0.29,0.84l0.15,0.6l-2.21,0.59l-0.86,0.96l-1.04,-0.83l-1.09,-0.23l-0.54,-1.06l-0.66,-0.49l2.41,-0.48l4.13,0.1Z", "name": "Guinea-Bissau"}, "GT": {"path": "M195.08,249.77l-2.48,-0.37l-1.03,-0.45l-1.14,-0.89l0.3,-0.99l-0.24,-0.68l0.96,-1.66l2.98,-0.01l0.4,-0.37l-0.19,-1.28l-1.67,-1.4l0.51,-0.4l0.0,-1.05l3.85,0.02l-0.21,4.53l0.4,0.43l1.46,0.38l-1.48,0.98l-0.35,0.7l0.12,0.57l-2.2,1.96Z", "name": "Guatemala"}, "GR": {"path": "M487.07,174.59l-0.59,1.43l-0.37,0.21l-2.84,-0.35l-3.03,0.77l-0.18,0.68l1.28,1.23l-0.61,0.23l-1.14,0.0l-1.2,-1.39l-0.63,0.03l-0.53,1.01l0.56,1.76l1.03,1.19l-0.56,0.38l-0.05,0.62l2.52,2.12l0.02,0.87l-1.78,-0.59l-0.48,0.56l0.5,1.0l-1.07,0.2l-0.3,0.53l0.75,2.01l-0.98,0.02l-1.84,-1.12l-1.37,-4.2l-2.21,-2.95l-0.11,-0.56l1.04,-1.28l0.2,-0.95l0.85,-0.66l0.03,-0.46l1.32,-0.21l1.01,-0.64l1.22,0.05l0.65,-0.56l2.26,-0.0l1.82,-0.75l1.85,1.0l2.28,-0.28l0.35,-0.39l0.01,-0.77l0.34,0.22ZM480.49,192.16l0.58,0.4l-0.68,-0.12l0.11,-0.28ZM482.52,192.82l2.51,0.06l0.24,0.32l-1.99,0.13l-0.77,-0.51Z", "name": "Greece"}, "GQ": {"path": "M448.79,279.62l0.02,2.22l-4.09,0.0l0.69,-2.27l3.38,0.05Z", "name": "Eq. Guinea"}, "GY": {"path": "M277.42,270.07l-0.32,1.83l-1.32,0.57l-0.23,0.46l-0.28,2.0l1.11,1.82l0.83,0.19l0.32,1.25l1.13,1.62l-1.21,-0.19l-1.08,0.71l-1.77,0.5l-0.44,0.46l-0.86,-0.09l-1.32,-1.01l-0.77,-2.27l0.36,-1.9l0.68,-1.23l-0.57,-1.17l-0.74,-0.43l0.12,-1.16l-0.9,-0.69l-1.1,0.09l-1.31,-1.48l0.53,-0.72l-0.04,-0.84l1.99,-0.86l0.05,-0.59l-0.71,-0.78l0.14,-0.57l1.66,-1.24l1.36,0.77l1.41,1.49l0.06,1.15l0.37,0.38l0.8,0.05l2.06,1.86Z", "name": "Guyana"}, "GE": {"path": "M521.71,168.93l5.29,0.89l4.07,2.01l1.41,-0.44l2.07,0.56l0.68,1.1l1.07,0.55l-0.12,0.59l0.98,1.29l-1.01,-0.13l-1.81,-0.83l-0.94,0.47l-3.23,0.43l-2.29,-1.39l-2.33,0.05l0.21,-0.97l-0.76,-2.26l-1.45,-1.12l-1.43,-0.39l-0.41,-0.42Z", "name": "Georgia"}, "GB": {"path": "M412.61,118.72l-2.19,3.22l-0.0,0.45l5.13,-0.3l-0.53,2.37l-2.2,3.12l0.29,0.63l2.37,0.21l2.33,4.3l1.76,0.69l2.2,5.12l2.94,0.77l-0.23,1.62l-1.15,0.88l-0.1,0.52l0.82,1.42l-1.86,1.43l-3.3,-0.02l-4.12,0.87l-1.04,-0.58l-0.47,0.06l-1.51,1.41l-2.12,-0.34l-1.86,1.18l-0.6,-0.29l3.19,-3.0l2.16,-0.69l0.28,-0.41l-0.34,-0.36l-3.73,-0.53l-0.4,-0.76l2.2,-0.87l0.17,-0.61l-1.26,-1.67l0.36,-1.7l3.38,0.28l0.43,-0.33l0.37,-1.99l-1.79,-2.49l-3.11,-0.72l-0.38,-0.59l0.79,-1.35l-0.04,-0.46l-0.82,-0.97l-0.61,0.01l-0.68,0.84l-0.1,-2.34l-1.23,-1.88l0.85,-3.47l1.77,-2.68l1.85,0.26l2.17,-0.22ZM406.26,132.86l-1.01,1.77l-1.57,-0.59l-1.16,0.01l0.37,-1.54l-0.39,-1.39l1.45,-0.1l2.3,1.84Z", "name": "United Kingdom"}, "GA": {"path": "M453.24,279.52l-0.08,0.98l0.7,1.29l2.36,0.24l-0.98,2.63l1.18,1.79l0.25,1.78l-0.29,1.52l-0.6,0.93l-1.84,-0.09l-1.23,-1.11l-0.66,0.23l-0.15,0.84l-1.42,0.26l-1.02,0.7l-0.11,0.52l0.77,1.35l-1.34,0.97l-3.94,-4.3l-1.44,-2.45l0.06,-0.6l0.54,-0.81l1.05,-3.46l4.17,-0.07l0.4,-0.4l-0.02,-2.66l2.39,0.21l1.25,-0.27Z", "name": "Gabon"}, "GN": {"path": "M391.8,254.11l0.47,0.8l1.11,-0.32l0.98,0.7l1.07,0.2l2.26,-1.22l0.64,0.44l1.13,1.56l-0.48,1.4l0.8,0.3l-0.08,0.48l0.46,0.68l-0.35,1.36l1.05,2.61l-1.0,0.69l0.03,1.41l-0.72,-0.06l-1.08,1.0l-0.24,-0.27l0.07,-1.11l-1.05,-1.54l-1.79,0.21l-0.35,-2.01l-1.6,-2.18l-2.0,-0.0l-1.31,0.54l-1.95,2.18l-1.86,-2.19l-1.2,-0.78l-0.3,-1.11l-0.8,-0.85l0.65,-0.72l0.81,-0.03l1.64,-0.8l0.23,-1.87l2.67,0.64l0.89,-0.3l1.21,0.15Z", "name": "Guinea"}, "GM": {"path": "M379.31,251.39l0.1,-0.35l2.43,-0.07l0.74,-0.61l0.51,-0.03l0.77,0.49l-1.03,-0.3l-1.87,0.9l-1.65,-0.04ZM384.03,250.91l0.91,0.05l0.75,-0.24l-0.59,0.31l-1.08,-0.13Z", "name": "Gambia"}, "GL": {"path": "M353.02,1.2l14.69,4.67l-3.68,1.89l-22.97,0.86l-0.36,0.27l0.12,0.43l1.55,1.18l8.79,-0.66l7.48,2.07l4.86,-1.77l1.66,1.73l-2.53,3.19l-0.01,0.48l0.46,0.15l6.35,-2.2l12.06,-2.31l7.24,1.13l1.09,1.99l-9.79,4.01l-1.44,1.32l-7.87,0.98l-0.35,0.41l0.38,0.38l5.07,0.24l-2.53,3.58l-2.07,3.81l0.08,6.05l2.57,3.11l-3.22,0.2l-4.12,1.66l-0.05,0.72l4.45,2.65l0.51,3.75l-2.3,0.4l-0.25,0.64l2.79,3.69l-4.82,0.31l-0.36,0.29l0.16,0.44l2.62,1.8l-0.59,1.22l-3.3,0.7l-3.45,0.01l-0.29,0.68l3.03,3.12l0.02,1.34l-4.4,-1.73l-1.72,1.35l0.15,0.66l3.31,1.15l3.13,2.71l0.81,3.16l-3.85,0.75l-4.89,-4.26l-0.47,-0.03l-0.17,0.44l0.79,2.86l-2.71,2.21l-0.13,0.44l0.37,0.27l8.73,0.34l-12.32,6.64l-7.24,1.48l-2.94,0.08l-2.69,1.75l-3.43,4.41l-5.24,2.84l-1.73,0.18l-7.12,2.1l-2.15,2.52l-0.13,2.99l-1.19,2.45l-4.01,3.09l-0.14,0.44l0.97,2.9l-2.28,6.48l-3.1,0.2l-3.83,-3.07l-4.86,-0.02l-2.25,-1.93l-1.7,-3.79l-4.3,-4.84l-1.21,-2.49l-0.44,-3.8l-3.32,-3.63l0.84,-2.86l-1.56,-1.7l2.28,-4.6l3.83,-1.74l1.03,-1.96l0.52,-3.47l-0.59,-0.41l-4.17,2.21l-2.07,0.58l-2.72,-1.28l-0.15,-2.71l0.85,-2.09l2.01,-0.06l5.06,1.2l0.46,-0.23l-0.14,-0.49l-6.54,-4.47l-2.67,0.55l-1.58,-0.86l2.56,-4.01l-0.03,-0.48l-1.5,-1.74l-4.98,-8.5l-3.13,-1.96l0.03,-1.88l-0.24,-0.37l-6.85,-3.02l-5.36,-0.38l-12.7,0.58l-2.78,-1.57l-3.66,-2.77l5.73,-1.45l5.0,-0.28l0.38,-0.38l-0.35,-0.41l-10.67,-1.38l-5.3,-2.06l0.25,-1.54l18.41,-5.26l1.22,-2.27l-0.25,-0.55l-6.14,-1.86l1.68,-1.77l8.55,-4.03l3.59,-0.63l0.3,-0.54l-0.88,-2.27l5.47,-1.47l7.65,-0.95l7.55,-0.05l3.04,1.85l6.48,-3.27l5.81,2.22l3.56,0.5l5.16,1.94l0.5,-0.21l-0.17,-0.52l-5.71,-3.13l0.28,-2.13l8.12,-3.6l8.7,0.28l3.35,-2.34l8.71,-0.6l19.93,0.8Z", "name": "Greenland"}, "GH": {"path": "M420.53,257.51l-0.01,0.72l0.96,1.2l0.24,3.73l0.59,0.95l-0.51,2.1l0.19,1.41l1.02,2.21l-6.97,2.84l-1.8,-0.57l0.04,-0.89l-1.02,-2.04l0.61,-2.65l1.07,-2.32l-0.96,-6.47l5.01,0.07l0.94,-0.39l0.61,0.11Z", "name": "Ghana"}, "OM": {"path": "M568.09,230.93l-0.91,1.67l-1.22,0.04l-0.6,0.76l-0.41,1.51l0.27,1.58l-1.16,0.05l-1.56,0.97l-0.76,1.74l-1.62,0.05l-0.98,0.65l-0.17,1.15l-0.89,0.52l-1.49,-0.18l-2.4,0.94l-2.47,-5.4l7.35,-2.71l1.67,-5.23l-1.12,-2.09l0.05,-0.83l0.67,-1.0l0.07,-1.05l0.9,-0.42l-0.05,-2.07l0.7,-0.01l1.0,1.62l1.51,1.08l3.3,0.84l1.73,2.29l0.81,0.37l-1.23,2.35l-0.99,0.79Z", "name": "Oman"}, "TN": {"path": "M448.1,188.24l-1.0,1.27l-0.02,1.32l0.84,0.88l-0.28,2.09l-1.53,1.32l-0.12,0.42l0.48,1.54l1.42,0.32l0.53,1.11l0.9,0.52l-0.11,1.67l-3.54,2.64l-0.1,2.38l-0.58,0.3l-0.96,-4.45l-1.54,-1.25l-0.16,-0.78l-1.92,-1.56l-0.18,-1.76l1.51,-1.62l0.59,-2.34l-0.38,-2.78l0.42,-1.21l2.45,-1.05l1.29,0.26l-0.06,1.11l0.58,0.38l1.47,-0.73Z", "name": "Tunisia"}, "JO": {"path": "M518.64,201.38l-5.14,1.56l-0.19,0.65l2.16,2.39l-0.89,1.14l-1.71,0.34l-1.71,1.8l-2.34,-0.37l1.21,-4.32l0.56,-4.07l2.8,0.94l4.46,-2.71l0.79,2.66Z", "name": "Jordan"}, "HR": {"path": "M455.59,162.84l1.09,0.07l-0.82,0.94l-0.27,-1.01ZM456.96,162.92l0.62,-0.41l1.73,0.45l0.42,-0.4l-0.01,-0.59l0.86,-0.52l0.2,-1.05l1.63,-0.68l2.57,1.68l2.07,0.6l0.87,-0.31l1.05,1.57l-0.52,0.63l-1.05,-0.56l-1.68,0.04l-2.1,-0.5l-1.29,0.06l-0.57,0.49l-0.59,-0.47l-0.62,0.16l-0.46,1.7l1.79,2.42l2.79,2.75l-1.18,-0.87l-2.21,-0.87l-1.67,-1.78l0.13,-0.63l-1.05,-1.19l-0.32,-1.27l-1.42,-0.43Z", "name": "Croatia"}, "HT": {"path": "M237.05,238.38l-1.16,0.43l-0.91,-0.55l0.05,-0.2l2.02,0.31ZM237.53,238.43l1.06,0.12l-0.05,0.01l-1.01,-0.12ZM239.25,238.45l0.79,-0.51l0.06,-0.62l-1.02,-1.0l0.02,-0.82l-0.3,-0.4l-0.93,-0.32l3.16,0.45l0.02,1.84l-0.48,0.34l-0.08,0.58l0.54,0.72l-1.78,-0.26Z", "name": "Haiti"}, "HU": {"path": "M462.08,157.89l0.65,-1.59l-0.09,-0.44l0.64,-0.0l0.39,-0.34l0.1,-0.69l1.75,0.87l2.32,-0.37l0.43,-0.66l3.49,-0.78l0.69,-0.78l0.57,-0.14l2.57,0.93l0.67,-0.23l1.03,0.65l0.08,0.37l-1.42,0.71l-2.59,4.14l-1.8,0.53l-1.68,-0.1l-2.74,1.23l-1.85,-0.54l-2.54,-1.66l-0.66,-1.1Z", "name": "Hungary"}, "HN": {"path": "M199.6,249.52l-1.7,-1.21l0.06,-0.94l3.04,-2.14l2.37,0.28l1.27,-0.09l1.1,-0.52l1.3,0.28l1.14,-0.25l1.38,0.37l2.23,1.37l-2.36,0.93l-1.23,-0.39l-0.88,1.3l-1.28,0.99l-0.98,-0.22l-0.42,0.52l-0.96,0.05l-0.36,0.41l0.04,0.88l-0.52,0.6l-0.3,0.04l-0.3,-0.55l-0.66,-0.31l0.11,-0.67l-0.48,-0.65l-0.87,-0.26l-0.73,0.2Z", "name": "Honduras"}, "PR": {"path": "M256.17,238.73l-0.26,0.27l-2.83,0.05l-0.07,-0.55l1.95,-0.1l1.22,0.33Z", "name": "Puerto Rico"}, "PS": {"path": "M509.21,203.07l0.1,-0.06l-0.02,0.03l-0.09,0.03ZM509.36,202.91l-0.02,-0.63l-0.33,-0.16l0.31,-1.09l0.24,0.1l-0.2,1.78Z", "name": "Palestine"}, "PT": {"path": "M401.84,187.38l-0.64,0.47l-1.13,-0.35l-0.91,0.17l0.28,-1.78l-0.24,-1.78l-1.25,-0.56l-0.45,-0.84l0.17,-1.66l1.01,-1.18l0.69,-2.92l-0.04,-1.39l-0.59,-1.9l1.3,-0.85l0.84,1.35l3.1,-0.3l0.46,0.99l-1.05,0.94l-0.03,2.16l-0.41,0.57l-0.08,1.1l-0.79,0.18l-0.26,0.59l0.91,1.6l-0.63,1.75l0.76,1.09l-1.1,1.52l0.07,1.05Z", "name": "Portugal"}, "PY": {"path": "M274.9,336.12l0.74,1.52l-0.16,3.45l0.32,0.41l2.64,0.5l1.11,-0.47l1.4,0.59l0.36,0.6l0.53,3.42l1.27,0.4l0.98,-0.38l0.51,0.27l-0.0,1.18l-1.21,5.32l-2.09,1.9l-1.8,0.4l-4.71,-0.98l2.2,-3.63l-0.32,-1.5l-2.78,-1.28l-3.03,-1.94l-2.07,-0.44l-4.34,-4.06l0.91,-2.9l0.08,-1.42l1.07,-2.04l4.13,-0.72l2.18,0.03l2.05,1.17l0.03,0.59Z", "name": "Paraguay"}, "PA": {"path": "M213.8,263.68l0.26,-1.52l-0.36,-0.26l-0.01,-0.49l0.44,-0.1l0.93,1.4l1.26,0.03l0.77,0.49l1.38,-0.23l2.51,-1.11l0.86,-0.72l3.45,0.85l1.4,1.18l0.41,1.74l-0.21,0.34l-0.53,-0.12l-0.47,0.29l-0.16,0.6l-0.68,-1.28l0.45,-0.49l-0.19,-0.66l-0.47,-0.13l-0.54,-0.84l-1.5,-0.75l-1.1,0.16l-0.75,0.99l-1.62,0.84l-0.18,0.96l0.85,0.97l-0.58,0.45l-0.69,0.08l-0.34,-1.18l-1.27,0.03l-0.71,-1.05l-2.59,-0.46Z", "name": "Panama"}, "PG": {"path": "M808.58,298.86l2.54,2.56l-0.13,0.26l-0.33,0.12l-0.87,-0.78l-1.22,-2.16ZM801.41,293.04l0.5,0.29l0.26,0.27l-0.49,-0.35l-0.27,-0.21ZM803.17,294.58l0.59,0.5l0.08,1.06l-0.29,-0.91l-0.38,-0.65ZM796.68,298.41l0.52,0.75l1.43,-0.19l2.27,-1.81l-0.01,-1.43l1.12,0.16l-0.04,1.1l-0.7,1.28l-1.12,0.18l-0.62,0.79l-2.46,1.11l-1.17,-0.0l-3.08,-1.25l3.41,0.0l0.45,-0.68ZM789.15,303.55l2.31,1.8l1.59,2.61l1.34,0.13l-0.06,0.66l0.31,0.43l1.06,0.24l0.06,0.65l2.25,1.05l-1.22,0.13l-0.72,-0.63l-4.56,-0.65l-3.22,-2.87l-1.49,-2.34l-3.27,-1.1l-2.38,0.72l-1.59,0.86l-0.2,0.42l0.27,1.55l-1.55,0.68l-1.36,-0.4l-2.21,-0.09l-0.08,-15.41l8.39,2.93l2.95,2.4l0.6,1.64l4.02,1.49l0.31,0.68l-1.76,0.21l-0.33,0.52l0.55,1.68Z", "name": "Papua New Guinea"}, "PE": {"path": "M244.96,295.21l-1.26,-0.07l-0.57,0.42l-1.93,0.45l-2.98,1.75l-0.36,1.36l-0.58,0.8l0.12,1.37l-1.24,0.59l-0.22,1.22l-0.62,0.84l1.04,2.27l1.28,1.44l-0.41,0.84l0.32,0.57l1.48,0.13l1.16,1.37l2.21,0.07l1.63,-1.08l-0.13,3.02l0.3,0.4l1.14,0.29l1.31,-0.34l1.9,3.59l-0.48,0.85l-0.17,3.85l-0.94,1.59l0.35,0.75l-0.47,1.07l0.98,1.97l-2.1,3.82l-0.98,0.5l-2.17,-1.28l-0.39,-1.16l-4.95,-2.58l-4.46,-2.79l-1.84,-1.51l-0.91,-1.84l0.3,-0.96l-2.11,-3.33l-4.82,-9.68l-1.04,-1.2l-0.87,-1.94l-3.4,-2.48l0.58,-1.18l-1.13,-2.23l0.66,-1.49l1.45,-1.15l-0.6,0.98l0.07,0.92l0.47,0.36l1.74,0.03l0.97,1.17l0.54,0.07l1.42,-1.03l0.6,-1.84l1.42,-2.02l3.04,-1.04l2.73,-2.62l0.86,-1.74l-0.1,-1.87l1.44,1.02l0.9,1.25l1.06,0.59l1.7,2.73l1.86,0.31l1.45,-0.61l0.96,0.39l1.36,-0.19l1.45,0.89l-1.4,2.21l0.31,0.61l0.59,0.05l0.47,0.5Z", "name": "Peru"}, "PK": {"path": "M615.09,192.34l-1.83,1.81l-2.6,0.39l-3.73,-0.68l-1.58,1.33l-0.09,0.42l1.77,4.39l1.7,1.23l-1.69,1.27l-0.12,2.14l-2.33,2.64l-1.6,2.8l-2.46,2.67l-3.03,-0.07l-2.76,2.83l0.05,0.6l1.5,1.11l0.26,1.9l1.44,1.5l0.37,1.68l-5.01,-0.01l-1.78,1.7l-1.42,-0.52l-0.76,-1.87l-2.27,-2.15l-11.61,0.86l0.71,-2.34l3.43,-1.32l0.25,-0.44l-0.21,-1.24l-1.2,-0.65l-0.28,-2.46l-2.29,-1.14l-1.28,-1.94l2.82,0.94l2.62,-0.38l1.42,0.33l0.76,-0.56l1.71,0.19l3.25,-1.14l0.27,-0.36l0.08,-2.19l1.18,-1.32l1.68,0.0l0.58,-0.82l1.6,-0.3l1.19,0.16l0.98,-0.78l0.02,-1.88l0.93,-1.47l1.48,-0.66l0.19,-0.55l-0.66,-1.25l2.04,-0.11l0.69,-1.01l-0.02,-1.16l1.11,-1.06l-0.17,-1.78l-0.49,-1.03l1.15,-0.98l5.42,-0.91l2.6,-0.82l1.6,1.16l0.97,2.34l3.45,0.97Z", "name": "Pakistan"}, "PH": {"path": "M737.01,263.84l0.39,2.97l-0.44,1.18l-0.55,-1.53l-0.67,-0.14l-1.17,1.28l0.65,2.09l-0.42,0.69l-2.48,-1.23l-0.57,-1.49l0.65,-1.03l-0.1,-0.54l-1.59,-1.19l-0.56,0.08l-0.65,0.87l-1.23,0.0l-1.58,0.97l0.83,-1.8l2.56,-1.42l0.65,0.84l0.45,0.13l1.9,-0.69l0.56,-1.11l1.5,-0.06l0.38,-0.43l-0.09,-1.19l1.21,0.71l0.36,2.02ZM733.59,256.58l0.05,0.75l0.08,0.26l-0.8,-0.42l-0.18,-0.71l0.85,0.12ZM734.08,256.1l-0.12,-1.12l-1.0,-1.27l1.36,0.03l0.53,0.73l0.51,2.04l-1.27,-0.4ZM733.76,257.68l0.38,0.98l-0.32,0.15l-0.07,-1.13ZM724.65,238.43l1.46,0.7l0.72,-0.31l-0.32,1.17l0.79,1.71l-0.57,1.84l-1.53,1.04l-0.39,2.25l0.56,2.04l1.63,0.57l1.16,-0.27l2.71,1.23l-0.19,1.08l0.76,0.84l-0.08,0.36l-1.4,-0.9l-0.88,-1.27l-0.66,0.0l-0.38,0.55l-1.6,-1.31l-2.15,0.36l-0.87,-0.39l0.07,-0.61l0.66,-0.55l-0.01,-0.62l-0.75,-0.59l-0.72,0.44l-0.74,-0.87l-0.39,-2.49l0.32,0.27l0.66,-0.28l0.26,-3.97l0.7,-2.02l1.14,0.0ZM731.03,258.87l-0.88,0.85l-1.19,1.94l-1.05,-1.19l0.93,-1.1l0.32,-1.47l0.52,-0.06l-0.27,1.15l0.22,0.45l0.49,-0.12l1.0,-1.32l-0.08,0.85ZM726.83,255.78l0.83,0.38l1.17,-0.0l-0.02,0.48l-2.0,1.4l0.03,-2.26ZM724.81,252.09l-0.38,1.27l-1.42,-1.95l1.2,0.05l0.6,0.63ZM716.55,261.82l1.1,-0.95l0.03,-0.03l-0.28,0.36l-0.85,0.61ZM719.22,259.06l0.04,-0.06l0.8,-1.53l0.16,0.75l-1.0,0.84Z", "name": "Philippines"}, "PL": {"path": "M468.44,149.42l-1.11,-1.54l-1.86,-0.33l-0.48,-1.05l-1.72,-0.37l-0.65,0.69l-0.72,-0.36l0.11,-0.61l-0.33,-0.46l-1.75,-0.27l-1.04,-0.93l-0.94,-1.94l0.16,-1.22l-0.62,-1.8l-0.78,-1.07l0.57,-1.04l-0.48,-1.43l1.41,-0.83l6.91,-2.71l2.14,0.5l0.52,0.91l5.51,0.44l4.55,-0.05l1.07,0.31l0.48,0.84l0.15,1.58l0.65,1.2l-0.01,0.99l-1.27,0.58l-0.19,0.54l0.73,1.48l0.08,1.55l1.2,2.76l-0.17,0.58l-1.23,0.44l-2.27,2.72l0.18,0.95l-1.97,-1.03l-1.98,0.4l-1.36,-0.28l-1.24,0.58l-1.07,-0.97l-1.16,0.24Z", "name": "Poland"}, "ZM": {"path": "M481.47,313.3l0.39,0.31l2.52,0.14l0.99,1.17l2.01,0.35l1.4,-0.64l0.69,1.17l1.78,0.33l1.84,2.35l2.23,0.18l0.4,-0.43l-0.21,-2.74l-0.62,-0.3l-0.48,0.32l-1.98,-1.17l0.72,-5.29l-0.51,-1.18l0.57,-1.3l3.68,-0.62l0.26,0.63l1.21,0.63l0.9,-0.22l2.16,0.67l1.33,0.71l1.07,1.02l0.56,1.87l-0.88,2.7l0.43,2.09l-0.73,0.87l-0.76,2.37l0.59,0.68l-6.6,1.83l-0.29,0.44l0.19,1.45l-1.68,0.35l-1.43,1.02l-0.38,0.87l-0.87,0.26l-3.48,3.69l-4.16,-0.53l-1.52,-1.0l-1.77,-0.13l-1.83,0.52l-3.04,-3.4l0.11,-7.59l4.82,0.03l0.39,-0.49l-0.18,-0.76l0.33,-0.83l-0.4,-1.36l0.24,-1.05Z", "name": "Zambia"}, "EH": {"path": "M384.42,230.28l0.25,-0.79l1.06,-1.29l0.8,-3.51l3.38,-2.78l0.7,-1.81l0.06,4.84l-1.98,0.2l-0.94,1.59l0.39,3.56l-3.7,-0.01ZM392.01,218.1l0.7,-1.8l1.77,-0.24l2.09,0.34l0.95,-0.62l1.28,-0.07l-0.0,2.51l-6.79,-0.12Z", "name": "W. Sahara"}, "EE": {"path": "M485.71,115.04l2.64,0.6l2.56,0.11l-1.6,1.91l0.61,3.54l-0.81,0.87l-1.78,-0.01l-3.22,-1.76l-1.8,0.45l0.21,-1.53l-0.58,-0.41l-0.69,0.34l-1.26,-1.03l-0.17,-1.63l2.83,-0.92l3.05,-0.52Z", "name": "Estonia"}, "EG": {"path": "M492.06,205.03l1.46,0.42l2.95,-1.64l2.04,-0.21l1.53,0.3l0.59,1.19l0.69,0.04l0.41,-0.64l1.81,0.58l1.95,0.16l1.04,-0.51l1.42,4.08l-2.03,4.54l-1.66,-1.77l-1.76,-3.85l-0.64,-0.12l-0.36,0.67l1.04,2.88l3.44,6.95l1.78,3.04l2.03,2.65l-0.36,0.53l0.23,2.01l2.7,2.19l-28.41,0.0l0.0,-18.96l-0.73,-2.2l0.59,-1.56l-0.32,-1.26l0.68,-0.99l3.06,-0.04l4.82,1.52Z", "name": "Egypt"}, "ZA": {"path": "M467.14,373.21l-0.13,-1.96l-0.68,-1.56l0.7,-0.68l-0.13,-2.33l-4.56,-8.19l0.77,-0.86l0.6,0.45l0.69,1.31l2.83,0.72l1.5,-0.26l2.24,-1.39l0.19,-9.55l1.35,2.3l-0.21,1.5l0.61,1.2l0.4,0.19l1.79,-0.27l2.6,-2.07l0.69,-1.32l0.96,-0.48l2.19,1.04l2.04,0.13l1.77,-0.65l0.85,-2.12l1.38,-0.33l1.59,-2.76l2.15,-1.89l3.41,-1.87l2.0,0.45l1.02,-0.28l0.99,0.2l1.75,5.29l-0.38,3.25l-0.81,-0.23l-1.0,0.46l-0.87,1.68l-0.05,1.16l1.97,1.84l1.47,-0.29l0.69,-1.18l1.09,0.01l-0.76,3.69l-0.58,1.09l-2.2,1.79l-3.17,4.76l-2.8,2.83l-3.57,2.88l-2.53,1.05l-1.22,0.14l-0.51,0.7l-1.18,-0.32l-1.39,0.5l-2.59,-0.52l-1.61,0.33l-1.18,-0.11l-2.55,1.1l-2.1,0.44l-1.6,1.07l-0.85,0.05l-0.93,-0.89l-0.93,-0.15l-0.97,-1.13l-0.25,0.05ZM491.45,364.19l0.62,-0.93l1.48,-0.59l1.18,-2.19l-0.07,-0.49l-1.99,-1.69l-1.66,0.56l-1.43,1.14l-1.34,1.73l0.02,0.51l1.88,2.11l1.31,-0.16Z", "name": "South Africa"}, "EC": {"path": "M231.86,285.53l0.29,1.59l-0.69,1.45l-2.61,2.51l-3.13,1.11l-1.53,2.18l-0.49,1.68l-1.0,0.73l-1.02,-1.11l-1.78,-0.16l0.67,-1.15l-0.24,-0.86l1.25,-2.13l-0.54,-1.09l-0.67,-0.08l-0.72,0.87l-0.87,-0.64l0.35,-0.69l-0.36,-1.96l0.81,-0.51l0.45,-1.51l0.92,-1.57l-0.07,-0.97l2.65,-1.33l2.75,1.35l0.77,1.05l2.12,0.35l0.76,-0.32l1.96,1.21Z", "name": "Ecuador"}, "IT": {"path": "M451.59,158.63l3.48,0.94l-0.21,1.17l0.3,0.83l-1.49,-0.24l-2.04,1.1l-0.21,0.39l0.13,1.45l-0.25,1.12l0.82,1.57l2.39,1.63l1.31,2.54l2.79,2.43l2.05,0.08l0.21,0.23l-0.39,0.33l0.09,0.67l4.05,1.97l2.17,1.76l-0.16,0.36l-1.17,-1.08l-2.18,-0.49l-0.44,0.2l-1.05,1.91l0.14,0.54l1.57,0.95l-0.19,0.98l-1.06,0.33l-1.25,2.34l-0.37,0.08l0.0,-0.33l1.0,-2.45l-1.73,-3.17l-1.12,-0.51l-0.88,-1.33l-1.51,-0.51l-1.27,-1.25l-1.75,-0.18l-4.12,-3.21l-1.62,-1.65l-1.03,-3.19l-3.53,-1.36l-1.3,0.51l-1.69,1.41l0.16,-0.72l-0.28,-0.47l-1.14,-0.33l-0.53,-1.96l0.72,-0.78l0.04,-0.48l-0.65,-1.17l0.8,0.39l1.4,-0.23l1.11,-0.84l0.52,0.35l1.19,-0.1l0.75,-1.2l1.53,0.33l1.36,-0.56l0.35,-1.14l1.08,0.32l0.68,-0.64l1.98,-0.44l0.42,0.82ZM459.19,184.75l-0.65,1.65l0.32,1.05l-0.31,0.89l-1.5,-0.85l-4.5,-1.67l0.19,-0.82l2.67,0.23l3.78,-0.48ZM443.93,176.05l1.18,1.66l-0.3,3.32l-1.06,-0.01l-0.77,0.73l-0.53,-0.44l-0.1,-3.37l-0.39,-1.22l1.04,0.01l0.92,-0.68Z", "name": "Italy"}, "VN": {"path": "M690.56,230.25l-2.7,1.82l-2.09,2.46l-0.63,1.95l4.31,6.45l2.32,1.65l1.43,1.94l1.11,4.59l-0.32,4.24l-1.93,1.54l-2.84,1.61l-2.11,2.15l-2.73,2.06l-0.59,-1.05l0.63,-1.53l-0.13,-0.47l-1.34,-1.04l1.51,-0.71l2.55,-0.18l0.3,-0.63l-0.82,-1.14l4.0,-2.07l0.31,-3.05l-0.57,-1.77l0.42,-2.66l-0.73,-1.97l-1.86,-1.76l-3.63,-5.29l-2.72,-1.46l0.36,-0.47l1.5,-0.64l0.21,-0.52l-0.97,-2.27l-0.37,-0.24l-2.83,-0.02l-2.24,-3.9l0.83,-0.4l4.39,-0.29l2.06,-1.31l1.15,0.89l1.88,0.4l-0.17,1.51l1.35,1.16l1.67,0.45Z", "name": "Vietnam"}, "SB": {"path": "M826.69,311.6l-0.61,0.09l-0.2,-0.33l0.37,0.15l0.44,0.09ZM824.18,307.38l-0.26,-0.3l-0.31,-0.91l0.03,0.0l0.54,1.21ZM823.04,309.33l-1.66,-0.22l-0.2,-0.52l1.16,0.28l0.69,0.46ZM819.28,304.68l1.14,0.65l0.02,0.03l-0.81,-0.44l-0.35,-0.23Z", "name": "Solomon Is."}, "ET": {"path": "M516.04,247.79l1.1,0.84l1.63,-0.45l0.68,0.47l1.63,0.03l2.01,0.94l1.73,1.66l1.64,2.07l-1.52,2.04l0.16,1.72l0.39,0.38l2.05,0.0l-0.36,1.03l2.86,3.58l8.32,3.08l1.31,0.02l-6.32,6.75l-3.1,0.11l-2.36,1.77l-1.47,0.04l-0.86,0.79l-1.38,-0.0l-1.32,-0.81l-2.29,1.05l-0.76,0.98l-3.29,-0.41l-3.07,-2.07l-1.8,-0.07l-0.62,-0.6l0.0,-1.24l-0.28,-0.38l-1.15,-0.37l-1.4,-2.59l-1.19,-0.68l-0.47,-1.0l-1.27,-1.23l-1.16,-0.22l0.43,-0.72l1.45,-0.28l0.41,-0.95l-0.03,-2.21l0.68,-2.44l1.05,-0.63l1.43,-3.06l1.57,-1.37l1.02,-2.51l0.35,-1.88l2.52,0.46l0.44,-0.24l0.58,-1.43Z", "name": "Ethiopia"}, "SO": {"path": "M525.13,288.48l-1.13,-1.57l-0.03,-8.86l2.66,-3.38l1.67,-0.13l2.13,-1.69l3.41,-0.23l7.08,-7.55l2.91,-3.69l0.08,-4.82l2.98,-0.67l1.24,-0.86l0.45,-0.0l-0.2,3.0l-1.21,3.62l-2.73,5.97l-2.13,3.65l-5.03,6.16l-8.56,6.4l-2.78,3.08l-0.8,1.56Z", "name": "Somalia"}, "ZW": {"path": "M498.91,341.09l-1.11,-0.22l-0.92,0.28l-2.09,-0.44l-1.5,-1.11l-1.89,-0.43l-0.62,-1.4l-0.01,-0.84l-0.3,-0.38l-0.97,-0.25l-2.71,-2.74l-1.92,-3.32l3.83,0.45l3.73,-3.82l1.08,-0.44l0.26,-0.77l1.25,-0.9l1.41,-0.26l0.5,0.89l1.99,-0.05l1.72,1.17l1.11,0.17l1.05,0.66l0.01,2.99l-0.59,3.76l0.38,0.86l-0.23,1.23l-0.39,0.35l-0.63,1.81l-2.43,2.75Z", "name": "Zimbabwe"}, "ES": {"path": "M416.0,169.21l1.07,1.17l4.61,1.38l1.06,-0.57l2.6,1.26l2.71,-0.3l0.09,1.12l-2.14,1.8l-3.11,0.61l-0.31,0.31l-0.2,0.89l-1.54,1.69l-0.97,2.4l0.84,1.74l-1.32,1.27l-0.48,1.68l-1.88,0.65l-1.66,2.07l-5.36,-0.01l-1.79,1.08l-0.89,0.98l-0.88,-0.17l-0.79,-0.82l-0.68,-1.59l-2.37,-0.63l-0.11,-0.5l1.21,-1.82l-0.77,-1.13l0.61,-1.68l-0.76,-1.62l0.87,-0.49l0.09,-1.25l0.42,-0.6l0.03,-2.11l0.99,-0.69l0.13,-0.5l-1.03,-1.73l-1.46,-0.11l-0.61,0.38l-1.06,0.0l-0.52,-1.23l-0.53,-0.21l-1.32,0.67l-0.01,-1.49l-0.75,-0.96l3.03,-1.88l2.99,0.53l3.32,-0.02l2.63,0.51l6.01,-0.06Z", "name": "Spain"}, "ER": {"path": "M520.38,246.23l3.42,2.43l3.5,3.77l0.84,0.54l-0.95,-0.01l-3.51,-3.89l-2.33,-1.15l-1.73,-0.07l-0.91,-0.51l-1.26,0.51l-1.34,-1.02l-0.61,0.17l-0.66,1.61l-2.35,-0.43l-0.17,-0.67l1.29,-5.29l0.61,-0.61l1.95,-0.53l0.87,-1.01l1.17,2.41l0.68,2.33l1.49,1.43Z", "name": "Eritrea"}, "ME": {"path": "M468.91,172.53l-1.22,-1.02l0.47,-1.81l0.89,-0.72l2.26,1.51l-0.5,0.57l-0.75,-0.27l-1.14,1.73Z", "name": "Montenegro"}, "MD": {"path": "M488.41,153.73l1.4,-0.27l1.72,0.93l1.07,0.15l0.85,0.65l-0.14,0.84l0.96,0.85l1.12,2.47l-1.15,-0.07l-0.66,-0.41l-0.52,0.25l-0.09,0.86l-1.08,1.89l-0.27,-0.86l0.25,-1.34l-0.16,-1.6l-3.29,-4.34Z", "name": "Moldova"}, "MG": {"path": "M545.91,319.14l0.4,3.03l0.62,1.21l-0.21,1.02l-0.57,-0.8l-0.69,-0.01l-0.47,0.76l0.41,2.12l-0.18,0.87l-0.73,0.78l-0.15,2.14l-4.71,15.2l-1.06,2.88l-3.92,1.64l-3.12,-1.49l-0.6,-1.21l-0.19,-2.4l-0.86,-2.05l-0.21,-1.77l0.38,-1.62l1.21,-0.75l0.01,-0.76l1.19,-2.04l0.23,-1.66l-1.06,-2.99l-0.19,-2.21l0.81,-1.33l0.32,-1.46l4.63,-1.22l3.44,-3.0l0.85,-1.4l-0.08,-0.7l0.78,-0.04l1.38,-1.77l0.13,-1.64l0.45,-0.61l1.16,1.69l0.59,1.6Z", "name": "Madagascar"}, "MA": {"path": "M378.78,230.02l0.06,-0.59l0.92,-0.73l0.82,-1.37l-0.09,-1.04l0.79,-1.7l1.31,-1.58l0.96,-0.59l0.66,-1.55l0.09,-1.47l0.81,-1.48l1.72,-1.07l1.55,-2.69l1.16,-0.96l2.44,-0.39l1.94,-1.82l1.31,-0.78l2.09,-2.28l-0.51,-3.65l1.24,-3.7l1.5,-1.75l4.46,-2.57l2.37,-4.47l1.44,0.01l1.68,1.21l2.32,-0.19l3.47,0.65l0.8,1.54l0.16,1.71l0.86,2.96l0.56,0.59l-0.26,0.61l-3.05,0.44l-1.26,1.05l-1.33,0.22l-0.33,0.37l-0.09,1.78l-2.68,1.0l-1.07,1.42l-4.47,1.13l-4.04,2.01l-0.54,4.64l-1.15,0.06l-0.92,0.61l-1.96,-0.35l-2.42,0.54l-0.74,1.9l-0.86,0.4l-1.14,3.26l-3.53,3.01l-0.8,3.55l-0.96,1.1l-0.29,0.82l-4.95,0.18Z", "name": "Morocco"}, "UZ": {"path": "M598.64,172.75l-1.63,1.52l0.06,0.64l1.85,1.12l1.97,-0.64l2.21,1.17l-2.52,1.68l-2.59,-0.22l-0.18,-0.41l0.46,-1.23l-0.45,-0.53l-3.35,0.69l-2.1,3.51l-1.87,-0.12l-1.03,1.51l0.22,0.55l1.64,0.62l0.46,1.83l-1.19,2.49l-2.66,-0.53l0.05,-1.36l-0.26,-0.39l-3.3,-1.23l-2.56,-1.4l-4.4,-3.34l-1.34,-3.14l-1.08,-0.6l-2.58,0.13l-0.69,-0.44l-0.47,-2.52l-3.37,-1.6l-0.43,0.05l-2.07,1.72l-2.1,1.01l-0.21,0.47l0.28,1.01l-1.91,0.03l-0.09,-10.5l5.99,-1.7l6.19,3.54l2.71,2.84l7.05,-0.67l2.71,2.01l-0.17,2.81l0.39,0.42l0.9,0.02l0.44,2.14l0.38,0.32l2.94,0.09l0.95,1.42l1.28,-0.24l1.05,-2.04l4.43,-2.5Z", "name": "Uzbekistan"}, "MM": {"path": "M673.9,230.21l-1.97,1.57l-0.57,0.96l-1.4,0.6l-1.36,1.05l-1.99,0.36l-1.08,2.66l-0.91,0.4l-0.19,0.55l1.21,2.27l2.52,3.43l-0.79,1.91l-0.74,0.41l-0.17,0.52l0.65,1.37l1.61,1.95l0.25,2.58l0.9,2.13l-1.92,3.57l0.68,-2.25l-0.81,-1.74l0.19,-2.65l-1.05,-1.53l-1.24,-6.17l-1.12,-2.26l-0.6,-0.13l-4.34,3.02l-2.39,-0.65l0.77,-2.84l-0.52,-2.61l-1.91,-2.96l0.25,-0.75l-0.29,-0.51l-1.33,-0.3l-1.61,-1.93l-0.1,-1.3l0.82,-0.24l0.04,-1.64l1.02,-0.52l0.21,-0.45l-0.23,-0.95l0.54,-0.96l0.08,-2.22l1.46,0.45l0.47,-0.2l1.12,-2.19l0.16,-1.35l1.33,-2.16l-0.0,-1.52l2.89,-1.66l1.63,0.44l0.5,-0.44l-0.17,-1.4l0.64,-0.36l0.08,-1.04l0.77,-0.11l0.71,1.35l1.06,0.69l-0.03,3.86l-2.38,2.37l-0.3,3.15l0.46,0.43l2.28,-0.38l0.51,2.08l1.47,0.67l-0.6,1.8l0.19,0.48l2.97,1.48l1.64,-0.55l0.02,0.32Z", "name": "Myanmar"}, "ML": {"path": "M392.61,254.08l-0.19,-2.37l-0.99,-0.87l-0.44,-1.3l-0.09,-1.28l0.81,-0.58l0.35,-1.24l2.37,0.65l1.31,-0.47l0.86,0.15l0.66,-0.56l9.83,-0.04l0.38,-0.28l0.56,-1.8l-0.44,-0.65l-2.35,-21.95l3.27,-0.04l16.7,11.38l0.74,1.31l2.5,1.09l0.02,1.38l0.44,0.39l2.34,-0.21l0.01,5.38l-1.28,1.61l-0.26,1.49l-5.31,0.57l-1.07,0.92l-2.9,0.1l-0.86,-0.48l-1.38,0.36l-2.4,1.08l-0.6,0.87l-1.85,1.09l-0.43,0.7l-0.79,0.39l-1.44,-0.21l-0.81,0.84l-0.34,1.64l-1.91,2.02l-0.06,1.03l-0.67,1.22l0.13,1.16l-0.97,0.39l-0.23,-0.64l-0.52,-0.24l-1.35,0.4l-0.34,0.55l-2.69,-0.28l-0.37,-0.35l-0.02,-0.9l-0.65,-0.35l0.45,-0.64l-0.03,-0.53l-2.12,-2.44l-0.76,-0.01l-2.0,1.16l-0.78,-0.15l-0.8,-0.67l-1.21,0.23Z", "name": "Mali"}, "MN": {"path": "M676.61,146.48l3.81,1.68l5.67,-1.0l2.37,0.41l2.34,1.5l1.79,1.75l2.29,-0.03l3.12,0.52l2.47,-0.81l3.41,-0.59l3.53,-2.21l1.25,0.29l1.53,1.13l2.27,-0.21l-2.66,5.01l0.64,1.68l0.47,0.21l1.32,-0.38l2.38,0.48l2.02,-1.11l1.76,0.89l2.06,2.02l-0.13,0.53l-1.72,-0.29l-3.77,0.46l-1.88,0.99l-1.76,1.99l-3.71,1.17l-2.45,1.6l-3.83,-0.87l-0.41,0.17l-1.31,1.99l1.04,2.24l-1.52,0.9l-1.74,1.57l-2.79,1.02l-3.78,0.13l-4.05,1.05l-2.77,1.52l-1.16,-0.85l-2.94,0.0l-3.62,-1.79l-2.58,-0.49l-3.4,0.41l-5.12,-0.67l-2.63,0.06l-1.31,-1.6l-1.4,-3.0l-1.48,-0.33l-3.13,-1.94l-6.16,-0.93l-0.71,-1.06l0.86,-3.82l-1.93,-2.71l-3.5,-1.18l-1.95,-1.58l-0.5,-1.72l2.34,-0.52l4.75,-2.8l3.62,-1.47l2.18,0.97l2.46,0.05l1.81,1.53l2.46,0.12l3.95,0.71l2.43,-2.28l0.08,-0.48l-0.9,-1.72l2.24,-2.98l2.62,1.27l4.94,1.17l0.43,2.24Z", "name": "Mongolia"}, "MK": {"path": "M472.8,173.98l0.49,-0.71l3.57,-0.71l1.0,0.77l0.13,1.45l-0.65,0.53l-1.15,-0.05l-1.12,0.67l-1.39,0.22l-0.79,-0.55l-0.29,-1.03l0.19,-0.6Z", "name": "Macedonia"}, "MW": {"path": "M505.5,309.31l0.85,1.95l0.15,2.86l-0.69,1.65l0.71,1.8l0.06,1.28l0.49,0.64l0.07,1.06l0.4,0.55l0.8,-0.23l0.55,0.61l0.69,-0.21l0.34,0.6l0.19,2.94l-1.04,0.62l-0.54,1.25l-1.11,-1.08l-0.16,-1.56l0.51,-1.31l-0.32,-1.3l-0.99,-0.65l-0.82,0.12l-2.36,-1.64l0.63,-1.96l0.82,-1.18l-0.46,-2.01l0.9,-2.86l-0.94,-2.51l0.96,0.18l0.29,0.4Z", "name": "Malawi"}, "MR": {"path": "M407.36,220.66l-2.58,0.03l-0.39,0.44l2.42,22.56l0.36,0.43l-0.39,1.24l-9.75,0.04l-0.56,0.53l-0.91,-0.11l-1.27,0.45l-1.61,-0.66l-0.97,0.03l-0.36,0.29l-0.38,1.35l-0.42,0.23l-2.93,-3.4l-2.96,-1.52l-1.62,-0.03l-1.27,0.54l-1.12,-0.2l-0.65,0.4l-0.08,-0.49l0.68,-1.29l0.31,-2.43l-0.57,-3.91l0.23,-1.21l-0.69,-1.5l-1.15,-1.02l0.25,-0.39l9.58,0.02l0.4,-0.45l-0.46,-3.68l0.47,-1.04l2.12,-0.21l0.36,-0.4l-0.08,-6.4l7.81,0.13l0.41,-0.4l0.01,-3.31l7.76,5.35Z", "name": "Mauritania"}, "UG": {"path": "M498.55,276.32l0.7,-0.46l1.65,0.5l1.96,-0.57l1.7,0.01l1.45,-0.98l0.91,1.33l1.33,3.95l-2.57,4.03l-1.46,-0.4l-2.54,0.91l-1.37,1.61l-0.01,0.81l-2.42,-0.01l-2.26,1.01l-0.17,-1.59l0.58,-1.04l0.14,-1.94l1.37,-2.28l1.78,-1.58l-0.17,-0.65l-0.72,-0.24l0.13,-2.43Z", "name": "Uganda"}, "MY": {"path": "M717.47,273.46l-1.39,0.65l-2.12,-0.41l-2.88,-0.0l-0.38,0.28l-0.84,2.75l-0.99,0.96l-1.21,3.29l-1.73,0.45l-2.45,-0.68l-1.39,0.31l-1.33,1.15l-1.59,-0.14l-1.41,0.44l-1.44,-1.19l-0.18,-0.73l1.34,0.53l1.93,-0.47l0.75,-2.22l4.02,-1.03l2.75,-3.21l0.82,0.94l0.64,-0.05l0.4,-0.65l0.96,0.06l0.42,-0.36l0.24,-2.68l1.81,-1.64l1.21,-1.86l0.63,-0.01l1.07,1.05l0.34,1.28l3.44,1.35l-0.06,0.35l-1.37,0.1l-0.35,0.54l0.32,0.88ZM673.68,269.59l0.17,1.09l0.47,0.33l1.65,-0.3l0.87,-0.94l1.61,1.52l0.98,1.56l-0.12,2.81l0.41,2.29l0.95,0.9l0.88,2.44l-1.27,0.12l-5.1,-3.67l-0.34,-1.29l-1.37,-1.59l-0.33,-1.97l-0.88,-1.4l0.25,-1.68l-0.46,-1.05l1.63,0.84Z", "name": "Malaysia"}, "MX": {"path": "M133.12,200.41l0.2,0.47l9.63,3.33l6.96,-0.02l0.4,-0.4l0.0,-0.74l3.77,0.0l3.55,2.93l1.39,2.83l1.52,1.04l2.08,0.82l0.47,-0.14l1.46,-2.0l1.73,-0.04l1.59,0.98l2.05,3.35l1.47,1.56l1.26,3.14l2.18,1.02l2.26,0.58l-1.18,3.72l-0.42,5.04l1.79,4.89l1.62,1.89l0.61,1.52l1.2,1.42l2.55,0.66l1.37,1.1l7.54,-1.89l1.86,-1.3l1.14,-4.3l4.1,-1.21l3.57,-0.11l0.32,0.3l-0.06,0.94l-1.26,1.45l-0.67,1.71l0.38,0.7l-0.72,2.27l-0.49,-0.3l-1.0,0.08l-1.0,1.39l-0.47,-0.11l-0.53,0.47l-4.26,-0.02l-0.4,0.4l-0.0,1.06l-1.1,0.26l0.1,0.44l1.82,1.44l0.56,0.91l-3.19,0.21l-1.21,2.09l0.24,0.72l-0.2,0.44l-2.24,-2.18l-1.45,-0.93l-2.22,-0.69l-1.52,0.22l-3.07,1.16l-10.55,-3.85l-2.86,-1.96l-3.78,-0.92l-1.08,-1.19l-2.62,-1.43l-1.18,-1.54l-0.38,-0.81l0.66,-0.63l-0.18,-0.53l0.52,-0.76l0.01,-0.91l-2.0,-3.82l-2.21,-2.63l-2.53,-2.09l-1.19,-1.62l-2.2,-1.17l-0.3,-0.43l0.34,-1.48l-0.21,-0.45l-1.23,-0.6l-1.36,-1.2l-0.59,-1.78l-1.54,-0.47l-2.44,-2.55l-0.16,-0.9l-1.33,-2.03l-0.84,-1.99l-0.16,-1.33l-1.81,-1.1l-0.97,0.05l-1.31,-0.7l-0.57,0.22l-0.4,1.12l0.72,3.77l3.51,3.89l0.28,0.78l0.53,0.26l0.41,1.43l1.33,1.73l1.58,1.41l0.8,2.39l1.43,2.41l0.13,1.32l0.37,0.36l1.04,0.08l1.67,2.28l-0.85,0.76l-0.66,-1.51l-1.68,-1.54l-2.91,-1.87l0.06,-1.82l-0.54,-1.68l-2.91,-2.03l-0.55,0.09l-1.95,-1.1l-0.88,-0.94l0.68,-0.08l0.93,-1.01l0.08,-1.78l-1.93,-1.94l-1.46,-0.77l-3.75,-7.56l4.88,-0.42Z", "name": "Mexico"}, "IL": {"path": "M507.76,203.05l0.4,-0.78l0.18,0.4l-0.33,1.03l0.52,0.44l0.68,-0.22l-0.86,3.6l-1.16,-3.32l0.59,-0.74l-0.03,-0.41ZM508.73,200.34l0.37,-1.02l0.64,0.0l0.52,-0.51l-0.49,1.53l-0.56,-0.24l-0.48,0.23Z", "name": "Israel"}, "FR": {"path": "M444.48,172.62l-0.64,1.78l-0.58,-0.31l-0.49,-1.72l0.4,-0.89l1.0,-0.72l0.3,1.85ZM429.64,147.1l1.78,1.58l1.46,-0.13l2.1,1.42l1.35,0.27l1.23,0.83l3.04,0.5l-1.03,1.85l-0.3,2.12l-0.41,0.32l-0.95,-0.24l-0.5,0.43l0.06,0.61l-1.81,1.92l-0.04,1.42l0.55,0.38l0.88,-0.36l0.61,0.97l-0.03,1.0l0.57,0.91l-0.75,1.09l0.65,2.39l1.27,0.57l-0.18,0.82l-2.01,1.53l-4.77,-0.8l-3.82,1.0l-0.53,1.85l-2.49,0.34l-2.71,-1.31l-1.16,0.57l-4.31,-1.29l-0.72,-0.86l1.19,-1.78l0.39,-6.45l-2.58,-3.3l-1.9,-1.66l-3.72,-1.23l-0.19,-1.72l2.81,-0.61l4.12,0.81l0.47,-0.48l-0.6,-2.77l1.94,0.95l5.83,-2.54l0.92,-2.74l1.6,-0.49l0.24,0.78l1.36,0.33l1.05,1.19ZM289.01,278.39l-0.81,0.8l-0.78,0.12l-0.5,-0.66l-0.56,-0.1l-0.91,0.6l-0.46,-0.22l1.09,-2.96l-0.96,-1.77l-0.17,-1.49l1.07,-1.77l2.32,0.75l2.51,2.01l0.3,0.74l-2.14,3.96Z", "name": "France"}, "XS": {"path": "M531.15,258.94l1.51,0.12l5.13,-0.95l5.3,-1.48l-0.01,4.4l-2.67,3.39l-1.85,0.01l-8.04,-2.94l-2.55,-3.17l1.12,-1.71l2.04,2.34Z", "name": "Somaliland"}, "FI": {"path": "M492.17,76.39l-0.23,3.5l3.52,2.63l-2.08,2.88l-0.02,0.44l2.8,4.56l-1.59,3.31l2.16,3.24l-0.94,2.39l0.14,0.47l3.44,2.51l-0.77,1.62l-7.52,6.95l-4.5,0.31l-4.38,1.37l-3.8,0.74l-1.44,-1.96l-2.17,-1.11l0.5,-3.66l-1.16,-3.33l1.09,-2.08l2.21,-2.42l5.67,-4.32l1.64,-0.83l0.21,-0.42l-0.46,-2.02l-3.38,-1.89l-0.75,-1.43l-0.22,-6.74l-6.79,-4.8l0.8,-0.62l2.54,2.12l3.46,-0.12l3.0,0.96l2.51,-2.11l1.17,-3.08l3.55,-1.38l2.76,1.53l-0.95,2.79Z", "name": "Finland"}, "FJ": {"path": "M869.95,326.98l-1.21,0.41l-0.08,-0.23l2.97,-1.21l-0.14,0.42l-1.54,0.61ZM867.58,329.25l0.43,0.37l-0.27,0.88l-1.24,0.28l-1.04,-0.24l-0.14,-0.66l0.63,-0.58l0.92,0.26l0.7,-0.31Z", "name": "Fiji"}, "FK": {"path": "M274.36,425.85l1.44,1.08l-0.47,0.73l-3.0,0.89l-0.96,-1.0l-0.52,-0.05l-1.83,1.29l-0.73,-0.88l2.46,-1.64l1.93,0.76l1.67,-1.19Z", "name": "Falkland Is."}, "NI": {"path": "M202.33,252.67l0.81,-0.18l1.03,-1.02l-0.04,-0.88l0.68,-0.0l0.63,-0.54l0.97,0.22l1.53,-1.26l0.58,-0.99l1.17,0.34l2.41,-0.94l0.13,1.32l-0.81,1.94l0.1,2.74l-0.36,0.37l-0.11,1.75l-0.47,0.81l0.18,1.14l-1.73,-0.85l-0.71,0.27l-1.47,-0.6l-0.52,0.16l-4.01,-3.81Z", "name": "Nicaragua"}, "NL": {"path": "M430.31,143.39l0.6,-0.5l2.13,-4.8l3.2,-1.33l1.74,0.08l0.33,0.8l-0.59,2.92l-0.5,0.99l-1.26,0.0l-0.4,0.45l0.33,2.7l-2.2,-1.78l-2.62,0.58l-0.75,-0.11Z", "name": "Netherlands"}, "NO": {"path": "M491.44,67.41l6.8,2.89l-2.29,0.86l-0.15,0.65l2.33,2.38l-4.98,1.79l0.84,-2.45l-0.18,-0.48l-3.55,-1.8l-3.89,1.52l-1.42,3.38l-2.12,1.72l-2.64,-1.0l-3.11,0.21l-2.66,-2.22l-0.5,-0.01l-1.41,1.1l-1.44,0.17l-0.35,0.35l-0.32,2.47l-4.32,-0.64l-0.44,0.29l-0.58,2.11l-2.45,0.2l-4.15,7.68l-3.88,5.76l0.78,1.62l-0.64,1.16l-2.24,-0.06l-0.38,0.24l-1.66,3.89l0.15,5.17l1.57,2.04l-0.78,4.16l-2.02,2.48l-0.85,1.63l-1.3,-1.75l-0.58,-0.07l-4.87,4.19l-3.1,0.79l-3.16,-1.7l-0.85,-3.77l-0.77,-8.55l2.14,-2.31l6.55,-3.27l5.02,-4.17l10.63,-13.84l10.98,-8.7l5.35,-1.91l4.34,0.12l3.69,-3.64l4.49,0.19l4.37,-0.89ZM484.55,20.04l4.26,1.75l-3.1,2.55l-7.1,0.65l-7.08,-0.9l-0.37,-1.31l-0.37,-0.29l-3.44,-0.1l-2.08,-2.0l6.87,-1.44l3.9,1.31l2.39,-1.64l6.13,1.4ZM481.69,33.93l-4.45,1.74l-3.54,-0.99l1.12,-0.9l0.05,-0.58l-1.06,-1.22l4.22,-0.89l1.09,1.97l2.57,0.87ZM466.44,24.04l7.43,3.77l-5.41,1.86l-1.58,4.08l-2.26,1.2l-1.12,4.11l-2.61,0.18l-4.79,-2.86l1.84,-1.54l-0.1,-0.68l-3.69,-1.53l-4.77,-4.51l-1.73,-3.89l6.11,-1.82l1.54,1.92l3.57,-0.08l1.2,-1.96l3.32,-0.18l3.05,1.92Z", "name": "Norway"}, "NA": {"path": "M474.26,330.66l-0.97,0.04l-0.38,0.4l-0.07,8.9l-2.09,0.08l-0.39,0.4l-0.0,17.42l-1.98,1.23l-1.17,0.17l-2.44,-0.66l-0.48,-1.13l-0.99,-0.74l-0.54,0.05l-0.9,1.01l-1.53,-1.68l-0.93,-1.88l-1.99,-8.56l-0.06,-3.12l-0.33,-1.52l-2.3,-3.34l-1.91,-4.83l-1.96,-2.43l-0.12,-1.57l2.33,-0.79l1.43,0.07l1.81,1.13l10.23,-0.25l1.84,1.23l5.87,0.35ZM474.66,330.64l6.51,-1.6l1.9,0.39l-1.69,0.4l-1.31,0.83l-1.12,-0.94l-4.29,0.92Z", "name": "Namibia"}, "VU": {"path": "M839.04,322.8l0.22,1.14l-0.44,0.03l-0.2,-1.45l0.42,0.27Z", "name": "Vanuatu"}, "NC": {"path": "M838.78,341.24l-0.33,0.22l-2.9,-1.75l-3.26,-3.37l1.65,0.83l4.85,4.07Z", "name": "New Caledonia"}, "NE": {"path": "M454.75,226.53l1.33,1.37l0.48,0.07l1.27,-0.7l0.53,3.52l0.94,0.83l0.17,0.92l0.81,0.69l-0.44,0.95l-0.96,5.26l-0.13,3.22l-3.04,2.31l-1.22,3.57l1.02,1.24l-0.0,1.46l0.39,0.4l1.13,0.04l-0.9,1.25l-1.47,-2.42l-0.86,-0.29l-2.09,1.37l-1.74,-0.67l-1.45,-0.17l-0.85,0.35l-1.36,-0.07l-1.64,1.09l-1.06,0.05l-2.94,-1.28l-1.44,0.59l-1.01,-0.03l-0.97,-0.94l-2.7,-0.98l-2.69,0.3l-0.87,0.64l-0.47,1.6l-0.75,1.16l-0.12,1.53l-1.57,-1.1l-1.31,0.24l0.03,-0.81l-0.32,-0.41l-2.59,-0.52l-0.15,-1.16l-1.35,-1.6l-0.29,-1.0l0.13,-0.84l1.29,-0.08l1.08,-0.92l3.31,-0.22l2.22,-0.41l0.32,-0.34l0.2,-1.47l1.39,-1.88l-0.01,-5.66l3.36,-1.12l7.24,-5.12l8.42,-4.92l3.69,1.06Z", "name": "Niger"}, "NG": {"path": "M456.32,253.89l0.64,0.65l-0.28,1.04l-2.11,2.01l-2.03,5.18l-1.37,1.16l-1.15,3.18l-1.33,0.66l-1.46,-0.97l-1.21,0.16l-1.38,1.36l-0.91,0.24l-1.79,4.06l-2.33,0.81l-1.11,-0.07l-0.86,0.5l-1.71,-0.05l-1.19,-1.39l-0.89,-1.89l-1.77,-1.66l-3.95,-0.08l0.07,-5.21l0.42,-1.43l1.95,-2.3l-0.14,-0.91l0.43,-1.18l-0.53,-1.41l0.25,-2.92l0.72,-1.07l0.32,-1.34l0.46,-0.39l2.47,-0.28l2.34,0.89l1.15,1.02l1.28,0.04l1.22,-0.58l3.03,1.27l1.49,-0.14l1.36,-1.0l1.33,0.07l0.82,-0.35l3.45,0.8l1.82,-1.32l1.84,2.67l0.66,0.16Z", "name": "Nigeria"}, "NZ": {"path": "M857.8,379.65l1.86,3.12l0.44,0.18l0.3,-0.38l0.03,-1.23l0.38,0.27l0.57,2.31l2.02,0.94l1.81,0.27l1.57,-1.06l0.7,0.18l-1.15,3.59l-1.98,0.11l-0.74,1.2l0.2,1.11l-2.42,3.98l-1.49,0.92l-1.04,-0.85l1.21,-2.05l-0.81,-2.01l-2.63,-1.25l0.04,-0.57l1.82,-1.19l0.43,-2.34l-0.16,-2.03l-0.95,-1.82l-0.06,-0.72l-3.11,-3.64l-0.79,-1.52l1.56,1.45l1.76,0.66l0.65,2.34ZM853.83,393.59l0.57,1.24l0.59,0.16l1.42,-0.97l0.46,0.79l0.0,1.03l-2.47,3.48l-1.26,1.2l-0.06,0.5l0.55,0.87l-1.41,0.07l-2.33,1.38l-2.03,5.02l-3.02,2.16l-2.06,-0.06l-1.71,-1.04l-2.47,-0.2l-0.27,-0.73l1.22,-2.1l3.05,-2.94l1.62,-0.59l4.02,-2.82l1.57,-1.67l1.07,-2.16l0.88,-0.7l0.48,-1.75l1.24,-0.97l0.35,0.79Z", "name": "New Zealand"}, "NP": {"path": "M641.14,213.62l0.01,3.19l-1.74,0.04l-4.8,-0.86l-1.58,-1.39l-3.37,-0.34l-7.65,-3.7l0.8,-2.09l2.33,-1.7l1.77,0.75l2.49,1.76l1.38,0.41l0.99,1.35l1.9,0.52l1.99,1.17l5.49,0.9Z", "name": "Nepal"}, "XK": {"path": "M472.77,172.64l-1.08,-1.29l0.96,-0.77l0.29,-0.83l1.98,1.64l-0.36,0.67l-1.79,0.58Z", "name": "Kosovo"}, "CI": {"path": "M407.4,259.27l0.86,0.42l0.56,0.9l1.13,0.53l1.19,-0.61l0.97,-0.08l1.42,0.54l0.6,3.24l-1.03,2.08l-0.65,2.84l1.06,2.33l-0.06,0.53l-2.54,-0.47l-1.66,0.03l-3.06,0.46l-4.11,1.6l0.32,-3.06l-1.18,-1.31l-1.32,-0.66l0.42,-0.85l-0.2,-1.4l0.5,-0.67l0.01,-1.59l0.84,-0.32l0.26,-0.5l-1.15,-3.01l0.12,-0.5l0.51,-0.25l0.66,0.31l1.93,0.02l0.67,-0.71l0.71,-0.14l0.25,0.69l0.57,0.22l1.4,-0.61Z", "name": "C\u00f4te d'Ivoire"}, "CH": {"path": "M444.62,156.35l-0.29,0.87l0.18,0.53l1.13,0.58l1.0,0.1l-0.1,0.65l-0.79,0.38l-1.72,-0.37l-0.45,0.23l-0.45,1.04l-0.75,0.06l-0.84,-0.4l-1.32,1.0l-0.96,0.12l-0.88,-0.55l-0.81,-1.3l-0.49,-0.16l-0.63,0.26l0.02,-0.65l1.71,-1.66l0.1,-0.56l0.93,0.08l0.58,-0.46l1.99,0.02l0.66,-0.61l2.19,0.79Z", "name": "Switzerland"}, "CO": {"path": "M242.07,254.93l-1.7,0.59l-0.59,1.18l-1.7,1.69l-0.38,1.93l-0.67,1.43l0.31,0.57l1.03,0.13l0.25,0.9l0.57,0.64l-0.04,2.34l1.64,1.42l3.16,-0.24l1.26,0.28l1.67,2.06l0.41,0.13l4.09,-0.39l0.45,0.22l-0.92,1.95l-0.2,1.8l0.52,1.83l0.75,1.05l-1.12,1.1l0.07,0.63l0.84,0.51l0.74,1.29l-0.39,-0.45l-0.59,-0.01l-0.71,0.74l-4.71,-0.05l-0.4,0.41l0.03,1.57l0.33,0.39l1.11,0.2l-1.68,0.4l-0.29,0.38l-0.01,1.82l1.16,1.14l0.34,1.25l-1.05,7.05l-1.04,-0.87l1.26,-1.99l-0.13,-0.56l-2.18,-1.23l-1.38,0.2l-1.14,-0.38l-1.27,0.61l-1.55,-0.26l-1.38,-2.46l-1.23,-0.75l-0.85,-1.2l-1.67,-1.19l-0.86,0.13l-2.11,-1.32l-1.01,0.31l-1.8,-0.29l-0.52,-0.91l-3.09,-1.68l0.77,-0.52l-0.1,-1.12l0.41,-0.64l1.34,-0.32l2.0,-2.88l-0.11,-0.57l-0.66,-0.43l0.39,-1.38l-0.52,-2.1l0.49,-0.83l-0.4,-2.13l-0.97,-1.35l0.17,-0.66l0.86,-0.08l0.47,-0.75l-0.46,-1.63l1.41,-0.07l1.8,-1.69l0.93,-0.24l0.3,-0.38l0.45,-2.76l1.22,-1.0l1.44,-0.04l0.45,-0.5l1.91,0.12l2.93,-1.84l1.15,-1.14l0.91,0.46l-0.25,0.45Z", "name": "Colombia"}, "CN": {"path": "M740.23,148.97l4.57,1.3l2.8,2.17l0.98,2.9l0.38,0.27l3.8,0.0l2.32,-1.28l3.29,-0.75l-0.96,2.09l-1.02,1.28l-0.85,3.4l-1.52,2.73l-2.76,-0.5l-2.4,1.13l-0.21,0.45l0.64,2.57l-0.32,3.2l-0.94,0.06l-0.37,0.89l-0.91,-1.01l-0.64,0.07l-0.92,1.57l-3.73,1.25l-0.26,0.48l0.26,1.06l-1.5,-0.08l-1.09,-0.86l-0.56,0.06l-1.67,2.06l-2.7,1.56l-2.03,1.88l-3.4,0.83l-1.93,1.4l-1.15,0.34l0.33,-0.7l-0.41,-0.89l1.79,-1.79l0.02,-0.54l-1.32,-1.56l-0.48,-0.1l-2.24,1.09l-2.83,2.06l-1.51,1.83l-2.28,0.13l-1.55,1.49l-0.04,0.5l1.32,1.97l2.0,0.58l0.31,1.35l1.98,0.84l3.0,-1.96l2.0,1.02l1.49,0.11l0.22,0.83l-3.37,0.86l-1.12,1.48l-2.5,1.52l-1.29,1.99l0.14,0.56l2.57,1.48l0.97,2.7l3.17,4.63l-0.03,1.66l-1.35,0.65l-0.2,0.51l0.6,1.47l1.4,0.91l-0.89,3.82l-1.43,0.38l-3.85,6.44l-2.27,3.11l-6.78,4.57l-2.73,0.29l-1.45,1.04l-0.62,-0.61l-0.55,-0.01l-1.36,1.25l-3.39,1.27l-2.61,0.4l-1.1,2.79l-0.81,0.09l-0.49,-1.42l0.5,-0.85l-0.25,-0.59l-3.36,-0.84l-1.3,0.4l-2.31,-0.62l-0.94,-0.84l0.33,-1.28l-0.3,-0.49l-2.19,-0.46l-1.13,-0.93l-0.47,-0.02l-2.06,1.36l-4.29,0.28l-2.76,1.05l-0.28,0.43l0.32,2.53l-0.59,-0.03l-0.19,-1.34l-0.55,-0.34l-1.68,0.7l-2.46,-1.23l0.62,-1.87l-0.26,-0.51l-1.37,-0.44l-0.54,-2.22l-0.45,-0.3l-2.13,0.35l0.24,-2.48l2.39,-2.4l0.03,-4.31l-1.19,-0.92l-0.78,-1.49l-0.41,-0.21l-1.41,0.19l-1.98,-0.3l0.46,-1.07l-1.17,-1.7l-0.55,-0.11l-1.63,1.05l-2.25,-0.57l-2.89,1.73l-2.25,1.98l-1.75,0.29l-1.17,-0.71l-3.31,-0.65l-1.48,0.79l-1.04,1.27l-0.12,-1.17l-0.54,-0.34l-1.44,0.54l-5.55,-0.86l-1.98,-1.16l-1.89,-0.54l-0.99,-1.35l-1.34,-0.37l-2.55,-1.79l-2.01,-0.84l-1.21,0.56l-5.57,-3.45l-0.53,-2.31l1.19,0.25l0.48,-0.37l0.08,-1.42l-0.98,-1.56l0.15,-2.44l-2.69,-3.32l-4.12,-1.23l-0.67,-2.0l-1.92,-1.48l-0.38,-0.7l-0.51,-3.01l-1.52,-0.66l-0.7,0.13l-0.48,-2.05l0.55,-0.51l-0.09,-0.82l2.03,-1.19l1.6,-0.54l2.56,0.38l0.42,-0.22l0.85,-1.7l3.0,-0.33l1.1,-1.26l4.05,-1.77l0.39,-0.91l-0.17,-1.44l1.45,-0.67l0.2,-0.52l-2.07,-4.9l4.51,-1.12l1.37,-0.73l1.89,-5.51l4.98,0.86l1.51,-1.7l0.11,-2.87l1.99,-0.38l1.83,-2.06l0.49,-0.13l0.68,2.08l2.23,1.77l3.44,1.16l1.55,2.29l-0.92,3.49l0.96,1.67l6.54,1.13l2.95,1.87l1.47,0.35l1.06,2.62l1.53,1.91l3.05,0.08l5.14,0.67l3.37,-0.41l2.36,0.43l3.65,1.8l3.06,0.04l1.45,0.88l2.87,-1.59l3.95,-1.02l3.83,-0.14l3.06,-1.14l1.77,-1.6l1.72,-1.01l0.17,-0.49l-1.1,-2.05l1.02,-1.54l4.02,0.8l2.45,-1.61l3.76,-1.19l1.96,-2.13l1.63,-0.83l3.51,-0.4l1.92,0.34l0.46,-0.3l0.17,-1.5l-2.27,-2.22l-2.11,-1.09l-2.18,1.11l-2.32,-0.47l-1.29,0.32l-0.4,-0.82l2.73,-5.16l3.02,1.06l3.53,-2.06l0.18,-1.68l2.16,-3.35l1.49,-1.35l-0.03,-1.85l-1.07,-0.85l1.54,-1.26l2.98,-0.59l3.23,-0.09l3.64,0.99l2.04,1.16l3.29,6.71l0.92,3.19ZM696.92,237.31l-1.87,1.08l-1.63,-0.64l-0.06,-1.79l1.03,-0.98l2.58,-0.69l1.16,0.05l0.3,0.54l-0.98,1.06l-0.53,1.37Z", "name": "China"}, "CM": {"path": "M457.92,257.49l1.05,1.91l-1.4,0.16l-1.05,-0.23l-0.45,0.22l-0.54,1.19l0.08,0.45l1.48,1.47l1.05,0.45l1.01,2.46l-1.52,2.99l-0.68,0.68l-0.13,3.69l2.38,3.84l1.09,0.8l0.24,2.48l-3.67,-1.14l-11.27,-0.13l0.23,-1.79l-0.98,-1.66l-1.19,-0.54l-0.44,-0.97l-0.6,-0.42l1.71,-4.27l0.75,-0.13l1.38,-1.36l0.65,-0.03l1.71,0.99l1.93,-1.12l1.14,-3.18l1.38,-1.17l2.0,-5.14l2.17,-2.13l0.3,-1.64l-0.86,-0.88l0.03,-0.33l0.94,1.28l0.07,3.22Z", "name": "Cameroon"}, "CL": {"path": "M246.5,429.18l-3.14,1.83l-0.57,3.16l-0.64,0.05l-2.68,-1.06l-2.82,-2.33l-3.04,-1.89l-0.69,-1.85l0.63,-2.14l-1.21,-2.11l-0.31,-5.37l1.01,-2.91l2.57,-2.38l-0.18,-0.68l-3.16,-0.77l2.05,-2.47l0.77,-4.65l2.32,0.9l0.54,-0.29l1.31,-6.31l-0.22,-0.44l-1.68,-0.8l-0.56,0.28l-0.7,3.36l-0.81,-0.22l1.56,-9.41l1.15,-2.24l-0.71,-2.82l-0.18,-2.84l1.01,-0.33l3.26,-9.14l1.07,-4.22l-0.56,-4.21l0.74,-2.34l-0.29,-3.27l1.46,-3.34l2.04,-16.59l-0.66,-7.76l1.03,-0.53l0.54,-0.9l0.79,1.14l0.32,1.78l1.25,1.16l-0.69,2.55l1.33,2.9l0.97,3.59l0.46,0.29l1.5,-0.3l0.11,0.23l-0.76,2.44l-2.57,1.23l-0.23,0.37l0.08,4.33l-0.46,0.77l0.56,1.21l-1.58,1.51l-1.68,2.62l-0.89,2.47l0.2,2.7l-1.48,2.73l1.12,5.09l0.64,0.61l-0.01,2.29l-1.38,2.68l0.01,2.4l-1.89,2.04l0.02,2.75l0.69,2.57l-1.43,1.13l-1.26,5.68l0.39,3.51l-0.97,0.89l0.58,3.5l1.02,1.14l-0.65,1.02l0.15,0.57l1.0,0.53l0.16,0.69l-1.03,0.85l0.26,1.75l-0.89,4.03l-1.31,2.66l0.24,1.75l-0.71,1.83l-1.99,1.7l0.3,3.67l0.88,1.19l1.58,0.01l0.01,2.21l1.04,1.95l5.98,0.63ZM248.69,430.79l0.0,7.33l0.4,0.4l3.52,0.05l-0.44,0.75l-1.94,0.98l-2.49,-0.37l-1.88,-1.06l-2.55,-0.49l-5.59,-3.71l-2.38,-2.63l4.1,2.48l3.32,1.23l0.45,-0.12l1.29,-1.57l0.83,-2.32l2.05,-1.24l1.31,0.29Z", "name": "Chile"}, "XC": {"path": "M504.91,192.87l0.34,0.01l0.27,-0.07l-0.29,0.26l-0.31,-0.2Z", "name": "N. Cyprus"}, "CA": {"path": "M280.06,145.6l-1.67,2.88l0.07,0.49l0.5,0.04l1.46,-0.98l1.0,0.42l-0.56,0.72l0.17,0.62l2.22,0.89l1.35,-0.71l1.95,0.78l-0.66,2.01l0.5,0.51l1.32,-0.42l0.98,3.17l-0.91,2.41l-0.8,0.08l-1.23,-0.45l0.47,-2.25l-0.89,-0.83l-0.48,0.06l-2.78,2.63l-0.34,-0.02l1.02,-0.85l-0.14,-0.69l-2.4,-0.77l-7.4,0.08l-0.17,-0.41l1.3,-0.94l0.02,-0.64l-0.73,-0.58l1.85,-1.74l2.57,-5.16l1.47,-1.79l1.99,-1.05l0.46,0.06l-1.53,2.45ZM68.32,74.16l4.13,0.95l4.02,2.14l2.61,0.4l2.47,-1.89l2.88,-1.31l3.85,0.48l3.71,-1.94l3.82,-1.04l1.56,1.68l0.49,0.08l1.87,-1.04l0.65,-1.98l1.24,0.35l4.16,3.94l0.54,0.01l2.75,-2.49l0.26,2.59l0.49,0.35l3.08,-0.73l1.04,-1.27l2.73,0.23l3.83,1.86l5.86,1.61l3.47,0.75l2.44,-0.26l2.73,1.78l-2.98,1.81l-0.19,0.41l0.31,0.32l4.53,0.92l6.87,-0.5l2.0,-0.69l2.49,2.39l0.53,0.02l2.72,-2.16l-0.02,-0.64l-2.16,-1.54l1.15,-1.06l4.83,-0.61l1.84,0.95l2.48,2.31l3.01,-0.23l4.55,1.92l3.85,-0.67l3.61,0.1l0.41,-0.44l-0.25,-2.36l1.79,-0.61l3.49,1.32l-0.01,3.77l0.31,0.39l0.45,-0.22l1.48,-3.16l1.74,0.1l0.41,-0.3l1.13,-4.37l-2.78,-3.11l-2.8,-1.74l0.19,-4.64l2.71,-3.07l2.98,0.67l2.41,1.95l3.19,4.8l-1.99,1.97l0.21,0.68l4.33,0.84l-0.01,4.15l0.25,0.37l0.44,-0.09l3.07,-3.15l2.54,2.39l-0.61,3.33l2.42,2.88l0.61,0.0l2.61,-3.08l1.88,-3.82l0.17,-4.58l6.72,0.94l3.13,2.04l0.13,1.82l-1.76,2.19l-0.01,0.49l1.66,2.16l-0.26,1.71l-4.68,2.8l-3.28,0.61l-2.47,-1.2l-0.55,0.23l-0.73,2.04l-2.38,3.43l-0.74,1.77l-2.74,2.57l-3.44,0.25l-2.21,1.78l-0.28,2.53l-2.82,0.55l-3.12,3.22l-2.72,4.31l-1.03,3.17l-0.14,4.31l0.33,0.41l3.44,0.57l2.24,5.95l0.45,0.23l3.4,-0.69l4.52,1.51l2.43,1.31l1.91,1.73l3.1,0.96l2.62,1.46l6.6,0.54l-0.35,2.74l0.81,3.53l1.81,3.78l3.83,3.3l0.45,0.04l2.1,-1.28l1.37,-3.69l-1.31,-5.38l-1.45,-1.58l3.57,-1.47l2.84,-2.46l1.52,-2.8l-0.25,-2.55l-1.7,-3.07l-2.85,-2.61l2.8,-3.95l-1.08,-3.37l-0.79,-5.67l1.36,-0.7l6.76,1.41l2.12,-0.96l5.12,3.36l1.05,1.61l4.08,0.26l-0.06,2.87l0.83,4.7l0.3,0.32l2.16,0.54l1.73,2.06l0.5,0.09l3.63,-2.03l2.52,-4.19l1.26,-1.32l7.6,11.72l-0.92,2.04l0.16,0.51l3.3,1.97l2.22,1.98l4.1,0.98l1.43,0.99l0.95,2.79l2.1,0.68l0.84,1.08l0.17,3.45l-3.37,2.26l-4.22,1.24l-3.06,2.63l-4.06,0.51l-5.35,-0.69l-6.39,0.2l-2.3,2.41l-3.26,1.51l-6.47,7.15l-0.06,0.48l0.44,0.19l2.13,-0.52l4.17,-4.24l5.12,-2.62l3.52,-0.3l1.69,1.21l-2.12,2.21l0.81,3.47l1.02,2.61l3.47,1.6l4.14,-0.45l2.15,-2.8l0.26,1.48l1.14,0.8l-2.56,1.69l-5.5,1.82l-2.54,1.27l-2.74,2.15l-1.4,-0.16l-0.07,-2.01l4.14,-2.44l0.18,-0.45l-0.39,-0.29l-6.63,0.45l-1.39,-1.49l-0.14,-4.43l-1.11,-0.91l-1.82,0.39l-0.66,-0.66l-0.6,0.03l-1.91,2.39l-0.82,2.52l-0.8,1.27l-1.67,0.56l-0.46,0.76l-8.31,0.07l-1.21,0.62l-2.35,1.97l-0.71,-0.14l-1.37,0.96l-1.12,-0.48l-4.74,1.26l-0.9,1.17l0.21,0.62l1.73,0.3l-1.81,0.31l-1.85,0.81l-2.11,-0.13l-2.95,1.78l-0.69,-0.09l1.39,-2.1l1.73,-1.21l0.1,-2.29l1.16,-1.99l0.49,0.53l2.03,0.42l1.2,-1.16l0.02,-0.47l-2.66,-3.51l-2.28,-0.61l-5.64,-0.71l-0.4,-0.57l-0.79,0.13l0.2,-0.41l-0.22,-0.55l-0.68,-0.26l0.19,-1.26l-0.78,-0.73l0.31,-0.64l-0.29,-0.57l-2.6,-0.44l-0.75,-1.63l-0.94,-0.66l-4.31,-0.65l-1.13,1.19l-1.48,0.59l-0.85,1.06l-2.83,-0.76l-2.09,0.39l-2.39,-0.97l-4.24,-0.7l-0.57,-0.4l-0.41,-1.63l-0.4,-0.3l-0.85,0.02l-0.39,0.4l-0.01,0.85l-69.13,-0.01l-6.51,-4.52l-4.5,-1.38l-1.26,-2.66l0.33,-1.93l-0.23,-0.43l-3.01,-1.35l-0.55,-2.77l-2.89,-2.38l-0.04,-1.45l1.39,-1.83l-0.28,-2.55l-4.16,-2.2l-4.07,-6.6l-4.02,-3.22l-1.3,-1.88l-0.5,-0.13l-2.51,1.21l-2.23,1.87l-3.85,-3.88l-2.44,-1.04l-2.22,-0.13l0.03,-37.49ZM260.37,148.65l3.04,0.76l2.26,1.2l-3.78,-0.95l-1.53,-1.01ZM249.4,3.81l6.68,0.49l5.32,0.79l4.26,1.57l-0.07,1.1l-5.85,2.53l-6.02,1.21l-2.39,1.39l-0.18,0.45l0.39,0.29l4.01,-0.02l-4.65,2.82l-4.2,1.74l-4.19,4.59l-5.03,0.92l-1.67,1.15l-7.47,0.59l-0.37,0.37l0.32,0.42l2.41,0.49l-0.81,0.47l-0.12,0.59l1.83,2.41l-2.02,1.59l-3.81,1.51l-1.32,2.16l-3.38,1.53l-0.22,0.48l0.35,1.19l0.4,0.29l3.88,-0.18l0.03,0.61l-6.33,2.95l-6.41,-1.4l-7.43,0.79l-3.72,-0.62l-4.4,-0.25l-0.23,-1.83l4.29,-1.11l0.28,-0.51l-1.1,-3.45l1.0,-0.25l6.58,2.28l0.47,-0.16l-0.05,-0.49l-3.41,-3.45l-3.58,-0.98l1.48,-1.55l4.34,-1.29l0.97,-2.19l-0.16,-0.48l-3.42,-2.13l-0.81,-2.26l6.2,0.22l2.24,0.58l3.91,-2.1l0.2,-0.43l-0.35,-0.32l-5.64,-0.67l-8.73,0.36l-4.26,-1.9l-2.12,-2.4l-2.78,-1.66l-0.41,-1.52l3.31,-1.03l2.93,-0.2l4.91,-0.99l3.7,-2.27l2.87,0.3l2.62,1.67l0.56,-0.14l1.82,-3.2l3.13,-0.94l4.44,-0.69l7.53,-0.26l1.48,0.67l7.19,-1.06l10.8,0.79ZM203.85,57.54l0.01,0.42l1.97,2.97l0.68,-0.02l2.24,-3.72l5.95,-1.86l4.01,4.64l-0.35,2.91l0.5,0.43l4.95,-1.36l2.32,-1.8l5.31,2.28l3.27,2.11l0.3,1.84l0.48,0.33l4.42,-0.99l2.64,2.87l5.97,1.77l2.06,1.72l2.11,3.71l-4.19,1.86l-0.01,0.73l5.9,2.83l3.94,0.94l3.78,3.95l3.46,0.25l-0.63,2.37l-4.11,4.47l-2.76,-1.56l-3.9,-3.94l-3.59,0.41l-0.33,0.34l-0.19,2.72l2.63,2.38l3.42,1.89l0.94,0.97l1.55,3.75l-0.7,2.29l-2.74,-0.92l-6.25,-3.15l-0.51,0.13l0.05,0.52l6.07,5.69l0.18,0.59l-6.09,-1.39l-5.31,-2.24l-2.63,-1.66l0.6,-0.77l-0.12,-0.6l-7.39,-4.01l-0.59,0.37l0.03,0.79l-6.73,0.6l-1.69,-1.1l1.36,-2.46l4.51,-0.07l5.15,-0.52l0.31,-0.6l-0.74,-1.3l0.78,-1.84l3.21,-4.05l-0.67,-2.35l-1.11,-1.6l-3.84,-2.1l-4.35,-1.28l0.91,-0.63l0.06,-0.61l-2.65,-2.75l-2.34,-0.36l-1.89,-1.46l-0.53,0.03l-1.24,1.23l-4.36,0.55l-9.04,-0.99l-9.26,-1.98l-1.6,-1.22l2.22,-1.77l0.13,-0.44l-0.38,-0.27l-3.22,-0.02l-0.72,-4.25l1.83,-4.04l2.42,-1.85l5.5,-1.1l-1.39,2.35ZM261.19,159.33l2.07,0.61l1.44,-0.04l-1.15,0.63l-2.94,-1.23l-0.4,-0.68l0.36,-0.37l0.61,1.07ZM230.83,84.39l-2.37,0.18l-0.49,-1.63l0.93,-2.09l1.94,-0.51l1.62,0.99l0.02,1.52l-1.66,1.54ZM229.43,58.25l0.11,0.65l-4.87,-0.21l-2.72,0.62l-3.1,-2.57l0.08,-1.26l0.86,-0.23l5.57,0.51l4.08,2.5ZM222.0,105.02l-0.72,1.49l-0.63,-0.19l-0.48,-0.84l0.81,-0.99l0.65,0.05l0.37,0.46ZM183.74,38.32l2.9,1.7l4.79,-0.01l1.84,1.46l-0.49,1.68l0.23,0.48l2.82,1.14l1.76,1.26l7.01,0.65l4.1,-1.1l5.03,-0.43l3.93,0.35l2.48,1.77l0.46,1.7l-1.3,1.1l-3.56,1.01l-3.23,-0.59l-7.17,0.76l-5.09,0.09l-3.99,-0.6l-6.42,-1.54l-0.79,-2.51l-0.3,-2.49l-2.64,-2.5l-5.32,-0.72l-2.52,-1.4l0.68,-1.57l4.78,0.31ZM207.38,91.35l0.4,1.56l0.56,0.26l1.06,-0.52l1.32,0.96l5.42,2.57l0.2,1.68l0.46,0.35l1.68,-0.28l1.15,0.85l-1.55,0.87l-3.61,-0.88l-1.32,-1.69l-0.57,-0.06l-2.45,2.1l-3.12,1.79l-0.7,-1.87l-0.42,-0.26l-2.16,0.24l1.39,-1.39l0.32,-3.14l0.76,-3.35l1.18,0.22ZM215.49,102.6l-2.67,1.95l-1.4,-0.07l-0.3,-0.58l1.53,-1.48l2.84,0.18ZM202.7,24.12l2.53,1.59l-2.87,1.4l-4.53,4.05l-4.25,0.38l-5.03,-0.68l-2.45,-2.04l0.03,-1.62l1.82,-1.37l0.14,-0.45l-0.38,-0.27l-4.45,0.04l-2.59,-1.76l-1.41,-2.29l1.57,-2.32l1.62,-1.66l2.44,-0.39l0.25,-0.65l-0.6,-0.74l4.86,-0.25l3.24,3.11l8.16,2.3l1.9,3.61ZM187.47,59.2l-2.76,3.49l-2.38,-0.15l-1.44,-3.84l0.04,-2.2l1.19,-1.88l2.3,-1.23l5.07,0.17l4.11,1.02l-3.24,3.72l-2.88,0.89ZM186.07,48.79l-1.08,1.53l-3.34,-0.34l-2.56,-1.1l1.03,-1.75l3.25,-1.23l1.95,1.58l0.75,1.3ZM185.71,35.32l-5.3,-0.2l-0.32,-0.71l4.31,0.07l1.3,0.84ZM180.68,32.48l-3.34,1.0l-1.79,-1.1l-0.98,-1.87l-0.15,-1.73l4.1,0.53l2.67,1.7l-0.51,1.47ZM180.9,76.31l-1.1,1.08l-3.13,-1.23l-2.12,0.43l-2.71,-1.57l1.72,-1.09l1.55,-1.72l3.81,1.9l1.98,2.2ZM169.74,54.87l2.96,0.97l4.17,-0.57l0.41,0.88l-2.14,2.11l0.09,0.64l3.55,1.92l-0.4,3.72l-3.79,1.65l-2.17,-0.35l-1.72,-1.74l-6.02,-3.5l0.03,-0.85l4.68,0.54l0.4,-0.21l-0.05,-0.45l-2.48,-2.81l2.46,-1.95ZM174.45,40.74l1.37,1.73l0.07,2.44l-1.05,3.45l-3.79,0.47l-2.32,-0.69l0.05,-2.64l-0.44,-0.41l-3.68,0.35l-0.12,-3.1l2.45,0.1l3.67,-1.73l3.41,0.29l0.37,-0.26ZM170.05,31.55l0.67,1.56l-3.33,-0.49l-4.22,-1.77l-4.35,-0.16l1.4,-0.94l-0.06,-0.7l-2.81,-1.23l-0.12,-1.39l4.39,0.68l6.62,1.98l1.81,2.47ZM134.5,58.13l-1.02,1.82l0.45,0.58l5.4,-1.39l3.33,2.29l0.49,-0.03l2.6,-2.23l1.94,1.32l2.0,4.5l0.7,0.06l1.3,-2.29l-1.63,-4.46l1.69,-0.54l2.31,0.71l2.65,1.81l2.49,7.92l8.48,4.27l-0.19,1.35l-3.79,0.33l-0.26,0.67l1.4,1.49l-0.58,1.1l-4.23,-0.64l-4.43,-1.19l-3.0,0.28l-4.66,1.47l-10.52,1.04l-1.43,-2.02l-3.42,-1.2l-2.21,0.43l-2.51,-2.86l4.84,-1.05l3.6,0.19l3.27,-0.78l0.31,-0.39l-0.31,-0.39l-4.84,-1.06l-8.79,0.27l-0.85,-1.07l5.26,-1.66l0.27,-0.45l-0.4,-0.34l-3.8,0.06l-3.81,-1.06l1.81,-3.01l1.66,-1.79l6.48,-2.81l1.97,0.71ZM158.7,56.61l-1.7,2.44l-3.2,-2.75l0.37,-0.3l3.11,-0.18l1.42,0.79ZM149.61,42.73l1.01,1.89l0.5,0.18l2.14,-0.82l2.23,0.19l0.36,2.04l-1.33,2.09l-8.28,0.76l-6.35,2.15l-3.41,0.1l-0.19,-0.96l4.9,-2.08l0.23,-0.46l-0.41,-0.31l-11.25,0.59l-2.89,-0.74l3.04,-4.44l2.14,-1.32l6.81,1.69l4.58,3.06l4.37,0.39l0.36,-0.63l-3.36,-4.6l1.85,-1.53l2.18,0.51l0.77,2.26ZM144.76,34.41l-4.36,1.44l-3.0,-1.4l1.46,-1.24l3.47,-0.52l2.96,0.71l-0.52,1.01ZM145.13,29.83l-1.9,0.66l-3.67,-0.0l2.27,-1.61l3.3,0.95ZM118.92,65.79l-6.03,2.02l-1.33,-1.9l-5.38,-2.28l2.59,-5.05l2.16,-3.14l-0.02,-0.48l-1.97,-2.41l7.64,-0.7l3.6,1.02l6.3,0.27l4.42,2.95l-2.53,0.98l-6.24,3.43l-3.1,3.28l-0.11,2.01ZM129.54,35.53l-0.28,3.37l-1.72,1.62l-2.33,0.28l-4.61,2.19l-3.86,0.76l-2.64,-0.87l3.72,-3.4l5.01,-3.34l3.72,0.07l3.0,-0.67ZM111.09,152.69l-0.67,0.24l-3.85,-1.37l-0.83,-1.17l-2.12,-1.07l-0.66,-1.02l-2.4,-0.55l-0.74,-1.71l6.02,1.45l2.0,2.55l2.52,1.39l0.73,1.27ZM87.8,134.64l0.89,0.29l1.86,-0.21l-0.65,3.34l1.69,2.33l-1.31,-1.33l-0.99,-1.62l-1.17,-0.98l-0.33,-1.82Z", "name": "Canada"}, "CG": {"path": "M466.72,276.48l-0.1,1.03l-1.25,2.97l-0.19,3.62l-0.46,1.78l-0.23,0.63l-1.61,1.19l-1.21,1.39l-1.09,2.43l0.04,2.09l-3.25,3.24l-0.5,-0.24l-0.5,-0.83l-1.36,-0.02l-0.98,0.89l-1.68,-0.99l-1.54,1.24l-1.52,-1.96l1.57,-1.14l0.11,-0.52l-0.77,-1.35l2.1,-0.66l0.39,-0.73l1.05,0.82l2.21,0.11l1.12,-1.37l0.37,-1.81l-0.27,-2.09l-1.13,-1.5l1.0,-2.69l-0.13,-0.45l-0.92,-0.58l-1.6,0.17l-0.51,-0.94l0.1,-0.61l2.75,0.09l3.97,1.24l0.51,-0.33l0.17,-1.28l1.24,-2.21l1.28,-1.14l2.76,0.49Z", "name": "Congo"}, "CF": {"path": "M461.16,278.2l-0.26,-1.19l-1.09,-0.77l-0.84,-1.17l-0.29,-1.0l-1.04,-1.15l0.08,-3.43l0.58,-0.49l1.16,-2.35l1.85,-0.17l0.61,-0.62l0.97,0.58l3.15,-0.96l2.48,-1.92l0.02,-0.96l2.81,0.02l2.36,-1.17l1.93,-2.85l1.16,-0.93l1.11,-0.3l0.27,0.86l1.34,1.47l-0.39,2.01l0.3,1.01l4.01,2.75l0.17,0.93l2.63,2.31l0.6,1.44l2.08,1.4l-3.84,-0.21l-1.94,0.88l-1.23,-0.49l-2.67,1.2l-1.29,-0.18l-0.51,0.36l-0.6,1.22l-3.35,-0.65l-1.57,-0.91l-2.42,-0.83l-1.45,0.91l-0.97,1.27l-0.26,1.56l-3.22,-0.43l-1.49,1.33l-0.94,1.62Z", "name": "Central African Rep."}, "CD": {"path": "M487.01,272.38l2.34,-0.14l1.35,1.84l1.34,0.45l0.86,-0.39l1.21,0.12l1.07,-0.41l0.54,0.89l2.04,1.54l-0.14,2.72l0.7,0.54l-1.38,1.13l-1.53,2.54l-0.17,2.05l-0.59,1.08l-0.02,1.72l-0.72,0.84l-0.66,3.01l0.63,1.32l-0.44,4.26l0.64,1.47l-0.37,1.22l0.86,1.8l1.53,1.41l0.3,1.26l0.44,0.5l-4.08,0.75l-0.92,1.81l0.51,1.34l-0.74,5.43l0.17,0.38l2.45,1.46l0.54,-0.1l0.12,1.62l-1.28,-0.01l-1.85,-2.35l-1.94,-0.45l-0.48,-1.13l-0.55,-0.2l-1.41,0.74l-1.71,-0.3l-1.01,-1.18l-2.49,-0.19l-0.44,-0.77l-1.98,-0.21l-2.88,0.36l0.11,-2.41l-0.85,-1.13l-0.16,-1.36l0.32,-1.73l-0.46,-0.89l-0.04,-1.49l-0.4,-0.39l-2.53,0.02l0.1,-0.41l-0.39,-0.49l-1.28,0.01l-0.43,0.45l-1.62,0.32l-0.83,1.79l-1.09,-0.28l-2.4,0.52l-1.37,-1.91l-1.3,-3.3l-0.38,-0.27l-7.39,-0.03l-2.46,0.42l0.5,-0.45l0.37,-1.47l0.66,-0.38l0.92,0.08l0.73,-0.82l0.87,0.02l0.31,0.68l1.4,0.36l3.59,-3.63l0.01,-2.23l1.02,-2.29l2.69,-2.39l0.43,-0.99l0.49,-1.96l0.17,-3.51l1.25,-2.95l0.36,-3.14l0.86,-1.13l1.1,-0.66l3.57,1.73l3.65,0.73l0.46,-0.21l0.8,-1.46l1.24,0.19l2.61,-1.17l0.81,0.44l1.04,-0.03l0.59,-0.66l0.7,-0.16l1.81,0.25Z", "name": "Dem. Rep. Congo"}, "CZ": {"path": "M458.46,144.88l1.22,1.01l1.47,0.23l0.13,0.93l1.36,0.68l0.54,-0.2l0.24,-0.55l1.15,0.25l0.53,1.09l1.68,0.18l0.6,0.84l-1.04,0.73l-0.96,1.28l-1.6,0.17l-0.55,0.56l-1.04,-0.46l-1.05,0.15l-2.12,-0.96l-1.05,0.34l-1.2,1.12l-1.56,-0.87l-2.57,-2.1l-0.53,-1.88l4.7,-2.52l0.71,0.26l0.9,-0.28Z", "name": "Czech Rep."}, "CY": {"path": "M504.36,193.47l0.43,0.28l-1.28,0.57l-0.92,-0.28l-0.24,-0.46l2.01,-0.13Z", "name": "Cyprus"}, "CR": {"path": "M211.34,258.05l0.48,0.99l1.6,1.6l-0.54,0.45l0.29,1.42l-0.25,1.19l-1.09,-0.59l-0.05,-1.25l-2.46,-1.42l-0.28,-0.77l-0.66,-0.45l-0.45,-0.0l-0.11,1.04l-1.32,-0.95l0.31,-1.3l-0.36,-0.6l0.31,-0.27l1.42,0.58l1.29,-0.14l0.56,0.56l0.74,0.17l0.55,-0.27Z", "name": "Costa Rica"}, "CU": {"path": "M221.21,227.25l1.27,1.02l2.19,-0.28l4.43,3.33l2.08,0.43l-0.1,0.38l0.36,0.5l1.75,0.1l1.48,0.84l-3.11,0.51l-4.15,-0.03l0.77,-0.67l-0.04,-0.64l-1.2,-0.74l-1.49,-0.16l-0.7,-0.61l-0.56,-1.4l-0.4,-0.25l-1.34,0.1l-2.2,-0.66l-0.88,-0.58l-3.18,-0.4l-0.27,-0.16l0.58,-0.74l-0.36,-0.29l-2.72,-0.05l-1.7,1.29l-0.91,0.03l-0.61,0.69l-1.01,0.22l1.11,-1.29l1.01,-0.52l3.69,-1.01l3.98,0.21l2.21,0.84Z", "name": "Cuba"}, "SZ": {"path": "M500.35,351.36l0.5,2.04l-0.38,0.89l-1.05,0.21l-1.23,-1.2l-0.02,-0.64l0.83,-1.57l1.34,0.27Z", "name": "Swaziland"}, "SY": {"path": "M511.0,199.79l0.05,-1.33l0.54,-1.36l1.28,-0.99l0.13,-0.45l-0.41,-1.11l-1.14,-0.36l-0.19,-1.74l0.52,-1.0l1.29,-1.21l0.2,-1.18l0.59,0.23l2.62,-0.76l1.36,0.52l2.06,-0.01l2.95,-1.08l3.25,-0.26l-0.67,0.94l-1.28,0.66l-0.21,0.4l0.23,2.01l-0.88,3.19l-10.15,5.73l-2.15,-0.85Z", "name": "Syria"}, "KG": {"path": "M621.35,172.32l-3.87,1.69l-0.96,1.18l-3.04,0.34l-1.13,1.86l-2.36,-0.35l-1.99,0.63l-2.39,1.4l0.06,0.95l-0.4,0.37l-4.52,0.43l-3.02,-0.93l-2.37,0.17l0.11,-0.79l2.32,0.42l1.13,-0.88l1.99,0.2l3.21,-2.14l-0.03,-0.69l-2.97,-1.57l-1.94,0.65l-1.22,-0.74l1.71,-1.58l-0.12,-0.67l-0.36,-0.15l0.32,-0.77l1.36,-0.35l4.02,1.02l0.49,-0.3l0.35,-1.59l1.09,-0.48l3.42,1.22l1.11,-0.31l7.64,0.39l1.16,1.0l1.23,0.39Z", "name": "Kyrgyzstan"}, "KE": {"path": "M506.26,284.69l1.87,-2.56l0.93,-2.15l-1.38,-4.08l-1.06,-1.6l2.82,-2.75l0.79,0.26l0.12,1.41l0.86,0.83l1.9,0.11l3.28,2.13l3.57,0.44l1.05,-1.12l1.96,-0.9l0.82,0.68l1.16,0.09l-1.78,2.45l0.03,9.12l1.3,1.94l-1.37,0.78l-0.67,1.03l-1.08,0.46l-0.34,1.67l-0.81,1.07l-0.45,1.55l-0.68,0.56l-3.2,-2.23l-0.35,-1.58l-8.86,-4.98l0.14,-1.6l-0.57,-1.04Z", "name": "Kenya"}, "SS": {"path": "M481.71,263.34l1.07,-0.72l1.2,-3.18l1.36,-0.26l1.61,1.99l0.87,0.34l1.1,-0.41l1.5,0.07l0.57,0.53l2.49,0.0l0.44,-0.63l1.07,-0.4l0.45,-0.84l0.59,-0.33l1.9,1.33l1.6,-0.2l2.83,-3.33l-0.32,-2.21l1.59,-0.52l-0.24,1.6l0.3,1.83l1.35,1.18l0.2,1.87l0.35,0.41l0.02,1.53l-0.23,0.47l-1.42,0.25l-0.85,1.44l0.3,0.6l1.4,0.16l1.11,1.08l0.59,1.13l1.03,0.53l1.28,2.36l-4.41,3.98l-1.74,0.01l-1.89,0.55l-1.47,-0.52l-1.15,0.57l-2.96,-2.62l-1.3,0.49l-1.06,-0.15l-0.79,0.39l-0.82,-0.22l-1.8,-2.7l-1.91,-1.1l-0.66,-1.5l-2.62,-2.32l-0.18,-0.94l-2.37,-1.6Z", "name": "S. Sudan"}, "SR": {"path": "M283.12,270.19l2.1,0.53l-1.08,1.95l0.2,1.72l0.93,1.49l-0.59,2.03l-0.43,0.71l-1.12,-0.42l-1.32,0.22l-0.93,-0.2l-0.46,0.26l-0.25,0.73l0.33,0.7l-0.89,-0.13l-1.39,-1.97l-0.31,-1.34l-0.97,-0.31l-0.89,-1.47l0.35,-1.61l1.45,-0.82l0.33,-1.87l2.61,0.44l0.57,-0.47l1.75,-0.16Z", "name": "Suriname"}, "KH": {"path": "M689.52,249.39l0.49,1.45l-0.28,2.74l-4.0,1.86l-0.16,0.6l0.68,0.95l-2.06,0.17l-2.05,0.97l-1.82,-0.32l-2.12,-3.7l-0.55,-2.85l1.4,-1.85l3.02,-0.45l2.23,0.35l2.01,0.98l0.51,-0.14l0.95,-1.48l1.74,0.74Z", "name": "Cambodia"}, "SV": {"path": "M195.8,250.13l1.4,-1.19l2.24,1.45l0.98,-0.27l0.44,0.2l-0.27,1.05l-1.14,-0.03l-3.64,-1.21Z", "name": "El Salvador"}, "SK": {"path": "M476.82,151.17l-1.14,1.9l-2.73,-0.92l-0.82,0.2l-0.74,0.8l-3.46,0.73l-0.47,0.69l-1.76,0.33l-1.88,-1.0l-0.18,-0.81l0.38,-0.75l1.87,-0.32l1.74,-1.89l0.83,0.16l0.79,-0.34l1.51,1.04l1.34,-0.63l1.25,0.3l1.65,-0.42l1.81,0.95Z", "name": "Slovakia"}, "KR": {"path": "M737.51,185.84l0.98,-0.1l0.87,-1.17l2.69,-0.32l0.33,-0.29l1.76,2.79l0.58,1.76l0.02,3.12l-0.8,1.32l-2.21,0.55l-1.93,1.13l-1.8,0.19l-0.2,-1.1l0.43,-2.28l-0.95,-2.56l1.43,-0.37l0.23,-0.62l-1.43,-2.06Z", "name": "Korea"}, "SI": {"path": "M456.18,162.07l-0.51,-1.32l0.18,-1.05l1.69,0.2l1.42,-0.71l2.09,-0.07l0.62,-0.51l0.21,0.47l-1.61,0.67l-0.44,1.34l-0.66,0.24l-0.26,0.82l-1.22,-0.49l-0.84,0.46l-0.69,-0.04Z", "name": "Slovenia"}, "KP": {"path": "M736.77,185.16l-0.92,-0.42l-0.88,0.62l-1.21,-0.88l0.96,-1.15l0.59,-2.59l-0.46,-0.74l-2.09,-0.77l1.64,-1.52l2.72,-1.58l1.58,-1.91l1.11,0.78l2.17,0.11l0.41,-0.5l-0.3,-1.22l3.52,-1.18l0.94,-1.4l0.98,1.08l-2.19,2.18l0.01,2.14l-1.06,0.54l-1.41,1.4l-1.7,0.52l-1.25,1.09l-0.14,1.98l0.94,0.45l1.15,1.04l-0.13,0.26l-2.6,0.29l-1.13,1.29l-1.22,0.08Z", "name": "Dem. Rep. Korea"}, "KW": {"path": "M540.81,207.91l0.37,0.86l-0.17,0.76l0.6,1.53l-0.95,0.04l-0.82,-1.28l-1.57,-0.18l1.31,-1.88l1.22,0.17Z", "name": "Kuwait"}, "SN": {"path": "M390.09,248.21l0.12,1.55l0.49,1.46l0.96,0.82l0.05,1.28l-1.26,-0.19l-0.75,0.33l-1.84,-0.61l-5.84,-0.13l-2.54,0.51l-0.22,-1.03l1.77,0.04l2.01,-0.91l1.03,0.48l1.09,0.04l1.29,-0.62l0.14,-0.58l-0.51,-0.74l-1.81,0.25l-1.13,-0.63l-0.79,0.04l-0.72,0.61l-2.31,0.06l-0.92,-1.77l-0.81,-0.64l0.64,-0.35l2.46,-3.74l1.04,0.19l1.38,-0.56l1.19,-0.02l2.72,1.37l3.03,3.48Z", "name": "Senegal"}, "SL": {"path": "M394.46,264.11l-1.73,1.98l-0.58,1.33l-2.07,-1.06l-1.22,-1.26l-0.65,-2.39l1.16,-0.96l0.67,-1.17l1.21,-0.52l1.66,0.0l1.03,1.64l0.52,2.41Z", "name": "Sierra Leone"}, "KZ": {"path": "M552.8,172.89l0.46,-1.27l-0.48,-1.05l-2.96,-1.19l-1.06,-2.58l-1.37,-0.87l-0.03,-0.3l1.95,0.23l0.45,-0.38l0.08,-1.96l1.75,-0.41l2.1,0.45l0.48,-0.33l0.45,-3.04l-0.45,-2.09l-0.41,-0.31l-2.42,0.15l-2.36,-0.73l-2.87,1.37l-2.17,0.61l-0.85,-0.34l0.13,-1.61l-1.6,-2.12l-2.02,-0.08l-1.78,-1.82l1.29,-2.18l-0.57,-0.95l1.62,-2.91l2.21,1.63l0.63,-0.27l0.29,-2.22l4.92,-3.43l3.71,-0.08l8.4,3.6l2.92,-1.36l3.77,-0.06l3.11,1.66l0.51,-0.11l0.6,-0.81l3.31,0.13l0.39,-0.25l0.63,-1.57l-0.17,-0.5l-3.5,-1.98l1.87,-1.27l-0.13,-1.03l1.98,-0.72l0.18,-0.62l-1.59,-2.06l0.81,-0.82l9.23,-1.18l1.33,-0.88l6.18,-1.26l2.26,-1.42l4.08,0.68l0.73,3.33l0.51,0.3l2.48,-0.8l2.79,1.02l-0.17,1.56l0.43,0.44l2.55,-0.24l4.89,-2.53l0.03,0.32l3.15,2.61l5.56,8.47l0.65,0.02l1.12,-1.46l3.15,1.74l3.76,-0.78l1.15,0.49l1.14,1.8l1.84,0.76l0.99,1.29l3.35,-0.25l1.02,1.52l-1.6,1.81l-1.93,0.28l-0.34,0.38l-0.11,3.05l-1.13,1.16l-4.75,-1.0l-0.46,0.27l-1.76,5.47l-1.1,0.59l-4.91,1.23l-0.27,0.54l2.1,4.97l-1.37,0.63l-0.23,0.41l0.13,1.13l-0.88,-0.25l-1.42,-1.13l-7.89,-0.4l-0.92,0.31l-3.73,-1.22l-1.42,0.63l-0.53,1.66l-3.72,-0.94l-1.85,0.43l-0.76,1.4l-4.65,2.62l-1.13,2.08l-0.44,0.01l-0.92,-1.4l-2.87,-0.09l-0.45,-2.14l-0.38,-0.32l-0.8,-0.01l0.0,-2.96l-3.0,-2.22l-7.31,0.58l-2.35,-2.68l-6.71,-3.69l-6.45,1.83l-0.29,0.39l0.1,10.85l-0.7,0.08l-1.62,-2.17l-1.83,-0.96l-3.11,0.59l-0.64,0.51Z", "name": "Kazakhstan"}, "SA": {"path": "M537.53,210.34l2.0,0.24l0.9,1.32l1.49,-0.06l0.87,2.08l1.29,0.76l0.51,0.99l1.56,1.03l-0.1,1.9l0.32,0.9l1.58,2.47l0.76,0.53l0.7,-0.04l1.68,4.23l7.53,1.33l0.51,-0.29l0.77,1.25l-1.55,4.87l-7.29,2.52l-7.3,1.03l-2.34,1.17l-1.88,2.74l-0.76,0.28l-0.82,-0.78l-0.91,0.12l-2.88,-0.51l-3.51,0.25l-0.86,-0.56l-0.57,0.15l-0.66,1.27l0.16,1.11l-0.43,0.32l-0.93,-1.4l-0.33,-1.16l-1.23,-0.88l-1.27,-2.06l-0.78,-2.22l-1.73,-1.79l-1.14,-0.48l-1.54,-2.31l-0.21,-3.41l-1.44,-2.93l-1.27,-1.16l-1.33,-0.57l-1.31,-3.37l-0.77,-0.67l-0.97,-1.97l-2.8,-4.03l-1.06,-0.17l0.37,-1.96l0.2,-0.72l2.74,0.3l1.08,-0.84l0.6,-0.94l1.74,-0.35l0.65,-1.03l0.71,-0.4l0.1,-0.62l-2.06,-2.28l4.39,-1.22l0.48,-0.37l2.77,0.69l3.66,1.9l7.03,5.5l4.87,0.3Z", "name": "Saudi Arabia"}, "SE": {"path": "M480.22,89.3l-4.03,1.17l-2.43,2.86l0.26,2.57l-8.77,6.64l-1.78,5.79l1.78,2.68l2.22,1.96l-2.07,3.77l-2.72,1.13l-0.95,6.04l-1.29,3.01l-2.74,-0.31l-0.4,0.22l-1.31,2.59l-2.34,0.13l-0.75,-3.09l-2.08,-4.03l-1.83,-4.96l1.0,-1.93l2.14,-2.7l0.83,-4.45l-1.6,-2.17l-0.15,-4.94l1.48,-3.39l2.58,-0.15l0.87,-1.59l-0.78,-1.57l3.76,-5.59l4.04,-7.48l2.17,0.01l0.39,-0.29l0.57,-2.07l4.37,0.64l0.46,-0.34l0.33,-2.56l1.1,-0.13l6.94,4.87l0.06,6.32l0.66,1.36Z", "name": "Sweden"}, "SD": {"path": "M505.98,259.4l-0.34,-0.77l-1.17,-0.9l-0.26,-1.61l0.29,-1.81l-0.34,-0.46l-1.16,-0.17l-0.54,0.59l-1.23,0.11l-0.28,0.65l0.53,0.65l0.17,1.22l-2.44,3.0l-0.96,0.19l-2.39,-1.4l-0.95,0.52l-0.38,0.78l-1.11,0.41l-0.29,0.5l-1.94,0.0l-0.54,-0.52l-1.81,-0.09l-0.95,0.4l-2.45,-2.35l-2.07,0.54l-0.73,1.26l-0.6,2.1l-1.25,0.58l-0.75,-0.62l0.27,-2.65l-1.48,-1.78l-0.22,-1.48l-0.92,-0.96l-0.02,-1.29l-0.57,-1.16l-0.68,-0.16l0.69,-1.29l-0.18,-1.14l0.65,-0.62l0.03,-0.55l-0.36,-0.41l1.55,-2.97l1.91,0.16l0.43,-0.4l-0.1,-10.94l2.49,-0.01l0.4,-0.4l-0.0,-4.82l29.02,0.0l0.64,2.04l-0.49,0.66l0.36,2.69l0.93,3.16l2.12,1.55l-0.89,1.04l-1.72,0.39l-0.98,0.9l-1.43,5.65l0.24,1.15l-0.38,2.06l-0.96,2.38l-1.53,1.31l-1.32,2.91l-1.22,0.86l-0.37,1.34Z", "name": "Sudan"}, "DO": {"path": "M241.8,239.2l0.05,-0.65l-0.46,-0.73l0.42,-0.44l0.19,-1.0l-0.09,-1.53l1.66,0.01l1.99,0.63l0.33,0.67l1.28,0.19l0.33,0.76l1.0,0.08l0.8,0.62l-0.45,0.51l-1.13,-0.47l-1.88,-0.01l-1.27,0.59l-0.75,-0.55l-1.01,0.54l-0.79,1.4l-0.23,-0.61Z", "name": "Dominican Rep."}, "DJ": {"path": "M528.43,256.18l-0.45,0.66l-0.58,-0.25l-1.51,0.13l-0.18,-1.01l1.45,-1.95l0.83,0.17l0.77,-0.44l0.2,1.0l-1.2,0.51l-0.06,0.7l0.73,0.47Z", "name": "Djibouti"}, "DK": {"path": "M452.28,129.07l-1.19,2.24l-2.13,-1.6l-0.23,-0.95l2.98,-0.95l0.57,1.26ZM447.74,126.31l-0.26,0.57l-0.88,-0.07l-1.8,2.53l0.48,1.69l-1.09,0.36l-1.61,-0.39l-0.89,-1.69l-0.07,-3.43l0.96,-1.73l2.02,-0.2l1.09,-1.07l1.33,-0.67l-0.05,1.06l-0.73,1.41l0.3,1.0l1.2,0.64Z", "name": "Denmark"}, "DE": {"path": "M453.14,155.55l-0.55,-0.36l-1.2,-0.1l-1.87,0.57l-2.13,-0.13l-0.56,0.63l-0.86,-0.6l-0.96,0.09l-2.57,-0.93l-0.85,0.67l-1.47,-0.02l0.24,-1.75l1.23,-2.14l-0.28,-0.59l-3.52,-0.58l-0.92,-0.66l0.12,-1.2l-0.48,-0.88l0.27,-2.17l-0.37,-3.03l1.41,-0.22l0.63,-1.26l0.66,-3.19l-0.41,-1.18l0.26,-0.39l1.66,-0.15l0.33,0.54l0.62,0.07l1.7,-1.69l-0.54,-3.02l1.37,0.33l1.31,-0.37l0.31,1.18l2.25,0.71l-0.02,0.92l0.5,0.4l2.55,-0.65l1.34,-0.87l2.57,1.24l1.06,0.98l0.48,1.44l-0.57,0.74l-0.0,0.48l0.87,1.15l0.57,1.64l-0.14,1.29l0.82,1.7l-1.5,-0.07l-0.56,0.57l-4.47,2.15l-0.22,0.54l0.68,2.26l2.58,2.16l-0.66,1.11l-0.79,0.36l-0.23,0.43l0.32,1.87Z", "name": "Germany"}, "YE": {"path": "M528.27,246.72l0.26,-0.42l-0.22,-1.01l0.19,-1.5l0.92,-0.69l-0.07,-1.35l0.39,-0.75l1.01,0.47l3.34,-0.27l3.76,0.41l0.95,0.81l1.36,-0.58l1.74,-2.62l2.18,-1.09l6.86,-0.94l2.48,5.41l-1.64,0.76l-0.56,1.9l-6.23,2.16l-2.29,1.8l-1.93,0.05l-1.41,1.02l-4.24,0.74l-1.72,1.49l-3.28,0.19l-0.52,-1.18l0.02,-1.51l-1.34,-3.29Z", "name": "Yemen"}, "DZ": {"path": "M441.46,188.44l-0.32,1.07l0.39,2.64l-0.54,2.16l-1.58,1.82l0.37,2.39l1.91,1.55l0.18,0.8l1.42,1.03l1.84,7.23l0.12,1.16l-0.57,5.0l0.2,1.51l-0.87,0.99l-0.02,0.51l1.41,1.86l0.14,1.2l0.89,1.48l0.5,0.16l0.98,-0.41l1.73,1.08l0.82,1.23l-8.22,4.81l-7.23,5.11l-3.43,1.13l-2.3,0.21l-0.28,-1.59l-2.56,-1.09l-0.67,-1.25l-26.12,-17.86l0.01,-3.47l3.77,-1.88l2.44,-0.41l2.12,-0.75l1.08,-1.42l2.81,-1.05l0.35,-2.08l1.33,-0.29l1.04,-0.94l3.47,-0.69l0.46,-1.08l-0.1,-0.45l-0.58,-0.52l-0.82,-2.81l-0.19,-1.83l-0.78,-1.49l2.03,-1.31l2.63,-0.48l1.7,-1.22l2.31,-0.84l8.24,-0.73l1.49,0.38l2.28,-1.1l2.46,-0.02l0.92,0.6l1.35,-0.05Z", "name": "Algeria"}, "US": {"path": "M892.72,99.2l1.31,0.53l1.41,-0.37l1.89,0.98l1.89,0.42l-1.32,0.58l-2.9,-1.53l-2.08,0.22l-0.26,-0.15l0.07,-0.67ZM183.22,150.47l0.37,1.47l1.12,0.85l4.23,0.7l2.39,0.98l2.17,-0.38l1.85,0.5l-1.55,0.65l-3.49,2.61l-0.16,0.77l0.5,0.39l2.33,-0.61l1.77,1.02l5.15,-2.4l-0.31,0.65l0.25,0.56l1.36,0.38l1.71,1.16l4.7,-0.88l0.67,0.85l1.31,0.21l0.58,0.58l-1.34,0.17l-2.18,-0.32l-3.6,0.89l-2.71,3.25l0.35,0.9l0.59,-0.0l0.55,-0.6l-1.36,4.65l0.29,3.09l0.67,1.58l0.61,0.45l1.77,-0.44l1.6,-1.96l0.14,-2.21l-0.82,-1.96l0.11,-1.13l1.19,-2.37l0.44,-0.33l0.48,0.75l0.4,-0.29l0.4,-1.37l0.6,-0.47l0.24,-0.8l1.69,0.49l1.65,1.08l-0.03,2.37l-1.27,1.13l-0.0,1.13l0.87,0.36l1.66,-1.29l0.5,0.17l0.5,2.6l-2.49,3.75l0.17,0.61l1.54,0.62l1.48,0.17l1.92,-0.44l4.72,-2.15l2.16,-1.8l-0.05,-1.24l0.75,-0.22l3.92,0.36l2.12,-1.05l0.21,-0.4l-0.28,-1.48l3.27,-2.4l8.32,-0.02l0.56,-0.82l1.9,-0.77l0.93,-1.51l0.74,-2.37l1.58,-1.98l0.92,0.62l1.47,-0.47l0.8,0.66l-0.0,4.09l1.96,2.6l-2.34,1.31l-5.37,2.09l-1.83,2.72l0.02,1.79l0.83,1.59l0.54,0.23l-6.19,0.94l-2.2,0.89l-0.23,0.48l0.45,0.29l2.99,-0.46l-2.19,0.56l-1.13,0.0l-0.15,-0.32l-0.48,0.08l-0.76,0.82l0.22,0.67l0.32,0.06l-0.41,1.62l-1.27,1.58l-1.48,-1.07l-0.49,-0.04l-0.16,0.46l0.52,1.58l0.61,0.59l0.03,0.79l-0.95,1.38l-1.21,-1.22l-0.27,-2.27l-0.35,-0.35l-0.42,0.25l-0.48,1.27l0.33,1.41l-0.97,-0.27l-0.48,0.24l0.18,0.5l1.52,0.83l0.1,2.52l0.79,0.51l0.52,3.42l-1.42,1.88l-2.47,0.8l-1.71,1.66l-1.31,0.25l-1.27,1.03l-0.43,0.99l-2.69,1.78l-2.64,3.03l-0.45,2.12l0.45,2.08l0.85,2.38l1.09,1.9l0.04,1.2l1.16,3.06l-0.18,2.69l-0.55,1.43l-0.47,0.21l-0.89,-0.23l-0.49,-1.18l-0.87,-0.56l-2.75,-5.16l0.48,-1.68l-0.72,-1.78l-2.01,-2.38l-1.12,-0.53l-2.72,1.18l-1.47,-1.35l-1.57,-0.68l-2.99,0.31l-2.17,-0.3l-2.0,0.19l-1.15,0.46l-0.19,0.58l0.39,0.63l0.14,1.34l-0.84,-0.2l-0.84,0.46l-1.58,-0.07l-2.08,-1.44l-2.09,0.33l-1.91,-0.62l-3.73,0.84l-2.39,2.07l-2.54,1.22l-1.45,1.41l-0.61,1.38l0.34,3.71l-0.29,0.02l-3.5,-1.33l-1.25,-3.11l-1.44,-1.5l-2.24,-3.56l-1.76,-1.09l-2.27,-0.01l-1.71,2.07l-1.76,-0.69l-1.16,-0.74l-1.52,-2.98l-3.93,-3.16l-4.34,-0.0l-0.4,0.4l-0.0,0.74l-6.5,0.02l-9.02,-3.14l-0.34,-0.71l-5.7,0.49l-0.43,-1.29l-1.62,-1.61l-1.14,-0.38l-0.55,-0.88l-1.28,-0.13l-1.01,-0.77l-2.22,-0.27l-0.43,-0.3l-0.36,-1.58l-2.4,-2.83l-2.01,-3.85l-0.06,-0.9l-2.92,-3.26l-0.33,-2.29l-1.3,-1.66l0.52,-2.37l-0.09,-2.57l-0.78,-2.3l0.95,-2.82l0.61,-5.68l-0.47,-4.27l-1.46,-4.08l3.19,0.79l1.26,2.83l0.69,0.08l0.69,-1.14l-1.1,-4.79l68.76,-0.0l0.4,-0.4l0.14,-0.86ZM32.44,67.52l1.73,1.97l0.55,0.05l0.99,-0.79l3.65,0.24l-0.09,0.62l0.32,0.45l3.83,0.77l2.61,-0.43l5.19,1.4l4.84,0.43l1.89,0.57l3.42,-0.7l6.14,1.87l-0.03,38.06l0.38,0.4l2.39,0.11l2.31,0.98l3.9,3.99l0.55,0.04l2.4,-2.03l2.16,-1.04l1.2,1.71l3.95,3.14l4.09,6.63l4.2,2.29l0.06,1.83l-1.02,1.23l-1.16,-1.08l-2.04,-1.03l-0.67,-2.89l-3.28,-3.03l-1.65,-3.57l-6.35,-0.32l-2.82,-1.01l-5.26,-3.85l-6.77,-2.04l-3.53,0.3l-4.81,-1.69l-3.25,-1.63l-2.78,0.8l-0.28,0.46l0.44,2.21l-3.91,0.96l-2.26,1.27l-2.3,0.65l-0.27,-1.65l1.05,-3.42l2.49,-1.09l0.16,-0.6l-0.69,-0.96l-0.55,-0.1l-3.19,2.12l-1.78,2.56l-3.55,2.61l-0.04,0.61l1.56,1.52l-2.07,2.29l-5.11,2.57l-0.77,1.66l-3.76,1.77l-0.92,1.73l-2.69,1.38l-1.81,-0.22l-6.95,3.32l-3.97,0.91l4.85,-2.5l2.59,-1.86l3.26,-0.52l1.19,-1.4l3.42,-2.1l2.59,-2.27l0.42,-2.68l1.23,-2.1l-0.04,-0.46l-0.45,-0.11l-2.68,1.03l-0.63,-0.49l-0.53,0.03l-1.05,1.04l-1.36,-1.54l-0.66,0.08l-0.32,0.62l-0.58,-1.14l-0.56,-0.16l-2.41,1.42l-1.07,-0.0l-0.17,-1.75l0.3,-1.71l-1.61,-1.33l-3.41,0.59l-1.96,-1.63l-1.57,-0.84l-0.15,-2.21l-1.7,-1.43l0.82,-1.88l1.99,-2.12l0.88,-1.92l1.71,-0.24l2.04,0.51l1.87,-1.77l1.91,0.25l1.91,-1.23l0.17,-0.43l-0.47,-1.82l-1.07,-0.7l1.39,-1.17l0.12,-0.45l-0.39,-0.26l-1.65,0.07l-2.66,0.88l-0.75,0.78l-1.92,-0.8l-3.46,0.44l-3.44,-0.91l-1.06,-1.61l-2.65,-1.99l2.91,-1.43l5.5,-2.0l1.52,0.0l-0.26,1.62l0.41,0.46l5.29,-0.16l0.3,-0.65l-2.03,-2.59l-3.14,-1.68l-1.79,-2.12l-2.4,-1.83l-3.09,-1.24l1.04,-1.69l4.23,-0.14l3.36,-2.07l0.73,-2.27l2.39,-1.99l2.42,-0.52l4.65,-1.97l2.46,0.23l3.71,-2.35l3.5,0.89ZM37.6,123.41l-2.25,1.23l-0.95,-0.69l-0.29,-1.24l3.21,-1.63l1.42,0.21l0.67,0.7l-1.8,1.42ZM31.06,234.03l0.98,0.47l0.74,0.87l-1.77,1.07l-0.44,-1.53l0.49,-0.89ZM29.34,232.07l0.18,0.05l0.08,0.05l-0.16,0.03l-0.11,-0.14ZM25.16,230.17l0.05,-0.03l0.18,0.22l-0.13,-0.01l-0.1,-0.18ZM5.89,113.26l-1.08,0.41l-2.21,-1.12l1.53,-0.4l1.62,0.28l0.14,0.83Z", "name": "United States"}, "UY": {"path": "M286.85,372.74l-0.92,1.5l-2.59,1.44l-1.69,-0.52l-1.42,0.26l-2.39,-1.19l-1.52,0.08l-1.27,-1.3l0.16,-1.5l0.56,-0.79l-0.02,-2.73l1.21,-4.74l1.19,-0.21l2.37,2.0l1.08,0.03l4.36,3.17l1.22,1.6l-0.96,1.5l0.61,1.4Z", "name": "Uruguay"}, "LB": {"path": "M510.37,198.01l-0.88,0.51l1.82,-3.54l0.62,0.08l0.22,0.61l-1.13,0.88l-0.65,1.47Z", "name": "Lebanon"}, "LA": {"path": "M689.54,248.53l-1.76,-0.74l-0.49,0.15l-0.94,1.46l-1.32,-0.64l0.62,-0.98l0.11,-2.17l-2.04,-2.42l-0.25,-2.65l-1.9,-2.1l-2.15,-0.31l-0.78,0.91l-1.12,0.06l-1.05,-0.4l-2.06,1.2l-0.04,-1.59l0.61,-2.68l-0.36,-0.49l-1.35,-0.1l-0.11,-1.23l-0.96,-0.88l1.96,-1.89l0.39,0.36l1.33,0.07l0.42,-0.45l-0.34,-2.66l0.7,-0.21l1.28,1.81l1.11,2.35l0.36,0.23l2.82,0.02l0.71,1.67l-1.39,0.65l-0.72,0.93l0.13,0.6l2.91,1.51l3.6,5.25l1.88,1.78l0.56,1.62l-0.35,1.96Z", "name": "Lao PDR"}, "TW": {"path": "M724.01,226.68l-0.74,1.48l-0.9,-1.52l-0.25,-1.74l1.38,-2.44l1.73,-1.74l0.64,0.44l-1.85,5.52Z", "name": "Taiwan"}, "TT": {"path": "M266.64,259.32l0.28,-1.16l1.13,-0.22l-0.06,1.2l-1.35,0.18Z", "name": "Trinidad and Tobago"}, "TR": {"path": "M513.21,175.47l3.64,1.17l3.05,-0.44l2.1,0.26l3.11,-1.56l2.46,-0.13l2.19,1.33l0.33,0.82l-0.22,1.33l0.25,0.44l2.28,1.13l-1.17,0.57l-0.21,0.45l0.75,3.2l-0.41,1.16l1.13,1.92l-0.55,0.22l-0.9,-0.67l-2.91,-0.37l-1.24,0.46l-4.23,0.41l-2.81,1.05l-1.91,0.01l-1.52,-0.53l-2.58,0.75l-0.66,-0.45l-0.62,0.3l-0.12,1.45l-0.89,0.84l-0.47,-0.67l0.79,-1.3l-0.41,-0.2l-1.43,0.23l-2.0,-0.63l-2.02,1.65l-3.51,0.3l-2.13,-1.53l-2.7,-0.1l-0.86,1.24l-1.38,0.27l-2.29,-1.44l-2.71,-0.01l-1.37,-2.65l-1.68,-1.52l1.07,-1.99l-0.09,-0.49l-1.27,-1.12l2.37,-2.41l3.7,-0.11l1.28,-2.24l4.49,0.37l3.21,-1.97l2.81,-0.82l3.99,-0.06l4.29,2.07ZM488.79,176.72l-1.72,1.31l-0.5,-0.88l1.37,-2.57l-0.7,-0.85l1.7,-0.63l1.8,0.34l0.46,1.17l1.76,0.78l-2.87,0.32l-1.3,1.01Z", "name": "Turkey"}, "LK": {"path": "M624.16,268.99l-1.82,0.48l-0.99,-1.67l-0.42,-3.46l0.95,-3.43l1.21,0.98l2.26,4.19l-0.34,2.33l-0.85,0.58Z", "name": "Sri Lanka"}, "LV": {"path": "M489.16,122.85l0.96,0.66l0.22,1.65l0.68,1.76l-3.65,1.7l-2.23,-1.58l-1.29,-0.26l-0.68,-0.77l-2.42,0.34l-4.16,-0.23l-2.47,0.9l0.06,-1.98l1.13,-2.06l1.95,-1.02l2.12,2.58l2.01,-0.07l0.38,-0.33l0.44,-2.52l1.76,-0.53l3.06,1.7l2.15,0.07Z", "name": "Latvia"}, "LT": {"path": "M486.93,129.3l0.17,1.12l-1.81,0.98l-0.72,2.02l-2.47,1.18l-2.1,-0.02l-0.73,-1.05l-1.06,-0.3l-0.09,-1.87l-3.56,-1.13l-0.43,-2.36l2.48,-0.94l4.12,0.22l2.25,-0.31l0.52,0.69l1.24,0.21l2.19,1.56Z", "name": "Lithuania"}, "LU": {"path": "M436.08,149.45l-0.48,-0.07l0.3,-1.28l0.27,0.4l-0.09,0.96Z", "name": "Luxembourg"}, "LR": {"path": "M399.36,265.97l0.18,1.54l-0.48,0.99l0.08,0.47l2.47,1.8l-0.33,2.8l-2.65,-1.13l-5.78,-4.61l0.58,-1.32l2.1,-2.33l0.86,-0.22l0.77,1.14l-0.14,0.85l0.59,0.87l1.0,0.14l0.76,-0.99Z", "name": "Liberia"}, "LS": {"path": "M491.06,363.48l-0.49,0.15l-1.49,-1.67l1.1,-1.43l2.19,-1.44l1.51,1.27l-0.98,1.82l-1.23,0.38l-0.62,0.93Z", "name": "Lesotho"}, "TH": {"path": "M670.27,255.86l-1.41,3.87l0.15,2.0l0.38,0.36l1.38,0.07l0.9,2.04l0.55,2.34l1.4,1.44l1.61,0.38l0.96,0.97l-0.5,0.64l-1.1,0.2l-0.34,-1.18l-2.04,-1.1l-0.63,0.23l-0.63,-0.62l-0.48,-1.3l-2.56,-2.63l-0.73,0.41l0.95,-3.89l2.16,-4.22ZM670.67,254.77l-0.92,-2.18l-0.26,-2.61l-2.14,-3.06l0.71,-0.49l0.89,-2.59l-3.61,-5.45l0.87,-0.51l1.05,-2.58l1.74,-0.18l2.6,-1.59l0.76,0.56l0.13,1.39l0.37,0.36l1.23,0.09l-0.51,2.28l0.05,2.42l0.6,0.34l2.43,-1.42l0.77,0.39l1.47,-0.07l0.71,-0.88l1.48,0.14l1.71,1.88l0.25,2.65l1.92,2.11l-0.1,1.89l-0.61,0.86l-2.22,-0.33l-3.5,0.64l-1.6,2.12l0.36,2.58l-1.51,-0.79l-1.84,-0.01l0.28,-1.52l-0.4,-0.47l-2.21,0.01l-0.4,0.37l-0.19,2.74l-0.34,0.93Z", "name": "Thailand"}, "TF": {"path": "M596.68,420.38l-3.2,0.18l-0.05,-1.26l0.39,-1.41l1.3,0.78l2.08,0.35l-0.52,1.36Z", "name": "Fr. S. Antarctic Lands"}, "TG": {"path": "M422.7,257.63l-0.09,1.23l1.53,1.52l0.08,1.09l0.5,0.65l-0.11,5.62l0.49,1.47l-1.31,0.35l-1.02,-2.13l-0.18,-1.12l0.53,-2.19l-0.63,-1.16l-0.22,-3.68l-1.01,-1.4l0.07,-0.28l1.37,0.03Z", "name": "Togo"}, "TD": {"path": "M480.25,235.49l0.12,9.57l-2.1,0.05l-1.14,1.89l-0.69,1.63l0.34,0.73l-0.66,0.91l0.24,0.89l-0.86,1.95l0.45,0.5l0.6,-0.1l0.34,0.64l0.03,1.38l0.9,1.04l-1.45,0.43l-1.27,1.03l-1.83,2.76l-2.16,1.07l-2.31,-0.15l-0.86,0.25l-0.26,0.49l0.17,0.61l-2.11,1.68l-2.85,0.87l-1.09,-0.57l-0.73,0.66l-1.12,0.1l-1.1,-3.12l-1.25,-0.64l-1.22,-1.22l0.29,-0.64l3.01,0.04l0.35,-0.6l-1.3,-2.2l-0.08,-3.31l-0.97,-1.66l0.22,-1.04l-0.38,-0.48l-1.22,-0.04l0.0,-1.25l-0.98,-1.07l0.96,-3.01l3.25,-2.65l0.13,-3.33l0.95,-5.18l0.52,-1.07l-0.1,-0.48l-0.91,-0.78l-0.2,-0.96l-0.8,-0.58l-0.55,-3.65l2.1,-1.2l19.57,9.83Z", "name": "Chad"}, "LY": {"path": "M483.48,203.15l-0.75,1.1l0.29,1.39l-0.6,1.83l0.73,2.14l0.0,24.12l-2.48,0.01l-0.41,0.85l-19.41,-9.76l-4.41,2.28l-1.37,-1.33l-3.82,-1.1l-1.14,-1.65l-1.98,-1.23l-1.22,0.32l-0.66,-1.11l-0.17,-1.26l-1.28,-1.69l0.87,-1.19l-0.07,-4.34l0.43,-2.27l-0.86,-3.45l1.13,-0.76l0.22,-1.16l-0.2,-1.03l3.48,-2.61l0.29,-1.94l2.45,0.8l1.18,-0.21l1.98,0.44l3.15,1.18l1.37,2.54l5.72,1.67l2.64,1.35l1.61,-0.72l1.29,-1.34l-0.44,-2.34l0.66,-1.13l1.67,-1.21l1.57,-0.35l3.14,0.53l1.08,1.28l3.99,0.78l0.36,0.54Z", "name": "Libya"}, "AE": {"path": "M550.76,223.97l1.88,-0.4l3.84,0.02l4.78,-4.75l0.19,0.36l0.26,1.58l-0.81,0.01l-0.39,0.35l-0.08,2.04l-0.81,0.63l-0.01,0.96l-0.66,0.99l-0.39,1.41l-7.08,-1.25l-0.7,-1.96Z", "name": "United Arab Emirates"}, "VE": {"path": "M240.68,256.69l0.53,0.75l-0.02,1.06l-1.07,1.78l0.95,2.0l0.42,0.22l1.4,-0.44l0.56,-1.83l-0.77,-1.17l-0.1,-1.47l2.82,-0.93l0.26,-0.49l-0.28,-0.96l0.3,-0.28l0.66,1.31l1.96,0.26l1.4,1.22l0.08,0.68l0.39,0.35l4.81,-0.22l1.49,1.11l1.92,0.31l1.67,-0.84l0.22,-0.6l3.44,-0.14l-0.17,0.55l0.86,1.19l2.19,0.35l1.67,1.1l0.37,1.86l0.41,0.32l1.55,0.17l-1.66,1.35l-0.22,0.92l0.65,0.97l-1.67,0.54l-0.3,0.4l0.04,0.99l-0.56,0.57l-0.01,0.55l1.85,2.27l-0.66,0.69l-4.47,1.29l-0.72,0.54l-3.69,-0.9l-0.71,0.27l-0.02,0.7l0.91,0.53l-0.08,1.54l0.35,1.58l0.35,0.31l1.66,0.17l-1.3,0.52l-0.48,1.13l-2.68,0.91l-0.6,0.77l-1.57,0.13l-1.17,-1.13l-0.8,-2.52l-1.25,-1.26l1.02,-1.23l-1.29,-2.95l0.18,-1.62l1.0,-2.21l-0.2,-0.49l-1.14,-0.46l-4.02,0.36l-1.82,-2.1l-1.57,-0.33l-2.99,0.22l-1.06,-0.97l0.25,-1.23l-0.2,-1.01l-0.59,-0.69l-0.29,-1.06l-1.08,-0.39l0.78,-2.79l1.9,-2.11Z", "name": "Venezuela"}, "AF": {"path": "M600.7,188.88l-1.57,1.3l-0.1,0.48l0.8,2.31l-1.09,1.04l-0.03,1.27l-0.48,0.71l-2.16,-0.08l-0.37,0.59l0.78,1.48l-1.38,0.69l-1.06,1.69l0.06,1.7l-0.65,0.52l-0.91,-0.21l-1.91,0.36l-0.48,0.77l-1.88,0.13l-1.4,1.56l-0.18,2.32l-2.91,1.02l-1.65,-0.23l-0.71,0.55l-1.41,-0.3l-2.41,0.39l-3.52,-1.17l1.96,-2.35l-0.21,-1.78l-0.3,-0.34l-1.63,-0.4l-0.19,-1.58l-0.75,-2.03l0.95,-1.36l-0.19,-0.6l-0.73,-0.28l1.47,-4.8l2.14,0.9l2.12,-0.36l0.74,-1.34l1.77,-0.39l1.54,-0.92l0.63,-2.31l1.87,-0.5l0.49,-0.81l0.94,0.56l2.13,0.11l2.55,0.92l1.95,-0.83l0.65,0.43l0.56,-0.13l0.69,-1.12l1.57,-0.08l0.72,-1.66l0.79,-0.74l0.8,0.39l-0.17,0.56l0.71,0.58l-0.08,2.39l1.11,0.95ZM601.37,188.71l1.73,-0.71l1.43,-1.18l4.03,0.35l-2.23,0.74l-4.95,0.8Z", "name": "Afghanistan"}, "IQ": {"path": "M530.82,187.47l0.79,0.66l1.26,-0.28l1.46,3.08l1.63,0.94l0.14,1.23l-1.22,1.05l-0.53,2.52l1.73,2.67l3.12,1.62l1.15,1.88l-0.38,1.85l0.39,0.48l0.41,-0.0l0.02,1.07l0.76,0.94l-2.47,-0.1l-1.71,2.44l-4.31,-0.2l-7.02,-5.48l-3.73,-1.94l-2.88,-0.73l-0.85,-2.87l5.45,-3.02l0.95,-3.43l-0.19,-1.96l1.27,-0.7l1.22,-1.7l0.87,-0.36l2.69,0.34Z", "name": "Iraq"}, "IS": {"path": "M384.14,88.06l-0.37,2.61l2.54,2.51l-2.9,2.75l-9.19,3.4l-9.25,-1.66l1.7,-1.22l-0.1,-0.7l-4.05,-1.47l2.96,-0.53l0.33,-0.43l-0.11,-1.2l-0.33,-0.36l-4.67,-0.85l1.28,-2.04l3.45,-0.56l3.77,2.72l0.44,0.02l3.64,-2.16l3.3,1.08l3.98,-2.16l3.58,0.26Z", "name": "Iceland"}, "IR": {"path": "M533.43,187.16l-1.27,-2.15l0.42,-0.98l-0.71,-3.04l1.03,-0.5l0.33,0.83l1.26,1.35l2.05,0.51l1.11,-0.16l2.89,-2.11l0.62,-0.14l0.39,0.46l-0.72,1.2l0.06,0.49l1.56,1.53l0.65,0.04l0.67,1.81l2.56,0.83l1.87,1.48l3.69,0.49l3.91,-0.76l0.47,-0.73l2.17,-0.6l1.66,-1.54l1.51,0.08l1.18,-0.53l1.59,0.24l2.83,1.48l1.88,0.3l2.77,2.47l1.77,0.18l0.18,1.99l-1.68,5.49l0.24,0.5l0.61,0.23l-0.82,1.48l0.8,2.18l0.19,1.71l0.3,0.34l1.63,0.4l0.15,1.32l-2.15,2.35l-0.01,0.53l2.21,3.03l2.34,1.24l0.06,2.14l1.24,0.72l0.11,0.69l-3.31,1.27l-1.08,3.03l-9.68,-1.68l-0.99,-3.05l-1.43,-0.73l-2.17,0.46l-2.47,1.26l-2.83,-0.82l-2.46,-2.02l-2.41,-0.8l-3.42,-6.06l-0.48,-0.2l-1.18,0.39l-1.44,-0.82l-0.5,0.08l-0.65,0.74l-0.97,-1.01l-0.02,-1.31l-0.71,-0.39l0.26,-1.81l-1.29,-2.11l-3.13,-1.63l-1.58,-2.43l0.5,-1.9l1.31,-1.26l-0.19,-1.66l-1.74,-1.1l-1.57,-3.3Z", "name": "Iran"}, "AM": {"path": "M536.99,182.33l-0.28,0.03l-1.23,-2.13l-0.93,0.01l-0.62,-0.66l-0.69,-0.07l-0.96,-0.81l-1.56,-0.62l0.19,-1.12l-0.26,-0.79l2.72,-0.36l1.09,1.01l-0.17,0.92l1.02,0.78l-0.47,0.62l0.08,0.56l2.04,1.23l0.04,1.4Z", "name": "Armenia"}, "AL": {"path": "M470.32,171.8l0.74,0.03l0.92,0.89l-0.17,1.95l0.36,1.28l1.01,0.82l-1.82,2.83l-0.19,-0.61l-1.25,-0.89l-0.18,-1.2l0.53,-2.82l-0.54,-1.47l0.6,-0.83Z", "name": "Albania"}, "AO": {"path": "M461.55,300.03l1.26,3.15l1.94,2.36l2.47,-0.53l1.25,0.32l0.44,-0.18l0.93,-1.92l1.31,-0.08l0.41,-0.44l0.47,-0.0l-0.1,0.41l0.39,0.49l2.65,-0.02l0.03,1.19l0.48,1.01l-0.34,1.52l0.18,1.55l0.83,1.04l-0.13,2.85l0.54,0.39l3.96,-0.41l-0.1,1.79l0.39,1.05l-0.24,1.43l-4.7,-0.03l-0.4,0.39l-0.12,8.13l2.92,3.49l-3.83,0.88l-5.89,-0.36l-1.88,-1.24l-10.47,0.22l-1.3,-1.01l-1.85,-0.16l-2.4,0.77l-0.15,-1.06l0.33,-2.16l1.0,-3.45l1.35,-3.2l2.24,-2.8l0.33,-2.06l-0.13,-1.53l-0.8,-1.08l-1.21,-2.87l0.87,-1.62l-1.27,-4.12l-1.17,-1.53l2.47,-0.63l7.03,0.03ZM451.71,298.87l-0.47,-1.25l1.25,-1.11l0.32,0.3l-0.99,1.03l-0.12,1.03Z", "name": "Angola"}, "AR": {"path": "M249.29,428.93l-2.33,-0.52l-5.83,-0.43l-0.89,-1.66l0.05,-2.37l-0.45,-0.4l-1.43,0.18l-0.67,-0.91l-0.2,-3.13l1.88,-1.47l0.79,-2.04l-0.25,-1.7l1.3,-2.68l0.91,-4.15l-0.22,-1.69l0.85,-0.45l0.2,-0.44l-0.27,-1.16l-0.98,-0.68l0.59,-0.92l-0.05,-0.5l-1.04,-1.07l-0.52,-3.1l0.97,-0.86l-0.42,-3.58l1.2,-5.43l1.38,-0.98l0.16,-0.43l-0.75,-2.79l-0.01,-2.43l1.78,-1.75l0.06,-2.57l1.43,-2.85l0.01,-2.58l-0.69,-0.74l-1.09,-4.52l1.47,-2.7l-0.18,-2.79l0.85,-2.35l1.59,-2.46l1.73,-1.64l0.05,-0.52l-0.6,-0.84l0.44,-0.85l-0.07,-4.19l2.7,-1.44l0.86,-2.75l-0.21,-0.71l1.76,-2.01l2.9,0.57l1.38,1.78l0.68,-0.08l0.87,-1.87l2.39,0.09l4.95,4.77l2.17,0.49l3.0,1.92l2.47,1.0l0.25,0.82l-2.37,3.93l0.23,0.59l5.39,1.16l2.12,-0.44l2.45,-2.16l0.5,-2.38l0.76,-0.31l0.98,1.2l-0.04,1.8l-3.67,2.51l-2.85,2.66l-3.43,3.88l-1.3,5.07l0.01,2.72l-0.54,0.73l-0.36,3.28l3.14,2.64l-0.16,2.11l1.4,1.11l-0.1,1.09l-2.29,3.52l-3.55,1.49l-4.92,0.6l-2.71,-0.29l-0.43,0.51l0.5,1.65l-0.49,2.1l0.38,1.42l-1.19,0.83l-2.36,0.38l-2.3,-1.04l-1.38,0.83l0.41,3.64l1.69,0.91l1.4,-0.71l0.36,0.76l-2.04,0.86l-2.01,1.89l-0.97,4.63l-2.34,0.1l-2.09,1.78l-0.61,2.75l2.46,2.31l2.17,0.63l-0.7,2.32l-2.83,1.73l-1.73,3.86l-2.17,1.22l-1.16,1.67l0.75,3.76l1.04,1.28ZM256.71,438.88l-2.0,0.15l-1.4,-1.22l-3.82,-0.1l-0.0,-5.83l1.6,3.05l3.26,2.07l3.08,0.78l-0.71,1.1Z", "name": "Argentina"}, "AU": {"path": "M705.8,353.26l0.26,0.04l0.17,-0.47l-0.48,-1.42l0.92,1.11l0.45,0.15l0.27,-0.39l-0.1,-1.56l-1.98,-3.63l1.09,-3.31l-0.24,-1.57l0.34,-0.62l0.38,1.06l0.43,-0.19l0.99,-1.7l1.91,-0.83l1.29,-1.15l1.81,-0.91l0.96,-0.17l0.92,0.26l1.92,-0.95l1.47,-0.28l1.03,-0.8l1.43,0.04l2.78,-0.84l1.36,-1.15l0.71,-1.45l1.41,-1.26l0.3,-2.58l1.27,-1.59l0.78,1.65l0.54,0.19l1.07,-0.51l0.15,-0.6l-0.73,-1.0l0.45,-0.71l0.78,0.39l0.58,-0.3l0.28,-1.82l1.87,-2.14l1.12,-0.39l0.28,-0.58l0.62,0.17l0.53,-0.73l1.87,-0.57l1.65,1.05l1.35,1.48l3.39,0.38l0.43,-0.54l-0.46,-1.23l1.05,-1.79l1.04,-0.61l0.14,-0.55l-0.25,-0.41l0.88,-1.17l1.31,-0.77l1.3,0.27l2.1,-0.48l0.31,-0.4l-0.05,-1.3l-0.92,-0.77l1.48,0.56l1.41,1.07l2.11,0.65l0.81,-0.2l1.4,0.7l1.69,-0.66l0.8,0.19l0.64,-0.33l0.71,0.77l-1.33,1.94l-0.71,0.07l-0.35,0.51l0.24,0.86l-1.52,2.35l0.12,1.05l2.15,1.65l1.97,0.85l3.04,2.36l1.97,0.65l0.55,0.88l2.72,0.85l1.84,-1.1l2.07,-5.97l-0.42,-3.59l0.3,-1.73l0.47,-0.87l-0.31,-0.68l1.09,-3.28l0.46,-0.47l0.4,0.71l0.16,1.51l0.65,0.52l0.16,1.04l0.85,1.21l0.12,2.38l0.9,2.0l0.57,0.18l1.3,-0.78l1.69,1.7l-0.2,1.08l0.53,2.2l0.39,1.3l0.68,0.48l0.6,1.95l-0.19,1.48l0.81,1.76l6.01,3.69l-0.11,0.76l1.38,1.58l0.95,2.77l0.58,0.22l0.72,-0.41l0.8,0.9l0.61,0.01l0.46,2.41l4.81,4.71l0.66,2.02l-0.07,3.31l1.14,2.2l-0.13,2.24l-1.1,3.68l0.03,1.64l-0.47,1.89l-1.05,2.4l-1.9,1.47l-1.72,3.51l-2.38,6.09l-0.24,2.82l-1.14,0.8l-2.85,0.15l-2.31,1.19l-2.51,2.25l-3.09,-1.57l0.3,-1.15l-0.54,-0.47l-1.5,0.63l-2.01,1.94l-7.12,-2.18l-1.48,-1.63l-1.14,-3.74l-1.45,-1.26l-1.81,-0.26l0.56,-1.18l-0.61,-2.1l-0.72,-0.1l-1.14,1.82l-0.9,0.21l0.63,-0.82l0.36,-1.55l0.92,-1.31l-0.13,-2.34l-0.7,-0.22l-2.0,2.34l-1.51,0.93l-0.94,2.01l-1.35,-0.81l-0.02,-1.52l-1.57,-2.04l-1.09,-0.88l0.24,-0.33l-0.14,-0.59l-3.21,-1.69l-1.83,-0.12l-2.54,-1.35l-4.58,0.28l-6.02,1.9l-2.53,-0.13l-2.62,1.41l-2.13,0.63l-1.49,2.6l-3.49,0.31l-2.29,-0.5l-3.48,0.43l-1.6,1.47l-0.81,-0.04l-2.37,1.63l-3.26,-0.1l-3.72,-2.21l0.04,-1.05l1.19,-0.46l0.49,-0.89l0.21,-2.97l-0.28,-1.64l-1.34,-2.86l-0.38,-1.47l0.05,-1.72l-0.95,-1.7l-0.18,-0.97l-1.01,-0.99l-0.29,-1.98l-1.13,-1.75ZM784.92,393.44l2.65,1.02l3.23,-0.96l1.09,0.14l0.15,3.06l-0.85,1.13l-0.17,1.63l-0.87,-0.24l-1.57,1.91l-1.68,-0.18l-1.4,-2.36l-0.37,-2.04l-1.39,-2.51l0.04,-0.8l1.15,0.18Z", "name": "Australia"}, "AT": {"path": "M462.89,152.8l0.04,2.25l-1.07,0.0l-0.33,0.63l0.36,0.51l-1.04,2.13l-2.02,0.07l-1.33,0.7l-5.29,-0.99l-0.47,-0.93l-0.44,-0.21l-2.47,0.55l-0.42,0.51l-3.18,-0.81l0.43,-0.91l1.12,0.78l0.6,-0.17l0.25,-0.58l1.93,0.12l1.86,-0.56l1.0,0.08l0.68,0.57l0.62,-0.15l0.26,-0.77l-0.3,-1.78l0.8,-0.44l0.68,-1.15l1.52,0.85l0.47,-0.06l1.34,-1.25l0.64,-0.17l1.81,0.92l1.28,-0.11l0.7,0.37Z", "name": "Austria"}, "IN": {"path": "M623.34,207.03l-1.24,1.04l-0.97,2.55l0.22,0.51l8.04,3.87l3.42,0.37l1.57,1.38l4.92,0.88l2.18,-0.04l0.38,-0.3l0.29,-1.24l-0.32,-1.64l0.14,-0.87l0.82,-0.31l0.45,2.48l2.28,1.02l1.77,-0.38l4.14,0.1l0.38,-0.36l0.18,-1.66l-0.5,-0.65l1.37,-0.29l2.25,-1.99l2.7,-1.62l1.93,0.62l1.8,-0.98l0.79,1.14l-0.68,0.91l0.26,0.63l2.42,0.36l0.09,0.47l-0.83,0.75l0.13,1.07l-1.52,-0.29l-3.24,1.86l-0.13,1.78l-1.32,2.14l-0.18,1.39l-0.93,1.82l-1.64,-0.5l-0.52,0.37l-0.09,2.63l-0.56,1.11l0.19,0.81l-0.53,0.27l-1.18,-3.73l-1.08,-0.27l-0.38,0.31l-0.24,1.0l-0.66,-0.66l0.54,-1.06l1.22,-0.34l1.15,-2.25l-0.24,-0.56l-1.57,-0.47l-4.34,-0.28l-0.18,-1.56l-0.35,-0.35l-1.11,-0.12l-1.91,-1.12l-0.56,0.17l-0.88,1.82l0.11,0.49l1.36,1.07l-1.09,0.69l-0.69,1.11l0.18,0.56l1.24,0.57l-0.32,1.54l0.85,1.94l0.36,2.01l-0.22,0.59l-4.58,0.52l-0.33,0.42l0.13,1.8l-1.17,1.36l-3.65,1.81l-2.79,3.03l-4.32,3.28l-0.18,1.27l-4.65,1.79l-0.77,2.16l0.64,5.3l-1.06,2.49l-0.01,3.94l-1.24,0.28l-1.14,1.93l0.39,0.84l-1.68,0.53l-1.04,1.83l-0.65,0.47l-2.06,-2.05l-2.1,-6.02l-2.2,-3.64l-1.05,-4.75l-2.29,-3.57l-1.76,-8.2l0.01,-3.11l-0.49,-2.53l-0.55,-0.29l-3.53,1.52l-1.53,-0.27l-2.86,-2.77l0.85,-0.67l0.08,-0.55l-0.74,-1.03l-2.67,-2.06l1.24,-1.32l5.34,0.01l0.39,-0.49l-0.5,-2.29l-1.42,-1.46l-0.27,-1.93l-1.43,-1.2l2.31,-2.37l3.05,0.06l2.62,-2.85l1.6,-2.81l2.4,-2.73l0.07,-2.04l1.97,-1.48l-0.02,-0.65l-1.93,-1.31l-0.82,-1.78l-0.8,-2.21l0.9,-0.89l3.59,0.65l2.92,-0.42l2.33,-2.19l2.31,2.85l-0.24,2.13l0.99,1.59l-0.05,0.82l-1.34,-0.28l-0.47,0.48l0.7,3.06l2.62,1.99l2.99,1.65Z", "name": "India"}, "TZ": {"path": "M495.56,296.42l2.8,-3.12l-0.02,-0.81l-0.64,-1.3l0.68,-0.52l0.14,-1.47l-0.76,-1.25l0.31,-0.11l2.26,0.03l-0.51,2.76l0.76,1.3l0.5,0.12l1.05,-0.53l1.19,-0.12l0.61,0.24l1.43,-0.62l0.1,-0.67l-0.71,-0.62l1.57,-1.7l8.65,4.86l0.32,1.53l3.34,2.33l-1.05,2.8l0.13,1.61l1.63,1.12l-0.6,1.76l-0.01,2.33l1.89,4.03l0.57,0.43l-1.46,1.08l-2.61,0.94l-1.43,-0.04l-1.06,0.77l-2.29,0.36l-2.87,-0.68l-0.83,0.07l-0.63,-0.75l-0.31,-2.78l-1.32,-1.35l-3.25,-0.77l-3.96,-1.58l-1.18,-2.41l-0.32,-1.75l-1.76,-1.49l0.42,-1.05l-0.44,-0.89l0.08,-0.96l-0.46,-0.58l0.06,-0.56Z", "name": "Tanzania"}, "AZ": {"path": "M539.29,175.73l1.33,0.32l1.94,-1.8l2.3,3.34l1.43,0.43l-1.26,0.15l-0.35,0.32l-0.8,3.14l-0.99,0.96l0.05,1.11l-1.26,-1.13l0.7,-1.18l-0.04,-0.47l-0.74,-0.86l-1.48,0.15l-2.34,1.71l-0.03,-1.27l-2.03,-1.35l0.47,-0.62l-0.08,-0.56l-1.03,-0.79l0.29,-0.43l-0.14,-0.58l-1.13,-0.86l1.89,0.68l1.69,0.06l0.37,-0.87l-0.81,-1.37l0.42,0.06l1.63,1.72ZM533.78,180.57l0.61,0.46l0.69,-0.0l0.59,1.15l-0.68,-0.15l-1.21,-1.45Z", "name": "Azerbaijan"}, "IE": {"path": "M405.08,135.42l0.35,2.06l-1.75,2.78l-4.22,1.88l-2.84,-0.4l1.73,-3.0l-1.18,-3.53l4.6,-3.74l0.32,1.15l-0.49,1.74l0.4,0.51l1.47,-0.04l1.6,0.6Z", "name": "Ireland"}, "ID": {"path": "M756.47,287.89l0.69,4.01l2.79,1.78l0.51,-0.1l2.04,-2.59l2.71,-1.43l2.05,-0.0l3.9,1.73l2.46,0.45l0.08,15.12l-1.75,-1.54l-2.54,-0.51l-0.88,0.71l-2.32,0.06l0.69,-1.33l1.45,-0.64l0.23,-0.46l-0.65,-2.74l-1.24,-2.21l-5.04,-2.29l-2.09,-0.23l-3.68,-2.27l-0.55,0.13l-0.65,1.07l-0.52,0.12l-0.55,-1.89l-1.21,-0.78l1.84,-0.62l1.72,0.05l0.39,-0.52l-0.21,-0.66l-0.38,-0.28l-3.45,-0.0l-1.13,-1.48l-2.1,-0.43l-0.52,-0.6l2.69,-0.48l1.28,-0.78l3.66,0.94l0.3,0.71ZM757.91,300.34l-0.62,0.82l-0.1,-0.8l0.59,-1.12l0.13,1.1ZM747.38,292.98l0.34,0.72l-1.22,-0.57l-4.68,-0.1l0.27,-0.62l2.78,-0.09l2.52,0.67ZM741.05,285.25l-0.67,-2.88l0.64,-2.01l0.41,0.86l1.21,0.18l0.16,0.7l-0.1,1.68l-0.84,-0.16l-0.46,0.3l-0.34,1.34ZM739.05,293.5l-0.5,0.44l-1.34,-0.36l-0.17,-0.37l1.73,-0.08l0.27,0.36ZM721.45,284.51l-0.19,1.97l2.24,2.23l0.54,0.02l1.27,-1.07l2.75,-0.5l-0.9,1.21l-2.11,0.93l-0.16,0.6l2.22,3.01l-0.3,1.07l1.36,1.74l-2.26,0.85l-0.28,-0.31l0.12,-1.19l-1.64,-1.34l0.17,-2.23l-0.56,-0.39l-1.67,0.76l-0.23,0.39l0.3,6.17l-1.1,0.25l-0.69,-0.47l0.64,-2.21l-0.39,-2.42l-0.39,-0.34l-0.8,-0.01l-0.58,-1.29l0.98,-1.6l0.35,-1.96l1.32,-3.87ZM728.59,296.27l0.38,0.49l-0.02,1.28l-0.88,0.49l-0.53,-0.47l1.04,-1.79ZM729.04,286.98l0.27,-0.05l-0.02,0.13l-0.24,-0.08ZM721.68,284.05l0.16,-0.32l1.89,-1.65l1.83,0.68l3.16,0.35l2.94,-0.1l2.39,-1.66l-1.73,2.13l-1.66,0.43l-2.41,-0.48l-4.17,0.13l-2.39,0.51ZM730.55,310.47l1.11,-1.93l2.03,-0.82l0.08,0.62l-1.45,1.67l-1.77,0.46ZM728.12,305.88l-0.1,0.38l-3.46,0.66l-2.91,-0.27l-0.0,-0.25l1.54,-0.41l1.66,0.73l1.67,-0.19l1.61,-0.65ZM722.9,310.24l-0.64,0.03l-2.26,-1.2l1.11,-0.24l1.78,1.41ZM716.26,305.77l0.88,0.51l1.28,-0.17l0.2,0.35l-4.65,0.73l0.39,-0.67l1.15,-0.02l0.75,-0.73ZM711.66,293.84l-0.38,-0.16l-2.54,1.01l-1.12,-1.44l-1.69,-0.13l-1.16,-0.75l-3.04,0.77l-1.1,-1.15l-3.31,-0.11l-0.35,-3.05l-1.35,-0.95l-1.11,-1.98l-0.33,-2.06l0.27,-2.14l0.9,-1.01l0.37,1.15l2.09,1.49l1.53,-0.48l1.82,0.08l1.38,-1.19l1.0,-0.18l2.28,0.67l2.26,-0.53l1.52,-3.64l1.01,-0.99l0.78,-2.57l4.1,0.3l-1.11,1.77l0.02,0.46l1.7,2.2l-0.23,1.39l2.07,1.71l-2.33,0.42l-0.88,1.9l0.1,2.05l-2.4,1.9l-0.06,2.45l-0.7,2.79ZM692.58,302.03l0.35,0.26l4.8,0.25l0.78,-0.97l4.17,1.09l1.13,1.68l3.69,0.45l2.13,1.04l-1.8,0.6l-2.77,-0.99l-4.8,-0.12l-5.24,-1.41l-1.84,-0.25l-1.11,0.3l-4.26,-0.97l-0.7,-1.14l-1.59,-0.13l1.18,-1.65l2.74,0.13l2.87,1.13l0.26,0.68ZM685.53,299.17l-2.22,0.04l-2.06,-2.03l-3.15,-2.01l-2.93,-3.51l-3.11,-5.33l-2.2,-2.12l-1.64,-4.06l-2.32,-1.69l-1.27,-2.07l-1.96,-1.5l-2.51,-2.65l-0.11,-0.66l4.81,0.53l2.15,2.38l3.31,2.74l2.35,2.66l2.7,0.17l1.95,1.59l1.54,2.17l1.59,0.95l-0.84,1.71l0.15,0.52l1.44,0.87l0.79,0.1l0.4,1.58l0.87,1.4l1.96,0.39l1.0,1.31l-0.6,3.01l-0.09,3.5Z", "name": "Indonesia"}, "UA": {"path": "M492.5,162.44l1.28,-2.49l1.82,0.19l0.66,-0.23l0.09,-0.71l-0.25,-0.75l-0.79,-0.72l-0.33,-1.21l-0.86,-0.62l-0.02,-1.19l-1.13,-0.86l-1.15,-0.19l-2.04,-1.0l-1.66,0.32l-0.66,0.47l-0.92,-0.0l-0.84,0.78l-2.48,0.7l-1.18,-0.71l-3.07,-0.36l-0.89,0.43l-0.24,-0.55l-1.11,-0.7l0.35,-0.93l1.26,-1.02l-0.54,-1.23l2.04,-2.43l1.4,-0.62l0.25,-1.19l-1.04,-2.39l0.83,-0.13l1.28,-0.84l1.8,-0.07l2.47,0.26l2.86,0.81l1.88,0.06l0.86,0.44l1.04,-0.41l0.77,0.66l2.18,-0.15l0.92,0.3l0.52,-0.34l0.15,-1.53l0.56,-0.54l2.85,-0.05l0.84,-0.72l3.04,-0.18l1.23,1.46l-0.48,0.77l0.21,1.03l0.36,0.32l1.8,0.14l0.93,2.08l3.18,1.15l1.94,-0.45l1.67,1.49l1.4,-0.03l3.35,0.96l0.02,0.54l-0.96,1.59l0.47,1.97l-0.26,0.7l-2.36,0.28l-1.29,0.89l-0.23,1.38l-1.83,0.27l-1.58,0.97l-2.41,0.21l-2.16,1.17l-0.21,0.38l0.34,2.26l1.23,0.75l2.13,-0.08l-0.14,0.31l-2.65,0.53l-3.23,1.69l-0.87,-0.39l0.42,-1.1l-0.25,-0.52l-2.21,-0.73l2.35,-1.06l0.12,-0.65l-0.93,-0.82l-3.62,-0.74l-0.13,-0.89l-0.46,-0.34l-2.61,0.59l-0.91,1.69l-1.71,2.04l-0.86,-0.4l-1.62,0.27Z", "name": "Ukraine"}, "QA": {"path": "M549.33,221.64l-0.76,-0.23l-0.14,-1.64l0.84,-1.29l0.47,0.52l0.04,1.34l-0.45,1.3Z", "name": "Qatar"}, "MZ": {"path": "M508.58,318.75l-0.34,-2.57l0.51,-2.05l3.55,0.63l2.5,-0.38l1.02,-0.76l1.49,0.01l2.74,-0.98l1.66,-1.2l0.5,9.24l0.41,1.23l-0.68,1.67l-0.93,1.71l-1.5,1.5l-5.16,2.28l-2.78,2.73l-1.02,0.53l-1.71,1.8l-0.98,0.57l-0.35,2.41l1.16,1.94l0.49,2.17l0.43,0.31l-0.06,2.06l-0.39,1.17l0.5,0.72l-0.25,0.73l-0.92,0.83l-5.12,2.39l-1.22,1.36l0.21,1.13l0.58,0.39l-0.11,0.72l-1.22,-0.01l-0.73,-2.97l0.42,-3.09l-1.78,-5.37l2.49,-2.81l0.69,-1.89l0.44,-0.43l0.28,-1.53l-0.39,-0.93l0.59,-3.65l-0.01,-3.26l-1.49,-1.16l-1.2,-0.22l-1.74,-1.17l-1.92,0.01l-0.29,-2.08l7.06,-1.96l1.28,1.09l0.89,-0.1l0.67,0.44l0.1,0.73l-0.51,1.29l0.19,1.81l1.75,1.83l0.65,-0.13l0.71,-1.65l1.17,-0.86l-0.26,-3.47l-1.05,-1.85l-1.04,-0.94Z", "name": "Mozambique"}}, "height": 440.7063107441331, "projection": {"type": "mill", "centralMeridian": 11.5}, "width": 900.0}); \ No newline at end of file diff --git a/src/test.html b/src/test.html deleted file mode 100644 index 3f463d4..0000000 --- a/src/test.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - Test - - - -
-
-
- - -
- -
-
-
- - - -
-
-
-
- Copyright © 2025 Designed by Colorlib. All rights reserved. -
-
- - \ No newline at end of file diff --git a/src/types/index.ts b/src/types/index.ts deleted file mode 100644 index 6714ceb..0000000 --- a/src/types/index.ts +++ /dev/null @@ -1,236 +0,0 @@ -/** - * Core type definitions for Adminator Dashboard - */ - -// Theme types -export type Theme = 'light' | 'dark' | 'auto'; - -export interface ThemeConfig { - theme: Theme; - autoDetect: boolean; - persistChoice: boolean; -} - -// Component types -export interface ComponentOptions { - [key: string]: any; -} - -export interface ComponentInterface { - name: string; - element: HTMLElement; - options: ComponentOptions; - isInitialized: boolean; - init(): void; - destroy(): void; -} - -// Sidebar types -export interface SidebarOptions { - breakpoint?: number; - collapsible?: boolean; - autoHide?: boolean; - animation?: boolean; - animationDuration?: number; -} - -export interface SidebarState { - isCollapsed: boolean; - isMobile: boolean; - activeMenu: string | null; -} - -// Chart types -export type ChartType = 'line' | 'bar' | 'doughnut' | 'pie' | 'radar' | 'scatter' | 'bubble' | 'polarArea'; - -export interface ChartDataset { - label?: string; - data: number[]; - backgroundColor?: string | string[]; - borderColor?: string | string[]; - borderWidth?: number; - fill?: boolean; -} - -export interface ChartData { - labels: string[]; - datasets: ChartDataset[]; -} - -export interface ChartOptions { - type: ChartType; - data: ChartData; - responsive?: boolean; - maintainAspectRatio?: boolean; - plugins?: any; - scales?: any; -} - -// DataTable types -export interface DataTableColumn { - key: string; - title: string; - sortable?: boolean; - searchable?: boolean; - render?: (value: any, row: any) => string; -} - -export interface DataTableOptions { - columns: DataTableColumn[]; - data: any[]; - pageSize?: number; - sortable?: boolean; - searchable?: boolean; - pagination?: boolean; -} - -export interface DataTableState { - currentPage: number; - pageSize: number; - totalRows: number; - sortColumn: string | null; - sortDirection: 'asc' | 'desc'; - searchQuery: string; - filteredData: any[]; -} - -// Date utilities types -export interface DateRange { - start: Date; - end: Date; -} - -export interface DateFormatOptions { - locale?: string; - format?: string; - timeZone?: string; -} - -// DOM utilities types -export type DOMEventHandler = (event: Event) => void; - -export interface DOMUtilities { - select: (selector: string, context?: Element | Document) => HTMLElement | null; - selectAll: (selector: string, context?: Element | Document) => HTMLElement[]; - on: (element: Element | Window | Document, event: string, handler: DOMEventHandler) => void; - off: (element: Element | Window | Document, event: string, handler: DOMEventHandler) => void; - addClass: (element: Element, className: string) => void; - removeClass: (element: Element, className: string) => void; - toggleClass: (element: Element, className: string) => void; - hasClass: (element: Element, className: string) => boolean; - attr: (element: Element, attribute: string, value?: string) => string | void; - data: (element: Element, key: string, value?: any) => any; - ready: (callback: () => void) => void; - exists: (selector: string, context?: Element | Document) => boolean; -} - -// Application state types -export interface ApplicationState { - theme: Theme; - sidebar: SidebarState; - components: Map; - isInitialized: boolean; -} - -export interface ApplicationConfig { - theme: ThemeConfig; - sidebar: SidebarOptions; - enableAnalytics?: boolean; - debugMode?: boolean; -} - -// Event types -export interface CustomEventDetail { - [key: string]: any; -} - -export interface ThemeChangeEvent extends CustomEvent { - detail: { - theme: Theme; - previousTheme: Theme; - }; -} - -export interface ComponentEvent extends CustomEvent { - detail: { - component: string; - action: 'init' | 'destroy' | 'update'; - data?: any; - }; -} - -// Utility types -export type DeepPartial = { - [P in keyof T]?: T[P] extends object ? DeepPartial : T[P]; -}; - -export type RequiredKeys = T & Required>; - -export type OptionalKeys = Omit & Partial>; - -// Color types -export interface ColorPalette { - primary: string; - secondary: string; - success: string; - danger: string; - warning: string; - info: string; - light: string; - dark: string; -} - -export interface ThemeColors { - light: ColorPalette; - dark: ColorPalette; -} - -// Animation types -export type AnimationEasing = 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear'; - -export interface AnimationOptions { - duration?: number; - easing?: AnimationEasing; - delay?: number; - fillMode?: 'none' | 'forwards' | 'backwards' | 'both'; -} - -// Layout types -export interface LayoutBreakpoints { - xs: number; - sm: number; - md: number; - lg: number; - xl: number; - xxl: number; -} - -export interface ResponsiveConfig { - breakpoints: LayoutBreakpoints; - mobileFirst: boolean; -} - -// Error types -export class AdminatorError extends Error { - constructor( - message: string, - public component?: string, - public code?: string - ) { - super(message); - this.name = 'AdminatorError'; - } -} - -// Plugin types -export interface PluginInterface { - name: string; - version: string; - dependencies?: string[]; - init(app: any): void; - destroy(): void; -} - -export interface PluginRegistry { - [key: string]: PluginInterface; -} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index f3d7fd3..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "moduleResolution": "node", - "allowJs": true, - "checkJs": false, - "outDir": "./dist", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "removeComments": false, - "importHelpers": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "allowSyntheticDefaultImports": true, - "noImplicitAny": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "exactOptionalPropertyTypes": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": false, - "noUncheckedIndexedAccess": false, - "baseUrl": "./src", - "paths": { - "@/*": ["*"], - "@/components/*": ["assets/scripts/components/*"], - "@/utils/*": ["assets/scripts/utils/*"], - "@/constants/*": ["assets/scripts/constants/*"] - } - }, - "include": [ - "src/**/*" - ], - "exclude": [ - "node_modules", - "dist", - "**/*.spec.ts", - "**/*.test.ts" - ] -} \ No newline at end of file diff --git a/webpack/plugins/htmlPlugin.js b/webpack/plugins/htmlPlugin.js index 9c32eb2..be97a6d 100755 --- a/webpack/plugins/htmlPlugin.js +++ b/webpack/plugins/htmlPlugin.js @@ -22,7 +22,6 @@ const titles = { '404': '404', '500': '500', 'basic-table': 'Basic Table', - 'test': 'Test', }; let minify = { diff --git a/webpack/rules/images.js b/webpack/rules/images.js index edf966f..4c74299 100755 --- a/webpack/rules/images.js +++ b/webpack/rules/images.js @@ -1,10 +1,8 @@ module.exports = { test : /\.(png|gif|jpg?g|svg)$/i, exclude : /(node_modules)/, - use : [{ - loader: 'file-loader', - options: { - outputPath: 'assets', - }, - }], + type : 'asset/resource', + generator: { + filename: 'assets/[name][ext]', + }, }; diff --git a/webpack/rules/index.js b/webpack/rules/index.js index 828388e..16105c6 100755 --- a/webpack/rules/index.js +++ b/webpack/rules/index.js @@ -1,6 +1,5 @@ module.exports = [ require('./js'), - require('./ts'), require('./images'), require('./css'), require('./sass'), diff --git a/webpack/rules/ts.js b/webpack/rules/ts.js deleted file mode 100644 index 10f5691..0000000 --- a/webpack/rules/ts.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - test: /\.tsx?$/, - exclude: /(node_modules|build|dist\/)/, - use: [ - { - loader: 'babel-loader', - }, - { - loader: 'ts-loader', - options: { - transpileOnly: true, - experimentalWatchApi: true, - }, - }, - ], -}; \ No newline at end of file