From 18b85815ce531b4e8d2bc63bf4825c2f437c4fc2 Mon Sep 17 00:00:00 2001 From: mahdahar <89adham@gmail.com> Date: Thu, 15 Jan 2026 10:44:09 +0700 Subject: [PATCH] refactor: standardize codebase with BaseModel and new conventions - Add BaseModel with automatic camel/snake case conversion - Add stringcase_helper with camel_to_snake(), snake_to_camel() functions - Update all models to extend BaseModel for consistent data handling - Update API controllers with standardized JSON response format - Remove legacy v1 PHP application directory - Consolidate documentation into AGENTS.md, delete VIEWS_RULES.md --- AGENTS.md | 865 +- README.md | 229 +- VIEWS_RULES.md | 531 - app/Config/Routes.php | 6 +- app/Controllers/Api/ControlApiController.php | 229 +- app/Controllers/Api/DeptApiController.php | 143 +- app/Controllers/Api/EntryApiController.php | 154 +- app/Controllers/Api/TestApiController.php | 156 +- app/Controllers/BaseController.php | 5 +- .../2026-01-14-000001_CreateCmodQcTables.php | 72 + app/Helpers/stringcase_helper.php | 47 + app/Models/BaseModel.php | 113 + app/Models/ControlModel.php | 30 +- app/Models/ControlTestModel.php | 10 +- app/Models/DailyResultModel.php | 28 +- app/Models/DeptModel.php | 12 +- app/Models/DictControlModel.php | 10 +- app/Models/DictDeptModel.php | 10 +- app/Models/DictTestModel.php | 10 +- app/Models/MonthlyCommentModel.php | 24 +- app/Models/ResultCommentModel.php | 10 +- app/Models/ResultModel.php | 10 +- app/Models/TestModel.php | 22 +- app/Views/control/index.php | 2 +- app/Views/dept/index.php | 2 +- app/Views/layout/main_layout.php | 30 +- app/Views/test/index.php | 2 +- app/Views/welcome_message.php | 331 - public/js/app.js | 13 + v1/assets/Chart.min.js | 13 - v1/assets/jquery.js | 4 - v1/assets/normalize.min.css | 349 - v1/assets/plotly.js | 78 - v1/assets/style_report.css | 16 - v1/assets/styles.css | 26 - v1/cmod-qc_script.sql | Bin 17640676 -> 0 bytes v1/cmod-qc_script_utf8.sql | 49594 ---------------- v1/config.php | 19 - v1/inc/control_add.php | 26 - v1/inc/control_del.php | 13 - v1/inc/control_edit.php | 45 - v1/inc/control_index.php | 26 - v1/inc/control_lotadd.php | 27 - v1/inc/ct_del.php | 8 - v1/inc/ct_edit.php | 29 - v1/inc/ct_view.php | 64 - v1/inc/entry.php | 99 - v1/inc/entry_ajax.php | 51 - v1/inc/entry_daily.php | 74 - v1/inc/entry_daily_1.php | 85 - v1/inc/entry_monthly.php | 192 - v1/inc/qc.php | 326 - v1/inc/report.php | 74 - v1/inc/report_1c.php | 145 - v1/inc/report_2c.php | 190 - v1/inc/report_3c.php | 204 - v1/inc/test_add.php.bak | 32 - v1/inc/test_del.php | 7 - v1/inc/test_edit.php | 72 - v1/inc/test_index.php | 28 - v1/inc/view.php | 113 - v1/inc/view_ajax.php | 55 - v1/index.php | 57 - v1/qc20260114.bak | Bin 8625664 -> 0 bytes 64 files changed, 1434 insertions(+), 53813 deletions(-) delete mode 100644 VIEWS_RULES.md create mode 100644 app/Helpers/stringcase_helper.php create mode 100644 app/Models/BaseModel.php delete mode 100644 app/Views/welcome_message.php delete mode 100644 v1/assets/Chart.min.js delete mode 100644 v1/assets/jquery.js delete mode 100644 v1/assets/normalize.min.css delete mode 100644 v1/assets/plotly.js delete mode 100644 v1/assets/style_report.css delete mode 100644 v1/assets/styles.css delete mode 100644 v1/cmod-qc_script.sql delete mode 100644 v1/cmod-qc_script_utf8.sql delete mode 100644 v1/config.php delete mode 100644 v1/inc/control_add.php delete mode 100644 v1/inc/control_del.php delete mode 100644 v1/inc/control_edit.php delete mode 100644 v1/inc/control_index.php delete mode 100644 v1/inc/control_lotadd.php delete mode 100644 v1/inc/ct_del.php delete mode 100644 v1/inc/ct_edit.php delete mode 100644 v1/inc/ct_view.php delete mode 100644 v1/inc/entry.php delete mode 100644 v1/inc/entry_ajax.php delete mode 100644 v1/inc/entry_daily.php delete mode 100644 v1/inc/entry_daily_1.php delete mode 100644 v1/inc/entry_monthly.php delete mode 100644 v1/inc/qc.php delete mode 100644 v1/inc/report.php delete mode 100644 v1/inc/report_1c.php delete mode 100644 v1/inc/report_2c.php delete mode 100644 v1/inc/report_3c.php delete mode 100644 v1/inc/test_add.php.bak delete mode 100644 v1/inc/test_del.php delete mode 100644 v1/inc/test_edit.php delete mode 100644 v1/inc/test_index.php delete mode 100644 v1/inc/view.php delete mode 100644 v1/inc/view_ajax.php delete mode 100644 v1/index.php delete mode 100644 v1/qc20260114.bak diff --git a/AGENTS.md b/AGENTS.md index ca17ce0..6ccfb87 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,340 +1,597 @@ -# AGENTS.md - QC Application Development Guide +# AGENTS.md - AI Agent Guidelines for [PROJECT NAME] -This document provides guidelines for agentic coding agents working on this PHP QC (Quality Control) application built with CodeIgniter 4. +## AI Agent Guidelines -## Project Overview +1. **Readability**: Write code that is easy to read and understand. +2. **Maintainability**: Write code that is easy to maintain and update. +3. **Performance**: Write code that is fast and efficient. +4. **Security**: Write code that is secure and protected against attacks. +5. **Testing**: Write code that is tested and verified. -This is a CodeIgniter 4 PHP application using SQL Server database for quality control data management. The app handles control tests, daily/monthly entries, and reporting. Uses Tailwind CSS and Alpine.js for UI. +## Technology Stack -## Build/Lint/Test Commands +| Layer | Technology | +|-------|------------| +| Backend | CodeIgniter 4 (PHP 8.1+) | +| Frontend | Alpine.js + TailwindCSS | +| Database | MySQL/MariaDB | -```bash -# PHP syntax check single file -php -l app/Controllers/Dashboard.php +## Key Files & Locations -# PHP syntax check all files recursively -find . -name "*.php" -exec php -l {} \; 2>&1 | grep -v "No syntax errors" +### Backend -# Run all PHPUnit tests -./vendor/bin/phpunit - -# Run single test class -./vendor/bin/phpunit tests/unit/HealthTest.php - -# Run single test method -./vendor/bin/phpunit tests/unit/HealthTest.php --filter=testIsDefinedAppPath - -# Run with coverage report -./vendor/bin/phpunit --coverage-html coverage/ - -# Start development server -php spark serve +``` +app/Controllers/ # API & page controllers +app/Models/ # Eloquent-style models +app/Database/Migrations/ # Schema definitions +app/Config/Routes.php # All routes defined here +app/Helpers/ # Helper functions ``` -## Code Style Guidelines +### Frontend -### General Principles +``` +app/Views/ # PHP views with Alpine.js +app/Views/layout/ # Base templates +public/ # Static assets (css, js) +``` -- Follow CodeIgniter 4 MVC patterns -- Maintain consistency with surrounding code -- Keep files focused (<200 lines preferred) -- Use clear, descriptive names +## Coding Conventions -### PHP Style +### PHP / CodeIgniter 4 -- Use `respond([ + 'status' => 'success', + 'message' => 'fetch success', + 'data' => $rows + ], 200); + ``` -### Naming Conventions +7. **Use camelCase for input/output**, snake_case for database: + - Controllers convert camel→snake before insert/update + - Models convert snake→camel after fetch + - Use helper functions: `camel_to_snake()`, `camel_to_snake_array()`, `snake_to_camel()` -- Classes: `PascalCase` (e.g., `Dashboard`, `DictTestModel`) -- Methods/functions: `$camelCase` (e.g., `getWithDept`, `saveResult`) -- Variables: `$camelCase` (e.g., `$dictTestModel`, `$resultData`) -- Constants: `UPPER_SNAKE_CASE` -- Views: `lowercase_with_underscores` (e.g., `dashboard.php`, `test_index.php`) -- Routes: kebab-case URLs (e.g., `/test/edit/(:num)` → `/test/edit/1`) +### Database -### CodeIgniter 4 Patterns +1. **Primary keys**: `{table_singular}_id` (e.g., `item_id`, `pat_id`) +2. **Foreign keys**: Match the referenced primary key name +3. **Naming**: All lowercase, underscores +4. **Soft deletes**: All tables have `deleted_at` DATETIME column +5. **Master data tables**: Prefix with `master_` (e.g., `master_items`) +6. **Timestamps**: `created_at`, `updated_at` DATETIME columns +7. **Unique constraints**: Add on code fields (e.g., `item_code`) + +### Frontend / Alpine.js + +1. **x-data** on container elements +2. **Fetch API** for AJAX calls (no jQuery) +3. **DaisyUI components** for UI elements +4. **camelCase** for JavaScript, **snake_case** for PHP/DB +5. **Modals** with x-show and x-transition +6. **ES6 modules** importing Alpine from `app.js` + +### File Naming + +| Component | Pattern | Example | +|-----------|---------|---------| +| Controller | `PascalCase + Controller` | `ItemsController` | +| Model | `PascalCase + Model` | `ItemsModel` | +| Migration | `YYYY-MM-DD-XXXXXX_Description.php` | `2026-01-15-000001_Items.php` | +| View | `module/action.php` | `items/index.php` | +| Helper | `snake_case + _helper.php` | `stringcase_helper.php` | +| Filter | `PascalCase + Filter.php` | `JwtAuthFilter.php` | + +### Directory Structure + +``` +app/ +├── Config/ +│ ├── Routes.php +│ └── Filters.php +├── Controllers/ +│ ├── BaseController.php +│ ├── ItemsController.php +│ └── Master/ +│ └── ItemsController.php +├── Database/ +│ └── Migrations/ +├── Filters/ +│ └── JwtAuthFilter.php +├── Helpers/ +│ ├── stringcase_helper.php +│ └── utc_helper.php +├── Models/ +│ ├── BaseModel.php +│ ├── ItemsModel.php +│ └── Master/ +│ └── ItemsModel.php +└── Views/ + ├── layout/ + │ ├── main_layout.php + │ └── form_layout.php + ├── items/ + │ ├── items_index.php + │ └── dialog_items_form.php + └── login.php +``` + +## Common Tasks + +### Adding a New Master Data Entity + +1. Create migration in `app/Database/Migrations/` +2. Create model in `app/Models/[Module]/` +3. Create controller in `app/Controllers/[Module]/` +4. Add routes in `app/Config/Routes.php` +5. Create view in `app/Views/[module]/` + +### Adding a New API Endpoint -**Controllers** extend `App\Controllers\BaseController`: ```php -namespace App\Controllers; - -use App\Models\DictTestModel; - -class Test extends BaseController -{ - protected $dictTestModel; - - public function __construct() - { - $this->dictTestModel = new DictTestModel(); - } - - public function index(): string - { - $data = [ - 'title' => 'Test Dictionary', - 'tests' => $this->dictTestModel->findAll(), - ]; - - return view('layout', [ - 'content' => view('test/index', $data), - 'page_title' => 'Test Dictionary', - 'active_menu' => 'test' - ]); - } -} +// In Routes.php +$routes->get('api/resource', 'ResourceController::index'); +$routes->get('api/resource/(:num)', 'ResourceController::show/$1'); +$routes->post('api/resource', 'ResourceController::create'); +$routes->patch('api/resource/(:num)', 'ResourceController::update/$1'); ``` -**Models** extend `CodeIgniter\Model`: -```php -namespace App\Models; +### Controller Template -use CodeIgniter\Model; - -class TestModel extends Model -{ - protected $table = 'dict_test'; - protected $primaryKey = 'id'; - protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['deptid', 'name', 'unit', 'method']; -} -``` - -**Views** use PHP short tags `` for output: -```php -
-

- -
- -
-``` - -### Database Operations - -- Configure connections in `app/Config/Database.php` -- Use CodeIgniter's Query Builder for queries -- Use parameterized queries to prevent SQL injection: - ```php - $builder = $this->db->table('results'); - $builder->select('*'); - $builder->where('control_ref_id', $controlId); - $results = $builder->get()->getResultArray(); - ``` -- For SQL Server, set `DBDriver` to `'SQLSRV'` in config - -### Error Handling - -- Use CodeIgniter's exception handling: `throw new \CodeIgniter\Exceptions\PageNotFoundException('Not found')` -- Return JSON responses for AJAX endpoints: - ```php - return $this->response->setJSON(['success' => true, 'data' => $results]); - ``` -- Use `log_message('error', $message)` for logging -- Validate input with `$this->validate()` in controllers - -### Frontend (Tailwind CSS + Alpine.js) - -The layout already includes Tailwind via CDN and Alpine.js: -```html - - -``` - -**Common JavaScript (`public/js/app.js`):** -- Contains global `App` object with shared utilities -- Handles sidebar toggle functionality -- Provides `App.showToast()`, `App.confirmSave()`, `App.closeAllModals()` -- Initialize with `App.init()` on DOMContentLoaded - -**Page-Specific Alpine.js:** -- Complex Alpine.js components should be defined inline in the view PHP file -- Use `x-data` with an object containing all properties and methods -- Example: - ```html -
- -
- ``` - -### File Organization - -- Controllers: `app/Controllers/` -- Models: `app/Models/` -- Views: `app/Views/` (subfolders for modules: `entry/`, `test/`, `control/`, `report/`, `dept/`) -- Config: `app/Config/` -- Routes: `app/Config/Routes.php` - -### Modal-based CRUD Pattern - -All CRUD operations use a single modal dialog file (`dialog.php`) that handles both add and edit modes. - -**File Naming:** -- Single dialog: `dialog.php` (no `_add` or `_edit` suffix) - -**Controller Pattern:** -```php -class Dept extends BaseController -{ - protected $dictDeptModel; - - public function __construct() - { - $this->dictDeptModel = new DictDeptModel(); - } - - public function index(): string - { - $data = [ - 'title' => 'Department Dictionary', - 'depts' => $this->dictDeptModel->findAll(), - ]; - - return view('layout', [ - 'content' => view('dept/index', $data), - 'page_title' => 'Department Dictionary', - 'active_menu' => 'dept' - ]); - } - - public function save(): \CodeIgniter\HTTP\RedirectResponse - { - $data = ['name' => $this->request->getPost('name')]; - $this->dictDeptModel->insert($data); - return redirect()->to('/dept'); - } - - public function update($id): \CodeIgniter\HTTP\RedirectResponse - { - $data = ['name' => $this->request->getPost('name')]; - $this->dictDeptModel->update($id, $data); - return redirect()->to('/dept'); - } - - public function delete($id): \CodeIgniter\HTTP\RedirectResponse - { - $this->dictDeptModel->delete($id); - return redirect()->to('/dept'); - } -} -``` - -**Dialog View Pattern (`dialog.php`):** ```php +namespace App\Controllers\Module; -
- - - +use CodeIgniter\API\ResponseTrait; +use App\Controllers\BaseController; +use App\Models\Module\ItemModel; - -
-``` +class ItemsController extends BaseController { + use ResponseTrait; -**Index View Pattern (`index.php`):** -```php -
- - - - - - - - - - -
- - -
-
+ protected $model; + protected $rules; - - + public function __construct() { + $this->model = new ItemsModel(); + $this->rules = [ + 'itemCode' => 'required|min_length[1]', + 'itemName' => 'required', + ]; + } - + } + + public function show($id = null) { + try { + $rows = $this->model->where('item_id', $id)->findAll(); + if (empty($rows)) { + return $this->respond([ + 'status' => 'success', + 'message' => 'data not found.' + ], 200); + } + return $this->respond([ + 'status' => 'success', + 'message' => 'fetch success', + 'data' => $rows + ], 200); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } + + public function create() { + $input = $this->request->getJSON(true); + $input = camel_to_snake_array($input); + if (!$this->validate($this->rules)) { + return $this->failValidationErrors($this->validator->getErrors()); + } + try { + $id = $this->model->insert($input, true); + return $this->respondCreated([ + 'status' => 'success', + 'message' => $id + ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } + + public function update($id = null) { + $input = $this->request->getJSON(true); + $input = camel_to_snake_array($input); + if (!$this->validate($this->rules)) { + return $this->failValidationErrors($this->validator->getErrors()); + } + try { + $this->model->update($id, $input); + return $this->respondCreated([ + 'status' => 'success', + 'message' => 'update success', + 'data' => $id + ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } +} ``` -**Searchable Multi-Select:** -- Use Select2 for searchable dropdowns (already included in layout.php) -- Initialize with: `$('#selectId').select2({ placeholder: 'Search...', allowClear: true })` +### Model Template -### Security Considerations +```php +validate('csrf')`) -- Escape all output in views with `` (auto-escaped) -- Use `$this->request->getPost()` instead of `$_POST` -- Never commit `.env` files with credentials +use App\Models\BaseModel; -## Common Operations +class ItemsModel extends BaseModel { + protected $table = 'module_items'; + protected $primaryKey = 'item_id'; + protected $allowedFields = [ + 'item_code', + 'item_name', + 'created_at', + 'updated_at', + 'deleted_at' + ]; + protected $useTimestamps = true; + protected $useSoftDeletes = true; -**Add a new CRUD resource:** -1. Create model in `app/Models/` -2. Create controller in `app/Controllers/` -3. Add routes in `app/Config/Routes.php` -4. Create views in `app/Views/[module]/` + public function getItems($keyword = null) { + if ($keyword) { + return $this->groupStart() + ->like('item_code', $keyword) + ->orLike('item_name', $keyword) + ->groupEnd() + ->findAll(); + } + return $this->findAll(); + } +} +``` -**Add a menu item:** -- Add to sidebar in `app/Views/layout.php` -- Add route in `app/Config/Routes.php` -- Create controller method -- Set `active_menu` parameter in view() call +### Migration Template + +```php +forge->addField([ + 'item_id' => [ + 'type' => 'int', + 'unsigned' => true, + 'auto_increment' => true + ], + 'item_code' => [ + 'type' => 'VARCHAR', + 'constraint' => 50 + ], + 'item_name' => [ + 'type' => 'VARCHAR', + 'constraint' => 150 + ], + 'created_at' => [ + 'type' => 'DATETIME', + 'null' => true + ], + 'updated_at' => [ + 'type' => 'DATETIME', + 'null' => true + ], + 'deleted_at' => [ + 'type' => 'DATETIME', + 'null' => true + ] + ]); + $this->forge->addKey('item_id', true); + $this->forge->addUniqueKey('item_code'); + $this->forge->createTable('module_items'); + } + + public function down() { + $this->forge->dropTable('module_items', true); + } +} +``` + +### Routes Template + +```php +post('/login', 'AuthController::login'); +$routes->get('/logout', 'AuthController::logout'); + +$routes->group('', ['filter' => 'jwt-auth'], function ($routes) { + $routes->get('/', 'PagesController::dashboard'); + $routes->get('/module', 'PagesController::module'); + $routes->get('/master/items', 'PagesController::masterItems'); +}); + +$routes->group('api', function ($routes) { + $routes->get('module/items', 'Module\ItemsController::index'); + $routes->get('module/items/(:num)', 'Module\ItemsController::show/$1'); + $routes->post('module/items', 'Module\ItemsController::create'); + $routes->patch('module/items/(:num)', 'Module\ItemsController::update/$1'); +}); +``` + +### View Template (Index with Alpine.js) + +```php +extend("layout/main_layout"); ?> + +section("content"); ?> +
+
+
+

Items

+

Manage your items

+
+ +
+ +
+
+
+ + +
+ +
+
+ +
+ +
+ + include('module/items/dialog_items_form'); ?> +
+endSection(); ?> + +section("script"); ?> + +endSection(); ?> +``` + +### Running Migrations + +```bash +php spark migrate # Run all pending +php spark migrate:rollback # Rollback last batch +php spark migrate:refresh # Rollback all + re-run +``` + +## Testing + +```bash +# Run all tests +./vendor/bin/phpunit + +# Run specific test file +./vendor/bin/phpunit tests/unit/SomeTest.php +``` + +## Things to Avoid + +1. **Don't use jQuery** - Use Alpine.js or vanilla JS +2. **Don't over-engineer** - This is a "no-nonsense" project +3. **Don't skip soft deletes** - Always use `deleted_at` +4. **Don't hardcode** - Use `.env` for configuration +5. **Don't mix concerns** - Controllers handle HTTP, Models handle data +6. **Don't forget camel/snake conversion** - Frontend uses camelCase, DB uses snake_case + +## Questions to Ask Before Making Changes + +1. Does this follow the existing patterns? +2. Is there a simpler way to do this? +3. Did I add the route? +4. Did I handle errors gracefully? +5. Does the API response match the standard format? +6. Did I convert camelCase to snake_case before DB operations? +7. Did I convert snake_case to camelCase after fetching? + +## Post-Change Requirements + +**After every significant code change, update `README.md`:** + +| Change Type | README Section to Update | +|-------------|--------------------------| +| New Controller | Project Structure, API Endpoints | +| New Model | Project Structure | +| New Migration/Table | Database Schema | +| New View | Project Structure | +| New Route | API Endpoints | +| New Command | Development Commands | +| Config Change | Setup | + +Keep the README accurate and up-to-date with the actual codebase. diff --git a/README.md b/README.md index d14b4c9..b43eb20 100644 --- a/README.md +++ b/README.md @@ -1,68 +1,207 @@ -# CodeIgniter 4 Application Starter +# TinyQC - Quality Control Management System -## What is CodeIgniter? +A CodeIgniter 4 PHP application for quality control data management in laboratory settings. Built with Tailwind CSS, Alpine.js, and DaisyUI. -CodeIgniter is a PHP full-stack web framework that is light, fast, flexible and secure. -More information can be found at the [official site](https://codeigniter.com). +## Features -This repository holds a composer-installable app starter. -It has been built from the -[development repository](https://github.com/codeigniter4/CodeIgniter4). +- **Dictionary Management**: Maintain departments, tests, and control parameters +- **Control Management**: Configure and manage quality control standards +- **Daily Entries**: Record daily quality control test results +- **Monthly Entries**: Aggregate and track monthly quality control data +- **Comments System**: Add notes and comments to results +- **Reporting**: Generate quality control reports and analysis -More information about the plans for version 4 can be found in [CodeIgniter 4](https://forum.codeigniter.com/forumdisplay.php?fid=28) on the forums. +## Technology Stack -You can read the [user guide](https://codeigniter.com/user_guide/) -corresponding to the latest version of the framework. +| Layer | Technology | +|-------|------------| +| Backend | CodeIgniter 4 (PHP 8.1+) | +| Database | SQL Server | +| Frontend | TailwindCSS + Alpine.js + DaisyUI | +| Icons | FontAwesome 7 | +| Testing | PHPUnit | -## Installation & updates +## Requirements -`composer create-project codeigniter4/appstarter` then `composer update` whenever -there is a new release of the framework. +- PHP 8.1 or higher +- SQL Server 2016+ +- Composer +- Web server (Apache/Nginx/IIS) -When updating, check the release notes to see if there are any changes you might need to apply -to your `app` folder. The affected files can be copied or merged from -`vendor/codeigniter4/framework/app`. +## Installation -## Setup +1. **Clone the repository** + ```bash + git clone tinyqc + cd tinyqc + ``` -Copy `env` to `.env` and tailor for your app, specifically the baseURL -and any database settings. +2. **Install dependencies** + ```bash + composer install + ``` -## Important Change with index.php +3. **Configure environment** + ```bash + copy env .env + ``` + Edit `.env` with your database settings: + ```env + database.default.hostname = localhost + database.default.port = 1433 + database.default.database = tinyqc + database.default.username = sa + database.default.password = your_password + database.default.DBDriver = SQLSRV + ``` -`index.php` is no longer in the root of the project! It has been moved inside the *public* folder, -for better security and separation of components. +4. **Set up database** + - Create a new SQL Server database + - Run migrations if applicable + - Seed initial data if needed -This means that you should configure your web server to "point" to your project's *public* folder, and -not to the project root. A better practice would be to configure a virtual host to point there. A poor practice would be to point your web server to the project root and expect to enter *public/...*, as the rest of your logic and the -framework are exposed. +5. **Configure web server** + Point your web server to the `public` directory: + ```apache + + ServerName tinyqc.local + DocumentRoot "D:/data/www/tinyqc/public" + + AllowOverride All + Require all granted + + + ``` -**Please** read the user guide for a better explanation of how CI4 works! +6. **Access the application** + Open http://localhost in your browser -## Repository Management +## Project Structure -We use GitHub issues, in our main repository, to track **BUGS** and to track approved **DEVELOPMENT** work packages. -We use our [forum](http://forum.codeigniter.com) to provide SUPPORT and to discuss -FEATURE REQUESTS. +``` +tinyqc/ +├── app/ +│ ├── Config/ # Configuration files +│ │ ├── Database.php # Database settings +│ │ └── Routes.php # Route definitions +│ ├── Controllers/ # Application controllers +│ │ ├── Api/ # API controllers +│ │ ├── Dashboard.php +│ │ ├── Dept.php +│ │ ├── Test.php +│ │ ├── Control.php +│ │ ├── Entry.php +│ │ ├── PageController.php +│ │ └── Report.php +│ ├── Models/ # Database models +│ │ ├── DictDeptModel.php +│ │ ├── DictTestModel.php +│ │ ├── DictControlModel.php +│ │ ├── ControlModel.php +│ │ ├── ControlTestModel.php +│ │ ├── DailyResultModel.php +│ │ └── ... +│ └── Views/ # View templates +│ ├── layout/ # Layout templates +│ ├── dashboard.php +│ ├── dept/ # Department views +│ ├── test/ # Test views +│ ├── control/ # Control views +│ ├── entry/ # Entry views +│ └── report/ # Report views +├── public/ # Web root +├── tests/ # Unit tests +├── writable/ # Writable directory +├── env # Environment template +├── composer.json +└── phpunit.xml.dist +``` -This repository is a "distribution" one, built by our release preparation script. -Problems with it can be raised on our forum, or as issues in the main repository. +## Usage -## Server Requirements +### Dashboard +The main dashboard provides an overview of quality control status and quick access to all modules. -PHP version 8.1 or higher is required, with the following extensions installed: +### Dictionary Management -- [intl](http://php.net/manual/en/intl.requirements.php) -- [mbstring](http://php.net/manual/en/mbstring.installation.php) +- **Departments**: Manage department/category entries +- **Tests**: Maintain test parameters and specifications +- **Controls**: Configure control standards and limits -> [!WARNING] -> - The end of life date for PHP 7.4 was November 28, 2022. -> - The end of life date for PHP 8.0 was November 26, 2023. -> - If you are still using PHP 7.4 or 8.0, you should upgrade immediately. -> - The end of life date for PHP 8.1 will be December 31, 2025. +### Data Entry -Additionally, make sure that the following extensions are enabled in your PHP: +- **Daily Entry**: Record daily QC test results +- **Monthly Entry**: Aggregate monthly data and comments -- json (enabled by default - don't turn it off) -- [mysqlnd](http://php.net/manual/en/mysqlnd.install.php) if you plan to use MySQL -- [libcurl](http://php.net/manual/en/curl.requirements.php) if you plan to use the HTTP\CURLRequest library +### Reports + +Generate quality control reports based on: +- Date ranges +- Test types +- Control parameters + +## API Endpoints + +| Method | Endpoint | Description | +|--------|----------|-------------| +| GET | /api/dept | List departments | +| GET | /api/dept/:id | Get department details | +| POST | /api/dept | Create department | +| PUT | /api/dept/:id | Update department | +| DELETE | /api/dept/:id | Delete department | +| GET | /api/test | List tests | +| GET | /api/test/:id | Get test details | +| POST | /api/test | Create test | +| PUT | /api/test/:id | Update test | +| DELETE | /api/test/:id | Delete test | +| GET | /api/control | List controls | +| GET | /api/control/:id | Get control details | +| POST | /api/control | Create control | +| PUT | /api/control/:id | Update control | +| DELETE | /api/control/:id | Delete control | +| GET | /api/entry/controls | Get controls for entry | +| GET | /api/entry/tests | Get tests for entry | +| POST | /api/entry/daily | Save daily result | +| POST | /api/entry/monthly | Save monthly entry | +| POST | /api/entry/comment | Save comment | + +## Development + +### Running Tests + +```bash +# Run all tests +./vendor/bin/phpunit + +# Run with coverage +./vendor/bin/phpunit --coverage-html coverage/ +``` + +### Code Style + +Follow these guidelines: +- PSR-12 coding standards +- CamelCase for variables/functions +- PascalCase for classes +- snake_case for database tables/columns + +### Adding New Features + +1. Create model in `app/Models/` +2. Create API controller in `app/Controllers/Api/` +3. Add routes in `app/Config/Routes.php` +4. Create views in `app/Views/[module]/` +5. Add menu item in layout if needed + +## Documentation + +- [agent1.md](agent1.md) - Complete development guide +- [VIEWS_RULES.md](VIEWS_RULES.md) - View patterns and conventions + +## License + +This project is proprietary software. + +## Support + +For support, please contact the development team. diff --git a/VIEWS_RULES.md b/VIEWS_RULES.md deleted file mode 100644 index 36d8feb..0000000 --- a/VIEWS_RULES.md +++ /dev/null @@ -1,531 +0,0 @@ -# TinyLab View Rules - -This document defines the view patterns and conventions used in TinyLab. Follow these rules when creating new views or modifying existing ones. - -## 1. Directory Structure - -``` -app/Views/ -├── layout/ -│ ├── main_layout.php # Primary app layout (sidebar, navbar, dark mode) -│ └── form_layout.php # Lightweight layout for standalone forms -├── [module_name]/ # Feature module (e.g., patients, requests) -│ ├── index.php # Main list page -│ ├── dialog_form.php # Modal form (Create/Edit) -│ └── drawer_filter.php # Filter drawer (optional) -├── master/ -│ └── [entity]/ # Master data entity (e.g., doctors, samples) -│ ├── index.php -│ └── dialog_form.php -└── errors/ - └── html/ - ├── error_404.php - └── error_exception.php -``` - -## 2. Layout Extension - -All pages must extend the appropriate layout: - -```php -extend("layout/main_layout"); ?> -section("content") ?> - -endSection(); ?> -section("script") ?> - -endSection(); ?> -``` - -Use `form_layout.php` for standalone pages like login: -```php -extend("layout/form_layout"); ?> -``` - -## 3. Alpine.js Integration - -### 3.1 Component Definition - -Always use `alpine:init` event listener: - -```php -section("script") ?> - -endSection(); ?> -``` - -### 3.2 Alpine Data Attribute - -Wrap page content in the component: - -```php -
- -
-``` - -## 4. Modal/Dialog Pattern - -### 4.1 Standard Modal Structure - -```php - -
-
- - -
-
- -
-

- -
- - -
-
- -
-
- - -

-
-
-
- - -
- - -
-
-
-
-``` - -## 5. Page Structure Pattern - -### 5.1 Standard CRUD Page - -```php -extend("layout/main_layout"); ?> -section("content") ?> -
- -
-
-

Module Title

-

Module description

-
- -
- - -
-
-
- - -
- -
-
- - -
-
- - -
-
- - -
- - - - - - - - -
- - - include('module/dialog_form'); ?> -
-endSection(); ?> -``` - -### 5.2 Master-Detail Pattern - -```php - -
- -
-
- -
-
- -
-
- - -
- - -
-
-``` - -## 6. Form Field Patterns - -### 6.1 Input with Icon -```php -
- - -
-``` - -### 6.2 Select Dropdown -```php - -``` - -### 6.3 Checkbox -```php - -``` - -### 6.4 Radio Group -```php -
- -
-``` - -## 7. Status Badges - -```php - - -``` - -## 8. CSS Classes Reference - -### Layout -- `flex`, `flex-col`, `grid`, `grid-cols-2`, `gap-4` -- `w-full`, `max-w-2xl`, `min-h-0` -- `overflow-hidden`, `overflow-y-auto` - -### Spacing -- `p-4`, `px-6`, `py-3`, `m-4`, `mb-6` -- `space-x-4`, `gap-3` - -### Typography -- `text-sm`, `text-xs`, `text-lg`, `text-2xl` -- `font-medium`, `font-semibold`, `font-bold` -- `text-slate-500`, `text-slate-800` - -### Borders & Backgrounds -- `bg-white`, `bg-slate-50`, `bg-blue-50` -- `border`, `border-slate-100`, `border-red-300` -- `rounded-lg`, `rounded-xl`, `rounded-2xl` - -### Components -- `btn btn-primary`, `btn btn-ghost` -- `checkbox checkbox-sm` -- `radio radio-primary` -- `input`, `select`, `textarea` - -### Icons -FontAwesome 7 via CDN: `` - -## 9. API Response Format - -Views expect API responses in this format: - -```json -{ - "status": "success", - "message": "Operation successful", - "data": [...] -} -``` - -## 10. Validation Pattern - -```javascript -validate() { - this.errors = {}; - - if (!this.form.field1) { - this.errors.field1 = 'Field 1 is required'; - } - if (!this.form.field2) { - this.errors.field2 = 'Field 2 is required'; - } - if (this.form.field3 && !/^\d+$/.test(this.form.field3)) { - this.errors.field3 = 'Must be numeric'; - } - - return Object.keys(this.errors).length === 0; -} -``` - -## 11. Error Handling - -```javascript -async save() { - this.loading = true; - try { - const res = await fetch(url, { ... }); - const data = await res.json(); - if (data.status === 'success') { - this.showToast('Saved successfully'); - this.fetchList(); - } else { - this.error = data.message || 'An error occurred'; - } - } catch (err) { - this.error = 'Network error. Please try again.'; - console.error(err); - } finally { - this.loading = false; - } -} -``` - -## 12. Quick Reference: File Templates - -### Standard List Page Template -See: `app/Views/master/doctors/doctors_index.php` - -### Modal Form Template -See: `app/Views/master/doctors/dialog_doctors_form.php` - -### Master-Detail Page Template -See: `app/Views/patients/patients_index.php` - -### Result Entry Table Template -See: `app/Views/requests/dialog_result_entry.php` - -## 13. Checklist for New Views - -- [ ] Create view file in correct directory -- [ ] Extend appropriate layout (`main_layout` or `form_layout`) -- [ ] Define `content` and `script` sections -- [ ] Wrap content in `x-data` component -- [ ] Include modal form if needed -- [ ] Use DaisyUI components for buttons, inputs, selects -- [ ] Add loading and empty states -- [ ] Implement proper error handling -- [ ] Use FontAwesome icons consistently -- [ ] Follow naming conventions (snake_case for PHP, camelCase for JS) - -## 14. Conventions Summary - -| Aspect | Convention | -|--------|------------| -| File naming | snake_case (e.g., `patients_index.php`) | -| PHP variables | snake_case | -| JavaScript variables | camelCase | -| HTML classes | kebab-case (Tailwind) | -| Icons | FontAwesome 7 | -| UI Framework | TailwindCSS + DaisyUI | -| State management | Alpine.js | -| API format | JSON with `status`, `message`, `data` | -| Primary key | `{table}_id` (e.g., `pat_id`) | -| Soft deletes | All tables use `deleted_at` | diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 96d5e0a..86276b9 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -19,20 +19,20 @@ $routes->group('api', function ($routes) { $routes->get('dept', 'Api\DeptApiController::index'); $routes->get('dept/(:num)', 'Api\DeptApiController::show/$1'); $routes->post('dept', 'Api\DeptApiController::store'); - $routes->put('dept/(:num)', 'Api\DeptApiController::update/$1'); + $routes->patch('dept/(:num)', 'Api\DeptApiController::update/$1'); $routes->delete('dept/(:num)', 'Api\DeptApiController::delete/$1'); $routes->get('test', 'Api\TestApiController::index'); $routes->get('test/(:num)', 'Api\TestApiController::show/$1'); $routes->post('test', 'Api\TestApiController::store'); - $routes->put('test/(:num)', 'Api\TestApiController::update/$1'); + $routes->patch('test/(:num)', 'Api\TestApiController::update/$1'); $routes->delete('test/(:num)', 'Api\TestApiController::delete/$1'); $routes->get('control', 'Api\ControlApiController::index'); $routes->get('control/(:num)', 'Api\ControlApiController::show/$1'); $routes->get('control/(:num)/tests', 'Api\ControlApiController::getTests/$1'); $routes->post('control', 'Api\ControlApiController::store'); - $routes->put('control/(:num)', 'Api\ControlApiController::update/$1'); + $routes->patch('control/(:num)', 'Api\ControlApiController::update/$1'); $routes->delete('control/(:num)', 'Api\ControlApiController::delete/$1'); $routes->get('entry/controls', 'Api\EntryApiController::getControls'); diff --git a/app/Controllers/Api/ControlApiController.php b/app/Controllers/Api/ControlApiController.php index 09b5de7..89389bb 100644 --- a/app/Controllers/Api/ControlApiController.php +++ b/app/Controllers/Api/ControlApiController.php @@ -10,142 +10,137 @@ class ControlApiController extends BaseController { protected $dictControlModel; protected $controlTestModel; + protected $rules; public function __construct() { $this->dictControlModel = new DictControlModel(); $this->controlTestModel = new ControlTestModel(); + $this->rules = [ + 'name' => 'required|min_length[1]', + 'dept_ref_id' => 'required', + ]; } public function index() { - $controls = $this->dictControlModel->getWithDept(); - return $this->response->setJSON([ - 'status' => 'success', - 'message' => 'Controls fetched successfully', - 'data' => $controls - ]); - } - - public function show($id) - { - $control = $this->dictControlModel->find($id); - if (!$control) { - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Control not found' - ])->setStatusCode(404); - } - return $this->response->setJSON([ - 'status' => 'success', - 'data' => $control - ]); - } - - public function getTests($id) - { - $tests = $this->controlTestModel->where('control_ref_id', $id)->findAll(); - $testIds = array_column($tests, 'test_ref_id'); - - return $this->response->setJSON([ - 'status' => 'success', - 'data' => $testIds - ]); - } - - public function store() - { - $post = $this->request->getJSON(true); - - $controlData = [ - 'dept_ref_id' => $post['dept_ref_id'] ?? null, - 'name' => $post['name'] ?? '', - 'lot' => $post['lot'] ?? '', - 'producer' => $post['producer'] ?? '', - 'expdate' => $post['expdate'] ?? null, - ]; - - $controlId = $this->dictControlModel->insert($controlData, true); - - if (!empty($post['test_ids'])) { - foreach ($post['test_ids'] as $testId) { - $this->controlTestModel->insert([ - 'control_ref_id' => $controlId, - 'test_ref_id' => $testId, - 'mean' => 0, - 'sd' => 0, - ]); - } - } - - if ($controlId) { - return $this->response->setJSON([ + try { + $rows = $this->dictControlModel->getWithDept(); + return $this->respond([ 'status' => 'success', - 'message' => 'Control saved successfully', - 'data' => ['control_id' => $controlId] - ]); + 'message' => 'fetch success', + 'data' => $rows + ], 200); + } catch (\Exception $e) { + return $this->failServerError('Exception: ' . $e->getMessage()); } - - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to save control' - ])->setStatusCode(500); } - public function update($id) + public function show($id = null) { - $post = $this->request->getJSON(true); - - $controlData = [ - 'dept_ref_id' => $post['dept_ref_id'] ?? null, - 'name' => $post['name'] ?? '', - 'lot' => $post['lot'] ?? '', - 'producer' => $post['producer'] ?? '', - 'expdate' => $post['expdate'] ?? null, - ]; + try { + $rows = $this->dictControlModel->where('control_id', $id)->findAll(); + if (empty($rows)) { + return $this->respond([ + 'status' => 'success', + 'message' => 'data not found.' + ], 200); + } + return $this->respond([ + 'status' => 'success', + 'message' => 'fetch success', + 'data' => $rows + ], 200); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } - $success = $this->dictControlModel->update($id, $controlData); + public function getTests($id = null) + { + try { + $rows = $this->controlTestModel->where('control_ref_id', $id)->findAll(); + return $this->respond([ + 'status' => 'success', + 'message' => 'fetch success', + 'data' => $rows + ], 200); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } - if (!empty($post['test_ids'])) { + public function create() + { + $input = $this->request->getJSON(true); + if (!$this->validate($this->rules)) { + return $this->failValidationErrors($this->validator->getErrors()); + } + try { + $controlId = $this->dictControlModel->insert($input, true); + + if (!empty($input['test_ids'])) { + foreach ($input['test_ids'] as $testId) { + $this->controlTestModel->insert([ + 'control_ref_id' => $controlId, + 'test_ref_id' => $testId, + 'mean' => 0, + 'sd' => 0, + ]); + } + } + + return $this->respondCreated([ + 'status' => 'success', + 'message' => $controlId + ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } + + public function update($id = null) + { + $input = $this->request->getJSON(true); + if (!$this->validate($this->rules)) { + return $this->failValidationErrors($this->validator->getErrors()); + } + try { + $this->dictControlModel->update($id, $input); + + if (!empty($input['test_ids'])) { + $this->controlTestModel->where('control_ref_id', $id)->delete(); + foreach ($input['test_ids'] as $testId) { + $this->controlTestModel->insert([ + 'control_ref_id' => $id, + 'test_ref_id' => $testId, + 'mean' => 0, + 'sd' => 0, + ]); + } + } + + return $this->respond([ + 'status' => 'success', + 'message' => 'update success', + 'data' => $id + ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } + + public function delete($id = null) + { + try { $this->controlTestModel->where('control_ref_id', $id)->delete(); - foreach ($post['test_ids'] as $testId) { - $this->controlTestModel->insert([ - 'control_ref_id' => $id, - 'test_ref_id' => $testId, - 'mean' => 0, - 'sd' => 0, - ]); - } - } - - if ($success) { - return $this->response->setJSON([ + $this->dictControlModel->delete($id); + return $this->respond([ 'status' => 'success', - 'message' => 'Control updated successfully' + 'message' => 'delete success' ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); } - - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to update control' - ])->setStatusCode(500); - } - - public function delete($id) - { - $this->controlTestModel->where('control_ref_id', $id)->delete(); - $success = $this->dictControlModel->delete($id); - - if ($success) { - return $this->response->setJSON([ - 'status' => 'success', - 'message' => 'Control deleted successfully' - ]); - } - - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to delete control' - ])->setStatusCode(500); } } diff --git a/app/Controllers/Api/DeptApiController.php b/app/Controllers/Api/DeptApiController.php index ffdfd6c..a7c701d 100644 --- a/app/Controllers/Api/DeptApiController.php +++ b/app/Controllers/Api/DeptApiController.php @@ -8,98 +8,95 @@ use App\Models\DictDeptModel; class DeptApiController extends BaseController { protected $dictDeptModel; + protected $rules; public function __construct() { $this->dictDeptModel = new DictDeptModel(); + $this->rules = [ + 'name' => 'required|min_length[1]', + ]; } public function index() { - $depts = $this->dictDeptModel->findAll(); - return $this->response->setJSON([ - 'status' => 'success', - 'message' => 'Departments fetched successfully', - 'data' => $depts - ]); - } - - public function show($id) - { - $dept = $this->dictDeptModel->find($id); - if (!$dept) { - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Department not found' - ])->setStatusCode(404); - } - return $this->response->setJSON([ - 'status' => 'success', - 'data' => $dept - ]); - } - - public function store() - { - $post = $this->request->getJSON(true); - - $data = [ - 'name' => $post['name'] ?? '', - ]; - - $id = $this->dictDeptModel->insert($data); - - if ($id) { - return $this->response->setJSON([ + try { + $rows = $this->dictDeptModel->findAll(); + return $this->respond([ 'status' => 'success', - 'message' => 'Department saved successfully', - 'data' => ['dept_id' => $id] - ]); + 'message' => 'fetch success', + 'data' => $rows + ], 200); + } catch (\Exception $e) { + return $this->failServerError('Exception: ' . $e->getMessage()); } - - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to save department' - ])->setStatusCode(500); } - public function update($id) + public function show($id = null) { - $post = $this->request->getJSON(true); - - $data = [ - 'name' => $post['name'] ?? '', - ]; - - $success = $this->dictDeptModel->update($id, $data); - - if ($success) { - return $this->response->setJSON([ + try { + $rows = $this->dictDeptModel->where('dept_id', $id)->findAll(); + if (empty($rows)) { + return $this->respond([ + 'status' => 'success', + 'message' => 'data not found.' + ], 200); + } + return $this->respond([ 'status' => 'success', - 'message' => 'Department updated successfully' - ]); + 'message' => 'fetch success', + 'data' => $rows + ], 200); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); } - - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to update department' - ])->setStatusCode(500); } - public function delete($id) + public function create() { - $success = $this->dictDeptModel->delete($id); - - if ($success) { - return $this->response->setJSON([ - 'status' => 'success', - 'message' => 'Department deleted successfully' - ]); + $input = $this->request->getJSON(true); + if (!$this->validate($this->rules)) { + return $this->failValidationErrors($this->validator->getErrors()); } + try { + $id = $this->dictDeptModel->insert($input, true); + return $this->respondCreated([ + 'status' => 'success', + 'message' => $id + ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to delete department' - ])->setStatusCode(500); + public function update($id = null) + { + $input = $this->request->getJSON(true); + if (!$this->validate($this->rules)) { + return $this->failValidationErrors($this->validator->getErrors()); + } + try { + $this->dictDeptModel->update($id, $input); + return $this->respond([ + 'status' => 'success', + 'message' => 'update success', + 'data' => $id + ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } + + public function delete($id = null) + { + try { + $this->dictDeptModel->delete($id); + return $this->respond([ + 'status' => 'success', + 'message' => 'delete success' + ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } } } diff --git a/app/Controllers/Api/EntryApiController.php b/app/Controllers/Api/EntryApiController.php index 7805883..db0906a 100644 --- a/app/Controllers/Api/EntryApiController.php +++ b/app/Controllers/Api/EntryApiController.php @@ -25,119 +25,111 @@ class EntryApiController extends BaseController public function getControls() { - $date = $this->request->getGet('date'); - $deptid = $this->request->getGet('deptid'); + try { + $date = $this->request->getGet('date'); + $deptId = $this->request->getGet('deptId'); - $controls = $this->dictControlModel->getActiveByDate($date, $deptid); - - return $this->response->setJSON([ - 'status' => 'success', - 'message' => 'Controls fetched successfully', - 'data' => $controls - ]); + $rows = $this->dictControlModel->getActiveByDate($date, $deptId); + return $this->respond([ + 'status' => 'success', + 'message' => 'fetch success', + 'data' => $rows + ], 200); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } } public function getTests() { - $controlid = $this->request->getGet('controlid'); + try { + $controlId = $this->request->getGet('controlId'); - $tests = $this->controlTestModel->getByControl($controlid); - - return $this->response->setJSON([ - 'status' => 'success', - 'message' => 'Tests fetched successfully', - 'data' => $tests - ]); + $rows = $this->controlTestModel->getByControl($controlId); + return $this->respond([ + 'status' => 'success', + 'message' => 'fetch success', + 'data' => $rows + ], 200); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } } public function saveDaily() { - $post = $this->request->getPost(); + $input = $this->request->getJSON(true); + + try { + $resultData = [ + 'control_ref_id' => $input['controlId'] ?? 0, + 'test_ref_id' => $input['testId'] ?? 0, + 'resdate' => $input['resdate'] ?? date('Y-m-d'), + 'resvalue' => $input['resvalue'] ?? '', + 'rescomment' => $input['rescomment'] ?? '', + ]; - $resultData = [ - 'control_ref_id' => $post['controlid'] ?? 0, - 'test_ref_id' => $post['testid'] ?? 0, - 'resdate' => $post['resdate'] ?? date('Y-m-d'), - 'resvalue' => $post['resvalue'] ?? '', - 'rescomment' => $post['rescomment'] ?? '', - ]; - - $success = $this->resultModel->saveResult($resultData); - - if ($success) { - return $this->response->setJSON([ + $this->resultModel->saveResult($resultData); + return $this->respond([ 'status' => 'success', - 'message' => 'Result saved successfully' + 'message' => 'save success' ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); } - - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to save result' - ])->setStatusCode(500); } public function saveMonthly() { - $post = $this->request->getPost(); + $input = $this->request->getJSON(true); + + try { + $controlId = $input['controlId'] ?? 0; + $testId = $input['testId'] ?? 0; + $dates = $input['dates'] ?? ''; + $resvalues = $input['resvalue'] ?? []; - $controlid = $post['controlid'] ?? 0; - $testid = $post['testid'] ?? 0; - $dates = $post['dates'] ?? ''; - $resvalues = $post['resvalue'] ?? []; - - $success = true; - foreach ($resvalues as $day => $value) { - if (!empty($value)) { - $resultData = [ - 'control_ref_id' => $controlid, - 'test_ref_id' => $testid, - 'resdate' => $dates . '-' . str_pad($day, 2, '0', STR_PAD_LEFT), - 'resvalue' => $value, - 'rescomment' => '', - ]; - if (!$this->resultModel->saveResult($resultData)) { - $success = false; + foreach ($resvalues as $day => $value) { + if (!empty($value)) { + $resultData = [ + 'control_ref_id' => $controlId, + 'test_ref_id' => $testId, + 'resdate' => $dates . '-' . str_pad($day, 2, '0', STR_PAD_LEFT), + 'resvalue' => $value, + 'rescomment' => '', + ]; + $this->resultModel->saveResult($resultData); } } - } - if ($success) { - return $this->response->setJSON([ + return $this->respond([ 'status' => 'success', - 'message' => 'Monthly data saved successfully' + 'message' => 'save success' ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); } - - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to save some entries' - ])->setStatusCode(500); } public function saveComment() { - $post = $this->request->getPost(); + $input = $this->request->getJSON(true); + + try { + $commentData = [ + 'control_ref_id' => $input['controlId'] ?? 0, + 'test_ref_id' => $input['testId'] ?? 0, + 'commonth' => $input['commonth'] ?? '', + 'comtext' => $input['comtext'] ?? '', + ]; - $commentData = [ - 'control_ref_id' => $post['controlid'] ?? 0, - 'test_ref_id' => $post['testid'] ?? 0, - 'commonth' => $post['commonth'] ?? '', - 'comtext' => $post['comtext'] ?? '', - ]; - - $success = $this->commentModel->saveComment($commentData); - - if ($success) { - return $this->response->setJSON([ + $this->commentModel->saveComment($commentData); + return $this->respond([ 'status' => 'success', - 'message' => 'Comment saved successfully' + 'message' => 'save success' ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); } - - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to save comment' - ])->setStatusCode(500); } } diff --git a/app/Controllers/Api/TestApiController.php b/app/Controllers/Api/TestApiController.php index 958fff8..37f0cb1 100644 --- a/app/Controllers/Api/TestApiController.php +++ b/app/Controllers/Api/TestApiController.php @@ -10,111 +10,97 @@ class TestApiController extends BaseController { protected $dictTestModel; protected $dictDeptModel; + protected $rules; public function __construct() { $this->dictTestModel = new DictTestModel(); $this->dictDeptModel = new DictDeptModel(); + $this->rules = [ + 'name' => 'required|min_length[1]', + 'dept_ref_id' => 'required', + ]; } public function index() { - $tests = $this->dictTestModel->getWithDept(); - return $this->response->setJSON([ - 'status' => 'success', - 'message' => 'Tests fetched successfully', - 'data' => $tests - ]); - } - - public function show($id) - { - $test = $this->dictTestModel->find($id); - if (!$test) { - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Test not found' - ])->setStatusCode(404); - } - return $this->response->setJSON([ - 'status' => 'success', - 'data' => $test - ]); - } - - public function store() - { - $post = $this->request->getJSON(true); - - $testData = [ - 'dept_ref_id' => $post['dept_ref_id'] ?? null, - 'name' => $post['name'] ?? '', - 'unit' => $post['unit'] ?? '', - 'method' => $post['method'] ?? '', - 'cva' => $post['cva'] ?? '', - 'ba' => $post['ba'] ?? '', - 'tea' => $post['tea'] ?? '', - ]; - - $id = $this->dictTestModel->insert($testData); - - if ($id) { - return $this->response->setJSON([ + try { + $rows = $this->dictTestModel->getWithDept(); + return $this->respond([ 'status' => 'success', - 'message' => 'Test saved successfully', - 'data' => ['test_id' => $id] - ]); + 'message' => 'fetch success', + 'data' => $rows + ], 200); + } catch (\Exception $e) { + return $this->failServerError('Exception: ' . $e->getMessage()); } - - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to save test' - ])->setStatusCode(500); } - public function update($id) + public function show($id = null) { - $post = $this->request->getJSON(true); - - $testData = [ - 'dept_ref_id' => $post['dept_ref_id'] ?? null, - 'name' => $post['name'] ?? '', - 'unit' => $post['unit'] ?? '', - 'method' => $post['method'] ?? '', - 'cva' => $post['cva'] ?? '', - 'ba' => $post['ba'] ?? '', - 'tea' => $post['tea'] ?? '', - ]; - - $success = $this->dictTestModel->update($id, $testData); - - if ($success) { - return $this->response->setJSON([ + try { + $rows = $this->dictTestModel->where('test_id', $id)->findAll(); + if (empty($rows)) { + return $this->respond([ + 'status' => 'success', + 'message' => 'data not found.' + ], 200); + } + return $this->respond([ 'status' => 'success', - 'message' => 'Test updated successfully' - ]); + 'message' => 'fetch success', + 'data' => $rows + ], 200); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); } - - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to update test' - ])->setStatusCode(500); } - public function delete($id) + public function create() { - $success = $this->dictTestModel->delete($id); - - if ($success) { - return $this->response->setJSON([ - 'status' => 'success', - 'message' => 'Test deleted successfully' - ]); + $input = $this->request->getJSON(true); + if (!$this->validate($this->rules)) { + return $this->failValidationErrors($this->validator->getErrors()); } + try { + $id = $this->dictTestModel->insert($input, true); + return $this->respondCreated([ + 'status' => 'success', + 'message' => $id + ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Failed to delete test' - ])->setStatusCode(500); + public function update($id = null) + { + $input = $this->request->getJSON(true); + if (!$this->validate($this->rules)) { + return $this->failValidationErrors($this->validator->getErrors()); + } + try { + $this->dictTestModel->update($id, $input); + return $this->respond([ + 'status' => 'success', + 'message' => 'update success', + 'data' => $id + ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } + } + + public function delete($id = null) + { + try { + $this->dictTestModel->delete($id); + return $this->respond([ + 'status' => 'success', + 'message' => 'delete success' + ]); + } catch (\Exception $e) { + return $this->failServerError('Something went wrong: ' . $e->getMessage()); + } } } diff --git a/app/Controllers/BaseController.php b/app/Controllers/BaseController.php index 744f77f..343b084 100644 --- a/app/Controllers/BaseController.php +++ b/app/Controllers/BaseController.php @@ -3,18 +3,21 @@ namespace App\Controllers; use CodeIgniter\Controller; +use CodeIgniter\API\ResponseTrait; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use Psr\Log\LoggerInterface; abstract class BaseController extends Controller { + use ResponseTrait; + protected $session; public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) { parent::initController($request, $response, $logger); $this->session = \Config\Services::session(); - $this->helpers = ['form', 'url']; + $this->helpers = ['form', 'url', 'json']; } } diff --git a/app/Database/Migrations/2026-01-14-000001_CreateCmodQcTables.php b/app/Database/Migrations/2026-01-14-000001_CreateCmodQcTables.php index 0373742..ae2c90a 100644 --- a/app/Database/Migrations/2026-01-14-000001_CreateCmodQcTables.php +++ b/app/Database/Migrations/2026-01-14-000001_CreateCmodQcTables.php @@ -33,6 +33,18 @@ class CreateCmodQcTables extends Migration 'type' => 'FLOAT', 'null' => true, ], + 'created_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'updated_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'deleted_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], ]); $this->forge->addKey('control_test_id', true); $this->forge->createTable('control_tests'); @@ -67,6 +79,18 @@ class CreateCmodQcTables extends Migration 'type' => 'TEXT', 'null' => true, ], + 'created_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'updated_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'deleted_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], ]); $this->forge->addKey('result_id', true); $this->forge->createTable('results'); @@ -101,6 +125,18 @@ class CreateCmodQcTables extends Migration 'type' => 'DATE', 'null' => true, ], + 'created_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'updated_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'deleted_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], ]); $this->forge->addKey('control_id', true); $this->forge->createTable('dict_controls'); @@ -117,6 +153,18 @@ class CreateCmodQcTables extends Migration 'constraint' => 50, 'null' => true, ], + 'created_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'updated_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'deleted_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], ]); $this->forge->addKey('dept_id', true); $this->forge->createTable('dict_depts'); @@ -163,6 +211,18 @@ class CreateCmodQcTables extends Migration 'constraint' => 50, 'null' => true, ], + 'created_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'updated_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'deleted_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], ]); $this->forge->addKey('test_id', true); $this->forge->createTable('dict_tests'); @@ -193,6 +253,18 @@ class CreateCmodQcTables extends Migration 'type' => 'TEXT', 'null' => true, ], + 'created_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'updated_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], + 'deleted_at' => [ + 'type' => 'DATETIME', + 'null' => true, + ], ]); $this->forge->addKey('result_comment_id', true); $this->forge->createTable('result_comments'); diff --git a/app/Helpers/stringcase_helper.php b/app/Helpers/stringcase_helper.php new file mode 100644 index 0000000..2f80e37 --- /dev/null +++ b/app/Helpers/stringcase_helper.php @@ -0,0 +1,47 @@ + $value) { + $snakeKey = camel_to_snake($key); + $converted[$snakeKey] = $value; + } + return $converted; + } +} + +if (!function_exists('snake_to_camel')) { + function snake_to_camel(string $string): string + { + $parts = explode('_', $string); + $camel = array_map(function ($part, $index) { + if ($index === 0) { + return $part; + } + return ucfirst($part); + }, $parts, array_keys($parts)); + return implode('', $camel); + } +} + +if (!function_exists('snake_to_camel_array')) { + function snake_to_camel_array(array $data): array + { + $converted = []; + foreach ($data as $key => $value) { + $camelKey = snake_to_camel($key); + $converted[$camelKey] = $value; + } + return $converted; + } +} diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php new file mode 100644 index 0000000..c1992e7 --- /dev/null +++ b/app/Models/BaseModel.php @@ -0,0 +1,113 @@ +returnType)) { + $this->returnType = 'array'; + } + } + + public function findAll(?int $limit = null, int $offset = 0) + { + $rows = parent::findAll($limit, $offset); + return $this->snakeToCamelRecursive($rows); + } + + public function find($id = null) + { + $row = parent::find($id); + if ($row) { + return $this->snakeToCamel($row); + } + return null; + } + + public function first() + { + $row = parent::first(); + if ($row) { + return $this->snakeToCamel($row); + } + return null; + } + + protected function snakeToCamel(array $row): array + { + $converted = []; + foreach ($row as $key => $value) { + $camelKey = $this->snakeToCamelKey($key); + $converted[$camelKey] = $value; + } + return $converted; + } + + protected function snakeToCamelRecursive($data) + { + if (is_array($data)) { + if (isset($data[0]) || empty($data)) { + return array_map([$this, 'snakeToCamelRecursive'], $data); + } + return $this->snakeToCamel($data); + } + return $data; + } + + protected function snakeToCamelKey(string $key): string + { + $parts = explode('_', $key); + $camel = array_map(function ($part, $index) { + if ($index === 0) { + return $part; + } + return ucfirst($part); + }, $parts, array_keys($parts)); + return implode('', $camel); + } + + public function insert($data = null, bool $returnID = true) + { + $snakeData = $this->camelToSnakeArray($data); + return parent::insert($snakeData, $returnID); + } + + public function update($id = null, $row = null): bool + { + $snakeData = $this->camelToSnakeArray($row); + return parent::update($id, $snakeData); + } + + protected function camelToSnakeArray(array $data): array + { + $converted = []; + foreach ($data as $key => $value) { + $snakeKey = $this->camelToSnakeKey($key); + $converted[$snakeKey] = $value; + } + return $converted; + } + + protected function camelToSnakeKey(string $key): string + { + $pattern = '/([a-z])([A-Z])/'; + $snake = preg_replace($pattern, '$1_$2', $key); + return strtolower($snake); + } +} diff --git a/app/Models/ControlModel.php b/app/Models/ControlModel.php index a8dd435..3aec9bd 100644 --- a/app/Models/ControlModel.php +++ b/app/Models/ControlModel.php @@ -2,38 +2,38 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class ControlModel extends Model +class ControlModel extends BaseModel { - protected $table = 'dict_control'; - protected $primaryKey = 'id'; + protected $table = 'dict_controls'; + protected $primaryKey = 'control_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['deptid', 'name', 'lot', 'producer', 'expdate']; - protected $useTimestamps = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; + protected $allowedFields = ['dept_ref_id', 'name', 'lot', 'producer', 'expdate']; - public function getByDept($deptid) + public function getByDept($deptId) { - return $this->where('deptid', $deptid)->findAll(); + return $this->where('dept_ref_id', $deptId)->findAll(); } public function getWithDept() { - $builder = $this->db->table('dict_control c'); + $builder = $this->db->table('dict_controls c'); $builder->select('c.*, d.name as dept_name'); - $builder->join('dict_dept d', 'd.id = c.deptid', 'left'); + $builder->join('dict_depts d', 'd.dept_id = c.dept_ref_id', 'left'); return $builder->get()->getResultArray(); } - public function getActiveByDate($date, $deptid = null) + public function getActiveByDate($date, $deptId = null) { - $builder = $this->db->table('dict_control c'); + $builder = $this->db->table('dict_controls c'); $builder->select('c.*'); $builder->where('c.expdate >=', $date); - if ($deptid) { - $builder->where('c.deptid', $deptid); + if ($deptId) { + $builder->where('c.dept_ref_id', $deptId); } $builder->orderBy('c.name', 'ASC'); return $builder->get()->getResultArray(); diff --git a/app/Models/ControlTestModel.php b/app/Models/ControlTestModel.php index f7a8283..7ba7530 100644 --- a/app/Models/ControlTestModel.php +++ b/app/Models/ControlTestModel.php @@ -2,17 +2,17 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class ControlTestModel extends Model +class ControlTestModel extends BaseModel { protected $table = 'control_tests'; protected $primaryKey = 'control_test_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['control_test_id', 'control_ref_id', 'test_ref_id', 'mean', 'sd']; - protected $useTimestamps = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; + protected $allowedFields = ['control_ref_id', 'test_ref_id', 'mean', 'sd']; public function getByControl($controlId) { diff --git a/app/Models/DailyResultModel.php b/app/Models/DailyResultModel.php index ad9227f..323634e 100644 --- a/app/Models/DailyResultModel.php +++ b/app/Models/DailyResultModel.php @@ -2,41 +2,41 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class DailyResultModel extends Model +class DailyResultModel extends BaseModel { protected $table = 'daily_result'; - protected $primaryKey = 'id'; + protected $primaryKey = 'daily_result_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['controlid', 'testid', 'resdate', 'resvalue', 'rescomment']; - protected $useTimestamps = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; + protected $allowedFields = ['control_ref_id', 'test_ref_id', 'resdate', 'resvalue', 'rescomment']; - public function getByMonth($controlid, $testid, $yearMonth) + public function getByMonth($controlId, $testId, $yearMonth) { $startDate = $yearMonth . '-01'; $endDate = $yearMonth . '-31'; $builder = $this->db->table('daily_result'); $builder->select('*'); - $builder->where('controlid', $controlid); - $builder->where('testid', $testid); + $builder->where('control_ref_id', $controlId); + $builder->where('test_ref_id', $testId); $builder->where('resdate >=', $startDate); $builder->where('resdate <=', $endDate); $builder->orderBy('resdate', 'ASC'); return $builder->get()->getResultArray(); } - public function getByControlMonth($controlid, $yearMonth) + public function getByControlMonth($controlId, $yearMonth) { $startDate = $yearMonth . '-01'; $endDate = $yearMonth . '-31'; $builder = $this->db->table('daily_result'); $builder->select('*'); - $builder->where('controlid', $controlid); + $builder->where('control_ref_id', $controlId); $builder->where('resdate >=', $startDate); $builder->where('resdate <=', $endDate); return $builder->get()->getResultArray(); @@ -46,14 +46,14 @@ class DailyResultModel extends Model { $builder = $this->db->table('daily_result'); $existing = $builder->select('*') - ->where('controlid', $data['controlid']) - ->where('testid', $data['testid']) + ->where('control_ref_id', $data['control_ref_id']) + ->where('test_ref_id', $data['test_ref_id']) ->where('resdate', $data['resdate']) ->get() ->getRowArray(); if ($existing) { - return $builder->where('id', $existing['id'])->update($data); + return $builder->where('daily_result_id', $existing['daily_result_id'])->update($data); } else { return $builder->insert($data); } diff --git a/app/Models/DeptModel.php b/app/Models/DeptModel.php index 3dca9d9..02351b0 100644 --- a/app/Models/DeptModel.php +++ b/app/Models/DeptModel.php @@ -2,15 +2,15 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class DeptModel extends Model +class DeptModel extends BaseModel { - protected $table = 'dict_dept'; - protected $primaryKey = 'id'; + protected $table = 'dict_depts'; + protected $primaryKey = 'dept_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; protected $allowedFields = ['name']; - protected $useTimestamps = false; } diff --git a/app/Models/DictControlModel.php b/app/Models/DictControlModel.php index 1942ed1..ac56d3d 100644 --- a/app/Models/DictControlModel.php +++ b/app/Models/DictControlModel.php @@ -2,17 +2,17 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class DictControlModel extends Model +class DictControlModel extends BaseModel { protected $table = 'dict_controls'; protected $primaryKey = 'control_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['control_id', 'dept_ref_id', 'name', 'lot', 'producer', 'expdate']; - protected $useTimestamps = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; + protected $allowedFields = ['dept_ref_id', 'name', 'lot', 'producer', 'expdate']; public function getByDept($deptId) { diff --git a/app/Models/DictDeptModel.php b/app/Models/DictDeptModel.php index 81e6bdb..d5bd067 100644 --- a/app/Models/DictDeptModel.php +++ b/app/Models/DictDeptModel.php @@ -2,15 +2,15 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class DictDeptModel extends Model +class DictDeptModel extends BaseModel { protected $table = 'dict_depts'; protected $primaryKey = 'dept_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['dept_id', 'name']; - protected $useTimestamps = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; + protected $allowedFields = ['name']; } diff --git a/app/Models/DictTestModel.php b/app/Models/DictTestModel.php index 81fe35e..70bf1e5 100644 --- a/app/Models/DictTestModel.php +++ b/app/Models/DictTestModel.php @@ -2,17 +2,17 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class DictTestModel extends Model +class DictTestModel extends BaseModel { protected $table = 'dict_tests'; protected $primaryKey = 'test_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['test_id', 'dept_ref_id', 'name', 'unit', 'method', 'cva', 'ba', 'tea']; - protected $useTimestamps = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; + protected $allowedFields = ['dept_ref_id', 'name', 'unit', 'method', 'cva', 'ba', 'tea']; public function getByDept($deptId) { diff --git a/app/Models/MonthlyCommentModel.php b/app/Models/MonthlyCommentModel.php index bac3da6..cf8c2b1 100644 --- a/app/Models/MonthlyCommentModel.php +++ b/app/Models/MonthlyCommentModel.php @@ -2,35 +2,35 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class MonthlyCommentModel extends Model +class MonthlyCommentModel extends BaseModel { protected $table = 'monthly_comment'; - protected $primaryKey = 'id'; + protected $primaryKey = 'monthly_comment_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['controlid', 'testid', 'commonth', 'comtext']; - protected $useTimestamps = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; + protected $allowedFields = ['control_ref_id', 'test_ref_id', 'commonth', 'comtext']; - public function getByControlTestMonth($controlid, $testid, $yearMonth) + public function getByControlTestMonth($controlId, $testId, $yearMonth) { - return $this->where('controlid', $controlid) - ->where('testid', $testid) + return $this->where('control_ref_id', $controlId) + ->where('test_ref_id', $testId) ->where('commonth', $yearMonth) ->first(); } public function saveComment($data) { - $existing = $this->where('controlid', $data['controlid']) - ->where('testid', $data['testid']) + $existing = $this->where('control_ref_id', $data['control_ref_id']) + ->where('test_ref_id', $data['test_ref_id']) ->where('commonth', $data['commonth']) ->first(); if ($existing) { - return $this->update($existing['id'], $data); + return $this->update($existing['monthly_comment_id'], $data); } else { return $this->insert($data); } diff --git a/app/Models/ResultCommentModel.php b/app/Models/ResultCommentModel.php index adf1012..d4086be 100644 --- a/app/Models/ResultCommentModel.php +++ b/app/Models/ResultCommentModel.php @@ -2,17 +2,17 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class ResultCommentModel extends Model +class ResultCommentModel extends BaseModel { protected $table = 'result_comments'; protected $primaryKey = 'result_comment_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['result_comment_id', 'control_ref_id', 'test_ref_id', 'commonth', 'comtext']; - protected $useTimestamps = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; + protected $allowedFields = ['control_ref_id', 'test_ref_id', 'commonth', 'comtext']; public function getByControlTestMonth($controlId, $testId, $yearMonth) { diff --git a/app/Models/ResultModel.php b/app/Models/ResultModel.php index cad6bf2..9cc6a7e 100644 --- a/app/Models/ResultModel.php +++ b/app/Models/ResultModel.php @@ -2,17 +2,17 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class ResultModel extends Model +class ResultModel extends BaseModel { protected $table = 'results'; protected $primaryKey = 'result_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['result_id', 'control_ref_id', 'test_ref_id', 'resdate', 'resvalue', 'rescomment']; - protected $useTimestamps = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; + protected $allowedFields = ['control_ref_id', 'test_ref_id', 'resdate', 'resvalue', 'rescomment']; public function getByMonth($controlId, $testId, $yearMonth) { diff --git a/app/Models/TestModel.php b/app/Models/TestModel.php index 1497a2d..2897ab7 100644 --- a/app/Models/TestModel.php +++ b/app/Models/TestModel.php @@ -2,28 +2,28 @@ namespace App\Models; -use CodeIgniter\Model; +use App\Models\BaseModel; -class TestModel extends Model +class TestModel extends BaseModel { - protected $table = 'dict_test'; - protected $primaryKey = 'id'; + protected $table = 'dict_tests'; + protected $primaryKey = 'test_id'; protected $useAutoIncrement = true; protected $returnType = 'array'; - protected $useSoftDeletes = false; - protected $allowedFields = ['deptid', 'name', 'unit', 'method', 'cva', 'ba', 'tea']; - protected $useTimestamps = false; + protected $useSoftDeletes = true; + protected $useTimestamps = true; + protected $allowedFields = ['dept_ref_id', 'name', 'unit', 'method', 'cva', 'ba', 'tea']; - public function getByDept($deptid) + public function getByDept($deptId) { - return $this->where('deptid', $deptid)->findAll(); + return $this->where('dept_ref_id', $deptId)->findAll(); } public function getWithDept() { - $builder = $this->db->table('dict_test t'); + $builder = $this->db->table('dict_tests t'); $builder->select('t.*, d.name as dept_name'); - $builder->join('dict_dept d', 'd.id = t.deptid', 'left'); + $builder->join('dict_depts d', 'd.dept_id = t.dept_ref_id', 'left'); return $builder->get()->getResultArray(); } } diff --git a/app/Views/control/index.php b/app/Views/control/index.php index 6c39ad5..4ccc8f4 100644 --- a/app/Views/control/index.php +++ b/app/Views/control/index.php @@ -197,7 +197,7 @@ document.addEventListener('alpine:init', () => { : `${window.BASEURL}/api/control`; const res = await fetch(url, { - method: this.form.control_id ? 'PUT' : 'POST', + method: this.form.control_id ? 'PATCH' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(this.form) }); diff --git a/app/Views/dept/index.php b/app/Views/dept/index.php index 7628405..54c9f27 100644 --- a/app/Views/dept/index.php +++ b/app/Views/dept/index.php @@ -142,7 +142,7 @@ document.addEventListener('alpine:init', () => { : `${window.BASEURL}/api/dept`; const res = await fetch(url, { - method: this.form.dept_id ? 'PUT' : 'POST', + method: this.form.dept_id ? 'PATCH' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: this.form.name }) }); diff --git a/app/Views/layout/main_layout.php b/app/Views/layout/main_layout.php index c428ef0..4f5a0eb 100644 --- a/app/Views/layout/main_layout.php +++ b/app/Views/layout/main_layout.php @@ -94,7 +94,7 @@ - +
@@ -104,16 +104,16 @@
- - -
+
-

@@ -236,6 +237,15 @@ + renderSection("script"); ?> diff --git a/app/Views/test/index.php b/app/Views/test/index.php index fb17551..4e84ed8 100644 --- a/app/Views/test/index.php +++ b/app/Views/test/index.php @@ -186,7 +186,7 @@ document.addEventListener('alpine:init', () => { : `${window.BASEURL}/api/test`; const res = await fetch(url, { - method: this.form.test_id ? 'PUT' : 'POST', + method: this.form.test_id ? 'PATCH' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(this.form) }); diff --git a/app/Views/welcome_message.php b/app/Views/welcome_message.php deleted file mode 100644 index c18eca3..0000000 --- a/app/Views/welcome_message.php +++ /dev/null @@ -1,331 +0,0 @@ - - - - - Welcome to CodeIgniter 4! - - - - - - - - - - - -
- - - -
- -

Welcome to CodeIgniter

- -

The small framework with powerful features

- -
- -
- - - -
- -

About this page

- -

The page you are looking at is being generated dynamically by CodeIgniter.

- -

If you would like to edit this page you will find it located at:

- -
app/Views/welcome_message.php
- -

The corresponding controller for this page can be found at:

- -
app/Controllers/Home.php
- -
- -
- -
- -

Go further

- -

- - Learn -

- -

The User Guide contains an introduction, tutorial, a number of "how to" - guides, and then reference documentation for the components that make up - the framework. Check the User Guide !

- -

- - Discuss -

- -

CodeIgniter is a community-developed open source project, with several - venues for the community members to gather and exchange ideas. View all - the threads on CodeIgniter's forum, or chat on Slack !

- -

- - Contribute -

- -

CodeIgniter is a community driven project and accepts contributions - of code and documentation from the community. Why not - - join us ?

- -
- -
- - - -
-
- -

Page rendered in {elapsed_time} seconds using {memory_usage} MB of memory.

- -

Environment:

- -
- -
- -

© CodeIgniter Foundation. CodeIgniter is open source project released under the MIT - open source licence.

- -
- -
- - - - - - - - - diff --git a/public/js/app.js b/public/js/app.js index bf08e70..038dd65 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1,3 +1,10 @@ +document.addEventListener('alpine:init', () => { + Alpine.store('appState', { + loading: false, + sidebarOpen: false + }); +}); + window.App = { loading: false, sidebarOpen: false, @@ -15,12 +22,18 @@ window.App = { if (toggleBtn) { toggleBtn.addEventListener('click', () => { this.sidebarOpen = !this.sidebarOpen; + if (window.Alpine) { + Alpine.store('appState').sidebarOpen = this.sidebarOpen; + } }); } if (backdrop) { backdrop.addEventListener('click', () => { this.sidebarOpen = false; + if (window.Alpine) { + Alpine.store('appState').sidebarOpen = false; + } }); } }, diff --git a/v1/assets/Chart.min.js b/v1/assets/Chart.min.js deleted file mode 100644 index 5399a16..0000000 --- a/v1/assets/Chart.min.js +++ /dev/null @@ -1,13 +0,0 @@ -/*! - * Chart.js v3.8.0 - * https://www.chartjs.org - * (c) 2022 Chart.js Contributors - * Released under the MIT License - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){"use strict";const t="undefined"==typeof window?function(t){return t()}:window.requestAnimationFrame;function e(e,i,s){const n=s||(t=>Array.prototype.slice.call(t));let o=!1,a=[];return function(...s){a=n(s),o||(o=!0,t.call(window,(()=>{o=!1,e.apply(i,a)})))}}function i(t,e){let i;return function(...s){return e?(clearTimeout(i),i=setTimeout(t,e,s)):t.apply(this,s),e}}const s=t=>"start"===t?"left":"end"===t?"right":"center",n=(t,e,i)=>"start"===t?e:"end"===t?i:(e+i)/2,o=(t,e,i,s)=>t===(s?"left":"right")?i:"center"===t?(e+i)/2:e;var a=new class{constructor(){this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}_notify(t,e,i,s){const n=e.listeners[s],o=e.duration;n.forEach((s=>s({chart:t,initial:e.initial,numSteps:o,currentStep:Math.min(i-e.start,o)})))}_refresh(){this._request||(this._running=!0,this._request=t.call(window,(()=>{this._update(),this._request=null,this._running&&this._refresh()})))}_update(t=Date.now()){let e=0;this._charts.forEach(((i,s)=>{if(!i.running||!i.items.length)return;const n=i.items;let o,a=n.length-1,r=!1;for(;a>=0;--a)o=n[a],o._active?(o._total>i.duration&&(i.duration=o._total),o.tick(t),r=!0):(n[a]=n[n.length-1],n.pop());r&&(s.draw(),this._notify(s,i,t,"progress")),n.length||(i.running=!1,this._notify(s,i,t,"complete"),i.initial=!1),e+=n.length})),this._lastDate=t,0===e&&(this._running=!1)}_getAnims(t){const e=this._charts;let i=e.get(t);return i||(i={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,i)),i}listen(t,e,i){this._getAnims(t).listeners[e].push(i)}add(t,e){e&&e.length&&this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){const e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(((t,e)=>Math.max(t,e._duration)),0),this._refresh())}running(t){if(!this._running)return!1;const e=this._charts.get(t);return!!(e&&e.running&&e.items.length)}stop(t){const e=this._charts.get(t);if(!e||!e.items.length)return;const i=e.items;let s=i.length-1;for(;s>=0;--s)i[s].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}remove(t){return this._charts.delete(t)}}; -/*! - * @kurkle/color v0.2.1 - * https://github.com/kurkle/color#readme - * (c) 2022 Jukka Kurkela - * Released under the MIT License - */function r(t){return t+.5|0}const l=(t,e,i)=>Math.max(Math.min(t,i),e);function h(t){return l(r(2.55*t),0,255)}function c(t){return l(r(255*t),0,255)}function d(t){return l(r(t/2.55)/100,0,1)}function u(t){return l(r(100*t),0,100)}const f={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},g=[..."0123456789ABCDEF"],p=t=>g[15&t],m=t=>g[(240&t)>>4]+g[15&t],b=t=>(240&t)>>4==(15&t);function x(t){var e=(t=>b(t.r)&&b(t.g)&&b(t.b)&&b(t.a))(t)?p:m;return t?"#"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):"")(t.a,e):void 0}const _=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function y(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function v(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function w(t,e,i){const s=y(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function M(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e>16&255,o>>8&255,255&o]}return t}(),A.transparent=[0,0,0,0]);const e=A[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}const L=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const R=t=>t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055,E=t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4);function I(t,e,i){if(t){let s=M(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),s=S(s),t.r=s[0],t.g=s[1],t.b=s[2]}}function z(t,e){return t?Object.assign(e||{},t):t}function F(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=c(t[3]))):(e=z(t,{r:0,g:0,b:0,a:1})).a=c(e.a),e}function B(t){return"r"===t.charAt(0)?function(t){const e=L.exec(t);let i,s,n,o=255;if(e){if(e[7]!==i){const t=+e[7];o=e[8]?h(t):l(255*t,0,255)}return i=+e[1],s=+e[3],n=+e[5],i=255&(e[2]?h(i):l(i,0,255)),s=255&(e[4]?h(s):l(s,0,255)),n=255&(e[6]?h(n):l(n,0,255)),{r:i,g:s,b:n,a:o}}}(t):D(t)}class V{constructor(t){if(t instanceof V)return t;const e=typeof t;let i;var s,n,o;"object"===e?i=F(t):"string"===e&&(o=(s=t).length,"#"===s[0]&&(4===o||5===o?n={r:255&17*f[s[1]],g:255&17*f[s[2]],b:255&17*f[s[3]],a:5===o?17*f[s[4]]:255}:7!==o&&9!==o||(n={r:f[s[1]]<<4|f[s[2]],g:f[s[3]]<<4|f[s[4]],b:f[s[5]]<<4|f[s[6]],a:9===o?f[s[7]]<<4|f[s[8]]:255})),i=n||T(t)||B(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=z(this._rgb);return t&&(t.a=d(t.a)),t}set rgb(t){this._rgb=F(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${d(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):void 0;var t}hexString(){return this._valid?x(this._rgb):void 0}hslString(){return this._valid?function(t){if(!t)return;const e=M(t),i=e[0],s=u(e[1]),n=u(e[2]);return t.a<255?`hsla(${i}, ${s}%, ${n}%, ${d(t.a)})`:`hsl(${i}, ${s}%, ${n}%)`}(this._rgb):void 0}mix(t,e){if(t){const i=this.rgb,s=t.rgb;let n;const o=e===n?.5:e,a=2*o-1,r=i.a-s.a,l=((a*r==-1?a:(a+r)/(1+a*r))+1)/2;n=1-l,i.r=255&l*i.r+n*s.r+.5,i.g=255&l*i.g+n*s.g+.5,i.b=255&l*i.b+n*s.b+.5,i.a=o*i.a+(1-o)*s.a,this.rgb=i}return this}interpolate(t,e){return t&&(this._rgb=function(t,e,i){const s=E(d(t.r)),n=E(d(t.g)),o=E(d(t.b));return{r:c(R(s+i*(E(d(e.r))-s))),g:c(R(n+i*(E(d(e.g))-n))),b:c(R(o+i*(E(d(e.b))-o))),a:t.a+i*(e.a-t.a)}}(this._rgb,t._rgb,e)),this}clone(){return new V(this.rgb)}alpha(t){return this._rgb.a=c(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=r(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return I(this._rgb,2,t),this}darken(t){return I(this._rgb,2,-t),this}saturate(t){return I(this._rgb,1,t),this}desaturate(t){return I(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=M(t);i[0]=P(i[0]+e),i=S(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function N(t){return new V(t)}function W(t){if(t&&"object"==typeof t){const e=t.toString();return"[object CanvasPattern]"===e||"[object CanvasGradient]"===e}return!1}function H(t){return W(t)?t:N(t)}function j(t){return W(t)?t:N(t).saturate(.5).darken(.1).hexString()}function $(){}const Y=function(){let t=0;return function(){return t++}}();function U(t){return null==t}function X(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.slice(0,7)&&"Array]"===e.slice(-6)}function q(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}const K=t=>("number"==typeof t||t instanceof Number)&&isFinite(+t);function G(t,e){return K(t)?t:e}function Z(t,e){return void 0===t?e:t}const J=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:t/e,Q=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function tt(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function et(t,e,i,s){let n,o,a;if(X(t))if(o=t.length,s)for(n=o-1;n>=0;n--)e.call(i,t[n],n);else for(n=0;ni;)t=t[e.slice(i,s)],i=s+1,s=ht(e,i);return t}function dt(t){return t.charAt(0).toUpperCase()+t.slice(1)}const ut=t=>void 0!==t,ft=t=>"function"==typeof t,gt=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function pt(t){return"mouseup"===t.type||"click"===t.type||"contextmenu"===t.type}const mt=Object.create(null),bt=Object.create(null);function xt(t,e){if(!e)return t;const i=e.split(".");for(let e=0,s=i.length;et.chart.platform.getDevicePixelRatio(),this.elements={},this.events=["mousemove","mouseout","click","touchstart","touchmove"],this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:"normal",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>j(e.backgroundColor),this.hoverBorderColor=(t,e)=>j(e.borderColor),this.hoverColor=(t,e)=>j(e.color),this.indexAxis="x",this.interaction={mode:"nearest",intersect:!0,includeInvisible:!1},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(t)}set(t,e){return _t(this,t,e)}get(t){return xt(this,t)}describe(t,e){return _t(bt,t,e)}override(t,e){return _t(mt,t,e)}route(t,e,i,s){const n=xt(this,t),o=xt(this,i),a="_"+e;Object.defineProperties(n,{[a]:{value:n[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[a],e=o[s];return q(t)?Object.assign({},e,t):Z(t,e)},set(t){this[a]=t}}})}}({_scriptable:t=>!t.startsWith("on"),_indexable:t=>"events"!==t,hover:{_fallback:"interaction"},interaction:{_scriptable:!1,_indexable:!1}});function vt(t,e,i){i=i||(i=>t[i]1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const wt=(t,e,i)=>vt(t,i,(s=>t[s][e]vt(t,i,(s=>t[s][e]>=i));function kt(t,e,i){let s=0,n=t.length;for(;ss&&t[n-1]>i;)n--;return s>0||n{const i="_onData"+dt(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function Dt(t,e){const i=t._chartjs;if(!i)return;const s=i.listeners,n=s.indexOf(e);-1!==n&&s.splice(n,1),s.length>0||(St.forEach((e=>{delete t[e]})),delete t._chartjs)}function Ct(t){const e=new Set;let i,s;for(i=0,s=t.length;it-e)).pop(),e}function Wt(t){return!isNaN(parseFloat(t))&&isFinite(t)}function Ht(t,e,i){return Math.abs(t-e)=t}function $t(t,e,i){let s,n,o;for(s=0,n=t.length;sl&&h=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function ie(){return"undefined"!=typeof window&&"undefined"!=typeof document}function se(t){let e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e}function ne(t,e,i){let s;return"string"==typeof t?(s=parseInt(t,10),-1!==t.indexOf("%")&&(s=s/100*e.parentNode[i])):s=t,s}const oe=t=>window.getComputedStyle(t,null);function ae(t,e){return oe(t).getPropertyValue(e)}const re=["top","right","bottom","left"];function le(t,e,i){const s={};i=i?"-"+i:"";for(let n=0;n<4;n++){const o=re[n];s[o]=parseFloat(t[e+"-"+o+i])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}function he(t,e){if("native"in t)return t;const{canvas:i,currentDevicePixelRatio:s}=e,n=oe(i),o="border-box"===n.boxSizing,a=le(n,"padding"),r=le(n,"border","width"),{x:l,y:h,box:c}=function(t,e){const i=t.touches,s=i&&i.length?i[0]:t,{offsetX:n,offsetY:o}=s;let a,r,l=!1;if(((t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot))(n,o,t.target))a=n,r=o;else{const t=e.getBoundingClientRect();a=s.clientX-t.left,r=s.clientY-t.top,l=!0}return{x:a,y:r,box:l}}(t,i),d=a.left+(c&&r.left),u=a.top+(c&&r.top);let{width:f,height:g}=e;return o&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/s),y:Math.round((h-u)/g*i.height/s)}}const ce=t=>Math.round(10*t)/10;function de(t,e,i,s){const n=oe(t),o=le(n,"margin"),a=ne(n.maxWidth,t,"clientWidth")||Lt,r=ne(n.maxHeight,t,"clientHeight")||Lt,l=function(t,e,i){let s,n;if(void 0===e||void 0===i){const o=se(t);if(o){const t=o.getBoundingClientRect(),a=oe(o),r=le(a,"border","width"),l=le(a,"padding");e=t.width-l.width-r.width,i=t.height-l.height-r.height,s=ne(a.maxWidth,o,"clientWidth"),n=ne(a.maxHeight,o,"clientHeight")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:s||Lt,maxHeight:n||Lt}}(t,e,i);let{width:h,height:c}=l;if("content-box"===n.boxSizing){const t=le(n,"border","width"),e=le(n,"padding");h-=e.width+t.width,c-=e.height+t.height}return h=Math.max(0,h-o.width),c=Math.max(0,s?Math.floor(h/s):c-o.height),h=ce(Math.min(h,a,l.maxWidth)),c=ce(Math.min(c,r,l.maxHeight)),h&&!c&&(c=ce(h/2)),{width:h,height:c}}function ue(t,e,i){const s=e||1,n=Math.floor(t.height*s),o=Math.floor(t.width*s);t.height=n/s,t.width=o/s;const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==s||a.height!==n||a.width!==o)&&(t.currentDevicePixelRatio=s,a.height=n,a.width=o,t.ctx.setTransform(s,0,0,s,0,0),!0)}const fe=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}return t}();function ge(t,e){const i=ae(t,e),s=i&&i.match(/^(\d+)(\.\d+)?px$/);return s?+s[1]:void 0}function pe(t){return!t||U(t.size)||U(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}function me(t,e,i,s,n){let o=e[n];return o||(o=e[n]=t.measureText(n).width,i.push(n)),o>s&&(s=o),s}function be(t,e,i,s){let n=(s=s||{}).data=s.data||{},o=s.garbageCollect=s.garbageCollect||[];s.font!==e&&(n=s.data={},o=s.garbageCollect=[],s.font=e),t.save(),t.font=e;let a=0;const r=i.length;let l,h,c,d,u;for(l=0;li.length){for(l=0;l0&&t.stroke()}}function ve(t,e,i){return i=i||.5,!e||t&&t.x>e.left-i&&t.xe.top-i&&t.y0&&""!==o.strokeColor;let l,h;for(t.save(),t.font=n.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]);U(e.rotation)||t.rotate(e.rotation);e.color&&(t.fillStyle=e.color);e.textAlign&&(t.textAlign=e.textAlign);e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,o),l=0;lt[0])){ut(s)||(s=Ne("_fallback",t));const o={[Symbol.toStringTag]:"Object",_cacheable:!0,_scopes:t,_rootScopes:i,_fallback:s,_getTarget:n,override:n=>Oe([n,...t],e,i,s)};return new Proxy(o,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,s)=>Ee(i,s,(()=>function(t,e,i,s){let n;for(const o of e)if(n=Ne(Le(o,t),i),ut(n))return Re(t,n)?Be(i,s,t,n):n}(s,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>We(t).includes(e),ownKeys:t=>We(t),set(t,e,i){const s=t._storage||(t._storage=n());return t[e]=s[e]=i,delete t._keys,!0}})}function Ae(t,e,i,s){const n={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:Te(t,s),setContext:e=>Ae(t,e,i,s),override:n=>Ae(t.override(n),e,i,s)};return new Proxy(n,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>Ee(t,e,(()=>function(t,e,i){const{_proxy:s,_context:n,_subProxy:o,_descriptors:a}=t;let r=s[e];ft(r)&&a.isScriptable(e)&&(r=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error("Recursion detected: "+Array.from(r).join("->")+"->"+t);r.add(t),e=e(o,a||s),r.delete(t),Re(t,e)&&(e=Be(n._scopes,n,t,e));return e}(e,r,t,i));X(r)&&r.length&&(r=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_descriptors:r}=i;if(ut(o.index)&&s(t))e=e[o.index%e.length];else if(q(e[0])){const i=e,s=n._scopes.filter((t=>t!==i));e=[];for(const l of i){const i=Be(s,n,t,l);e.push(Ae(i,o,a&&a[t],r))}}return e}(e,r,t,a.isIndexable));Re(e,r)&&(r=Ae(r,n,o&&o[e],a));return r}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,s)=>(t[i]=s,delete e[i],!0)})}function Te(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:s=e.indexable,_allKeys:n=e.allKeys}=t;return{allKeys:n,scriptable:i,indexable:s,isScriptable:ft(i)?i:()=>i,isIndexable:ft(s)?s:()=>s}}const Le=(t,e)=>t?t+dt(e):e,Re=(t,e)=>q(e)&&"adapters"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object);function Ee(t,e,i){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];const s=i();return t[e]=s,s}function Ie(t,e,i){return ft(t)?t(e,i):t}const ze=(t,e)=>!0===t?e:"string"==typeof t?ct(e,t):void 0;function Fe(t,e,i,s,n){for(const o of e){const e=ze(i,o);if(e){t.add(e);const o=Ie(e._fallback,i,n);if(ut(o)&&o!==i&&o!==s)return o}else if(!1===e&&ut(s)&&i!==s)return null}return!1}function Be(t,e,i,s){const n=e._rootScopes,o=Ie(e._fallback,i,s),a=[...t,...n],r=new Set;r.add(s);let l=Ve(r,a,i,o||i,s);return null!==l&&((!ut(o)||o===i||(l=Ve(r,a,o,l,s),null!==l))&&Oe(Array.from(r),[""],n,o,(()=>function(t,e,i){const s=t._getTarget();e in s||(s[e]={});const n=s[e];if(X(n)&&q(i))return i;return n}(e,i,s))))}function Ve(t,e,i,s,n){for(;i;)i=Fe(t,e,i,s,n);return i}function Ne(t,e){for(const i of e){if(!i)continue;const e=i[t];if(ut(e))return e}}function We(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith("_"))))e.add(t);return Array.from(e)}(t._scopes)),e}function He(t,e,i,s){const{iScale:n}=t,{key:o="r"}=this._parsing,a=new Array(s);let r,l,h,c;for(r=0,l=s;re"x"===t?"y":"x";function Ue(t,e,i,s){const n=t.skip?e:t,o=e,a=i.skip?e:i,r=Kt(o,n),l=Kt(a,o);let h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;const d=s*h,u=s*c;return{previous:{x:o.x-d*(a.x-n.x),y:o.y-d*(a.y-n.y)},next:{x:o.x+u*(a.x-n.x),y:o.y+u*(a.y-n.y)}}}function Xe(t,e="x"){const i=Ye(e),s=t.length,n=Array(s).fill(0),o=Array(s);let a,r,l,h=$e(t,0);for(a=0;a!t.skip))),"monotone"===e.cubicInterpolationMode)Xe(t,n);else{let i=s?t[t.length-1]:t[0];for(o=0,a=t.length;o0===t||1===t,Ze=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*At/i),Je=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*At/i)+1,Qe={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*Et),easeOutSine:t=>Math.sin(t*Et),easeInOutSine:t=>-.5*(Math.cos(Ot*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>Ge(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>Ge(t)?t:Ze(t,.075,.3),easeOutElastic:t=>Ge(t)?t:Je(t,.075,.3),easeInOutElastic(t){const e=.1125;return Ge(t)?t:t<.5?.5*Ze(2*t,e,.45):.5+.5*Je(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:t=>1-Qe.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*Qe.easeInBounce(2*t):.5*Qe.easeOutBounce(2*t-1)+.5};function ti(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function ei(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:"middle"===s?i<.5?t.y:e.y:"after"===s?i<1?t.y:e.y:i>0?e.y:t.y}}function ii(t,e,i,s){const n={x:t.cp2x,y:t.cp2y},o={x:e.cp1x,y:e.cp1y},a=ti(t,n,i),r=ti(n,o,i),l=ti(o,e,i),h=ti(a,r,i),c=ti(r,l,i);return ti(h,c,i)}const si=new Map;function ni(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let s=si.get(i);return s||(s=new Intl.NumberFormat(t,e),si.set(i,s)),s}(e,i).format(t)}const oi=new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/),ai=new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);function ri(t,e){const i=(""+t).match(oi);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t}function li(t,e){const i={},s=q(e),n=s?Object.keys(e):e,o=q(t)?s?i=>Z(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of n)i[t]=+o(t)||0;return i}function hi(t){return li(t,{top:"y",right:"x",bottom:"y",left:"x"})}function ci(t){return li(t,["topLeft","topRight","bottomLeft","bottomRight"])}function di(t){const e=hi(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function ui(t,e){t=t||{},e=e||yt.font;let i=Z(t.size,e.size);"string"==typeof i&&(i=parseInt(i,10));let s=Z(t.style,e.style);s&&!(""+s).match(ai)&&(console.warn('Invalid font style specified: "'+s+'"'),s="");const n={family:Z(t.family,e.family),lineHeight:ri(Z(t.lineHeight,e.lineHeight),i),size:i,style:s,weight:Z(t.weight,e.weight),string:""};return n.string=pe(n),n}function fi(t,e,i,s){let n,o,a,r=!0;for(n=0,o=t.length;ni&&0===t?0:t+e;return{min:a(s,-Math.abs(o)),max:a(n,o)}}function pi(t,e){return Object.assign(Object.create(t),e)}function mi(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>"center"===t?t:"right"===t?"left":"right",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function bi(t,e){let i,s;"ltr"!==e&&"rtl"!==e||(i=t.canvas.style,s=[i.getPropertyValue("direction"),i.getPropertyPriority("direction")],i.setProperty("direction",e,"important"),t.prevTextDirection=s)}function xi(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function _i(t){return"angle"===t?{between:Jt,compare:Gt,normalize:Zt}:{between:ee,compare:(t,e)=>t-e,normalize:t=>t}}function yi({start:t,end:e,count:i,loop:s,style:n}){return{start:t%i,end:e%i,loop:s&&(e-t+1)%i==0,style:n}}function vi(t,e,i){if(!i)return[t];const{property:s,start:n,end:o}=i,a=e.length,{compare:r,between:l,normalize:h}=_i(s),{start:c,end:d,loop:u,style:f}=function(t,e,i){const{property:s,start:n,end:o}=i,{between:a,normalize:r}=_i(s),l=e.length;let h,c,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,h=0,c=l;hx||l(n,b,p)&&0!==r(n,b),v=()=>!x||0===r(o,p)||l(o,b,p);for(let t=c,i=c;t<=d;++t)m=e[t%a],m.skip||(p=h(m[s]),p!==b&&(x=l(p,n,o),null===_&&y()&&(_=0===r(p,n)?t:i),null!==_&&v()&&(g.push(yi({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,b=p));return null!==_&&g.push(yi({start:_,end:d,loop:u,count:a,style:f})),g}function wi(t,e){const i=[],s=t.segments;for(let n=0;nn&&t[o%e].skip;)o--;return o%=e,{start:n,end:o}}(i,n,o,s);if(!0===s)return ki(t,[{start:a,end:r,loop:o}],i,e);return ki(t,function(t,e,i,s){const n=t.length,o=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%n];i.skip||i.stop?l.skip||(s=!1,o.push({start:e%n,end:(a-1)%n,loop:s}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&o.push({start:e%n,end:r%n,loop:s}),o}(i,a,r{t[a](e[i],n)&&(o.push({element:t,datasetIndex:s,index:l}),r=r||t.inRange(e.x,e.y,n))})),s&&!r?[]:o}var Ei={evaluateInteractionItems:Oi,modes:{index(t,e,i,s){const n=he(e,t),o=i.axis||"x",a=i.includeInvisible||!1,r=i.intersect?Ai(t,n,o,s,a):Li(t,n,o,!1,s,a),l=[];return r.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=r[0].index,i=t.data[e];i&&!i.skip&&l.push({element:i,datasetIndex:t.index,index:e})})),l):[]},dataset(t,e,i,s){const n=he(e,t),o=i.axis||"xy",a=i.includeInvisible||!1;let r=i.intersect?Ai(t,n,o,s,a):Li(t,n,o,!1,s,a);if(r.length>0){const e=r[0].datasetIndex,i=t.getDatasetMeta(e).data;r=[];for(let t=0;tAi(t,he(e,t),i.axis||"xy",s,i.includeInvisible||!1),nearest(t,e,i,s){const n=he(e,t),o=i.axis||"xy",a=i.includeInvisible||!1;return Li(t,n,o,i.intersect,s,a)},x:(t,e,i,s)=>Ri(t,he(e,t),"x",i.intersect,s),y:(t,e,i,s)=>Ri(t,he(e,t),"y",i.intersect,s)}};const Ii=["left","top","right","bottom"];function zi(t,e){return t.filter((t=>t.pos===e))}function Fi(t,e){return t.filter((t=>-1===Ii.indexOf(t.pos)&&t.box.axis===e))}function Bi(t,e){return t.sort(((t,i)=>{const s=e?i:t,n=e?t:i;return s.weight===n.weight?s.index-n.index:s.weight-n.weight}))}function Vi(t,e){const i=function(t){const e={};for(const i of t){const{stack:t,pos:s,stackWeight:n}=i;if(!t||!Ii.includes(s))continue;const o=e[t]||(e[t]={count:0,placed:0,weight:0,size:0});o.count++,o.weight+=n}return e}(t),{vBoxMaxWidth:s,hBoxMaxHeight:n}=e;let o,a,r;for(o=0,a=t.length;o{s[t]=Math.max(e[t],i[t])})),s}return s(t?["left","right"]:["top","bottom"])}function $i(t,e,i,s){const n=[];let o,a,r,l,h,c;for(o=0,a=t.length,h=0;ot.box.fullSize)),!0),s=Bi(zi(e,"left"),!0),n=Bi(zi(e,"right")),o=Bi(zi(e,"top"),!0),a=Bi(zi(e,"bottom")),r=Fi(e,"x"),l=Fi(e,"y");return{fullSize:i,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:zi(e,"chartArea"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}(t.boxes),l=r.vertical,h=r.horizontal;et(t.boxes,(t=>{"function"==typeof t.beforeLayout&&t.beforeLayout()}));const c=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,d=Object.freeze({outerWidth:e,outerHeight:i,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/c,hBoxMaxHeight:a/2}),u=Object.assign({},n);Wi(u,di(s));const f=Object.assign({maxPadding:u,w:o,h:a,x:n.left,y:n.top},n),g=Vi(l.concat(h),d);$i(r.fullSize,f,d,g),$i(l,f,d,g),$i(h,f,d,g)&&$i(l,f,d,g),function(t){const e=t.maxPadding;function i(i){const s=Math.max(e[i]-t[i],0);return t[i]+=s,s}t.y+=i("top"),t.x+=i("left"),i("right"),i("bottom")}(f),Ui(r.leftAndTop,f,d,g),f.x+=f.w,f.y+=f.h,Ui(r.rightAndBottom,f,d,g),t.chartArea={left:f.left,top:f.top,right:f.left+f.w,bottom:f.top+f.h,height:f.h,width:f.w},et(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(f.w,f.h,{left:0,top:0,right:0,bottom:0})}))}};class qi{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,s){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,s?Math.floor(e/s):i)}}isAttached(t){return!0}updateConfig(t){}}class Ki extends qi{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}}const Gi={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},Zi=t=>null===t||""===t;const Ji=!!fe&&{passive:!0};function Qi(t,e,i){t.canvas.removeEventListener(e,i,Ji)}function ts(t,e){for(const i of t)if(i===e||i.contains(e))return!0}function es(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ts(i.addedNodes,s),e=e&&!ts(i.removedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}function is(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ts(i.removedNodes,s),e=e&&!ts(i.addedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}const ss=new Map;let ns=0;function os(){const t=window.devicePixelRatio;t!==ns&&(ns=t,ss.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function as(t,i,s){const n=t.canvas,o=n&&se(n);if(!o)return;const a=e(((t,e)=>{const i=o.clientWidth;s(t,e),i{const e=t[0],i=e.contentRect.width,s=e.contentRect.height;0===i&&0===s||a(i,s)}));return r.observe(o),function(t,e){ss.size||window.addEventListener("resize",os),ss.set(t,e)}(t,a),r}function rs(t,e,i){i&&i.disconnect(),"resize"===e&&function(t){ss.delete(t),ss.size||window.removeEventListener("resize",os)}(t)}function ls(t,i,s){const n=t.canvas,o=e((e=>{null!==t.ctx&&s(function(t,e){const i=Gi[t.type]||t.type,{x:s,y:n}=he(t,e);return{type:i,chart:e,native:t,x:void 0!==s?s:null,y:void 0!==n?n:null}}(e,t))}),t,(t=>{const e=t[0];return[e,e.offsetX,e.offsetY]}));return function(t,e,i){t.addEventListener(e,i,Ji)}(n,i,o),o}class hs extends qi{acquireContext(t,e){const i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){const i=t.style,s=t.getAttribute("height"),n=t.getAttribute("width");if(t.$chartjs={initial:{height:s,width:n,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",i.boxSizing=i.boxSizing||"border-box",Zi(n)){const e=ge(t,"width");void 0!==e&&(t.width=e)}if(Zi(s))if(""===t.style.height)t.height=t.width/(e||2);else{const e=ge(t,"height");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e.$chartjs)return!1;const i=e.$chartjs.initial;["height","width"].forEach((t=>{const s=i[t];U(s)?e.removeAttribute(t):e.setAttribute(t,s)}));const s=i.style||{};return Object.keys(s).forEach((t=>{e.style[t]=s[t]})),e.width=e.width,delete e.$chartjs,!0}addEventListener(t,e,i){this.removeEventListener(t,e);const s=t.$proxies||(t.$proxies={}),n={attach:es,detach:is,resize:as}[e]||ls;s[e]=n(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),s=i[e];if(!s)return;({attach:rs,detach:rs,resize:rs}[e]||Qi)(t,e,s),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,s){return de(t,e,i,s)}isAttached(t){const e=se(t);return!(!e||!e.isConnected)}}function cs(t){return!ie()||"undefined"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?Ki:hs}var ds=Object.freeze({__proto__:null,_detectPlatform:cs,BasePlatform:qi,BasicPlatform:Ki,DomPlatform:hs});const us="transparent",fs={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const s=H(t||us),n=s.valid&&H(e||us);return n&&n.valid?n.mix(s,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class gs{constructor(t,e,i,s){const n=e[i];s=fi([t.to,s,n,t.from]);const o=fi([t.from,n,s]);this._active=!0,this._fn=t.fn||fs[t.type||typeof o],this._easing=Qe[t.easing]||Qe.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=o,this._to=s,this._promises=void 0}active(){return this._active}update(t,e,i){if(this._active){this._notify(!1);const s=this._target[this._prop],n=i-this._start,o=this._duration-n;this._start=i,this._duration=Math.floor(Math.max(o,t.duration)),this._total+=n,this._loop=!!t.loop,this._to=fi([t.to,e,s,t.from]),this._from=fi([t.from,s,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,i=this._duration,s=this._prop,n=this._from,o=this._loop,a=this._to;let r;if(this._active=n!==a&&(o||e1?2-r:r,r=this._easing(Math.min(1,Math.max(0,r))),this._target[s]=this._fn(n,a,r))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?"res":"rej",i=this._promises||[];for(let t=0;t"onProgress"!==t&&"onComplete"!==t&&"fn"!==t}),yt.set("animations",{colors:{type:"color",properties:["color","borderColor","backgroundColor"]},numbers:{type:"number",properties:["x","y","borderWidth","radius","tension"]}}),yt.describe("animations",{_fallback:"animation"}),yt.set("transitions",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:"transparent"},visible:{type:"boolean",duration:0}}},hide:{animations:{colors:{to:"transparent"},visible:{type:"boolean",easing:"linear",fn:t=>0|t}}}});class ms{constructor(t,e){this._chart=t,this._properties=new Map,this.configure(e)}configure(t){if(!q(t))return;const e=this._properties;Object.getOwnPropertyNames(t).forEach((i=>{const s=t[i];if(!q(s))return;const n={};for(const t of ps)n[t]=s[t];(X(s.properties)&&s.properties||[i]).forEach((t=>{t!==i&&e.has(t)||e.set(t,n)}))}))}_animateOptions(t,e){const i=e.options,s=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!s)return[];const n=this._createAnimations(s,i);return i.$shared&&function(t,e){const i=[],s=Object.keys(e);for(let e=0;e{t.options=i}),(()=>{})),n}_createAnimations(t,e){const i=this._properties,s=[],n=t.$animations||(t.$animations={}),o=Object.keys(e),a=Date.now();let r;for(r=o.length-1;r>=0;--r){const l=o[r];if("$"===l.charAt(0))continue;if("options"===l){s.push(...this._animateOptions(t,e));continue}const h=e[l];let c=n[l];const d=i.get(l);if(c){if(d&&c.active()){c.update(d,h,a);continue}c.cancel()}d&&d.duration?(n[l]=c=new gs(d,t,l,h),s.push(c)):t[l]=h}return s}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(a.add(this._chart,i),!0):void 0}}function bs(t,e){const i=t&&t.options||{},s=i.reverse,n=void 0===i.min?e:0,o=void 0===i.max?e:0;return{start:s?o:n,end:s?n:o}}function xs(t,e){const i=[],s=t._getSortedDatasetMetas(e);let n,o;for(n=0,o=s.length;n0||!i&&e<0)return n.index}return null}function Ms(t,e){const{chart:i,_cachedMeta:s}=t,n=i._stacks||(i._stacks={}),{iScale:o,vScale:a,index:r}=s,l=o.axis,h=a.axis,c=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(o,a,s),d=e.length;let u;for(let t=0;ti[t].axis===e)).shift()}function Ss(t,e){const i=t.controller.index,s=t.vScale&&t.vScale.axis;if(s){e=e||t._parsed;for(const t of e){const e=t._stacks;if(!e||void 0===e[s]||void 0===e[s][i])return;delete e[s][i]}}}const Ps=t=>"reset"===t||"none"===t,Ds=(t,e)=>e?t:Object.assign({},t);class Cs{constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.supportsDecimation=!1,this.$context=void 0,this._syncList=[],this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=ys(t.vScale,t),this.addElements()}updateIndex(t){this.index!==t&&Ss(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,i=this.getDataset(),s=(t,e,i,s)=>"x"===t?e:"r"===t?s:i,n=e.xAxisID=Z(i.xAxisID,ks(t,"x")),o=e.yAxisID=Z(i.yAxisID,ks(t,"y")),a=e.rAxisID=Z(i.rAxisID,ks(t,"r")),r=e.indexAxis,l=e.iAxisID=s(r,n,o,a),h=e.vAxisID=s(r,o,n,a);e.xScale=this.getScaleForId(n),e.yScale=this.getScaleForId(o),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(l),e.vScale=this.getScaleForId(h)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){const t=this._cachedMeta;this._data&&Dt(this._data,this),t._stacked&&Ss(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),i=this._data;if(q(e))this._data=function(t){const e=Object.keys(t),i=new Array(e.length);let s,n,o;for(s=0,n=e.length;s0&&i._parsed[t-1];if(!1===this._parsing)i._parsed=s,i._sorted=!0,h=s;else{h=X(s[t])?this.parseArrayData(i,s,t,e):q(s[t])?this.parseObjectData(i,s,t,e):this.parsePrimitiveData(i,s,t,e);const n=()=>null===l[a]||d&&l[a]t&&!e.hidden&&e._stacked&&{keys:xs(i,!0),values:null})(e,i,this.chart),l={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:h,max:c}=function(t){const{min:e,max:i,minDefined:s,maxDefined:n}=t.getUserBounds();return{min:s?e:Number.NEGATIVE_INFINITY,max:n?i:Number.POSITIVE_INFINITY}}(a);let d,u;function f(){u=s[d];const e=u[a.axis];return!K(u[t.axis])||h>e||c=0;--d)if(!f()){this.updateRangeFromParsed(l,t,u,r);break}return l}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let s,n,o;for(s=0,n=e.length;s=0&&tthis.getContext(i,s)),c);return f.$shared&&(f.$shared=r,n[o]=Object.freeze(Ds(f,r))),f}_resolveAnimations(t,e,i){const s=this.chart,n=this._cachedDataOpts,o=`animation-${e}`,a=n[o];if(a)return a;let r;if(!1!==s.options.animation){const s=this.chart.config,n=s.datasetAnimationScopeKeys(this._type,e),o=s.getOptionScopes(this.getDataset(),n);r=s.createResolver(o,this.getContext(t,i,e))}const l=new ms(s,r&&r.animations);return r&&r._cacheable&&(n[o]=Object.freeze(l)),l}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||Ps(t)||this.chart._animationsDisabled}updateElement(t,e,i,s){Ps(s)?Object.assign(t,i):this._resolveAnimations(e,s).update(t,i)}updateSharedOptions(t,e,i){t&&!Ps(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,s){t.active=s;const n=this.getStyle(e,s);this._resolveAnimations(e,i,s).update(t,{options:!s&&this.getSharedOptions(n)||n})}removeHoverStyle(t,e,i){this._setStyle(t,i,"active",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,"active",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){const e=this._data,i=this._cachedMeta.data;for(const[t,e,i]of this._syncList)this[t](e,i);this._syncList=[];const s=i.length,n=e.length,o=Math.min(n,s);o&&this.parse(0,o),n>s?this._insertElements(s,n-s,t):n{for(t.length+=e,a=t.length-1;a>=o;a--)t[a]=t[a-e]};for(r(n),a=t;a{s[t]=i[t]&&i[t].active()?i[t]._to:this[t]})),s}}Os.defaults={},Os.defaultRoutes=void 0;const As={values:t=>X(t)?t:""+t,numeric(t,e,i){if(0===t)return"0";const s=this.chart.options.locale;let n,o=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(n="scientific"),o=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=Ft(Math.abs(o)),r=Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:n,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),ni(t,s,l)},logarithmic(t,e,i){if(0===t)return"0";const s=t/Math.pow(10,Math.floor(Ft(t)));return 1===s||2===s||5===s?As.numeric.call(this,t,e,i):""}};var Ts={formatters:As};function Ls(t,e){const i=t.options.ticks,s=i.maxTicksLimit||function(t){const e=t.options.offset,i=t._tickSize(),s=t._length/i+(e?0:1),n=t._maxLength/i;return Math.floor(Math.min(s,n))}(t),n=i.major.enabled?function(t){const e=[];let i,s;for(i=0,s=t.length;is)return function(t,e,i,s){let n,o=0,a=i[0];for(s=Math.ceil(s),n=0;nn)return e}return Math.max(n,1)}(n,e,s);if(o>0){let t,i;const s=o>1?Math.round((r-a)/(o-1)):null;for(Rs(e,l,h,U(s)?0:a-s,a),t=0,i=o-1;te.lineWidth,tickColor:(t,e)=>e.color,offset:!1,borderDash:[],borderDashOffset:0,borderWidth:1},title:{display:!1,text:"",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:"",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Ts.formatters.values,minor:{},major:{},align:"center",crossAlign:"near",showLabelBackdrop:!1,backdropColor:"rgba(255, 255, 255, 0.75)",backdropPadding:2}}),yt.route("scale.ticks","color","","color"),yt.route("scale.grid","color","","borderColor"),yt.route("scale.grid","borderColor","","borderColor"),yt.route("scale.title","color","","color"),yt.describe("scale",{_fallback:!1,_scriptable:t=>!t.startsWith("before")&&!t.startsWith("after")&&"callback"!==t&&"parser"!==t,_indexable:t=>"borderDash"!==t&&"tickBorderDash"!==t}),yt.describe("scales",{_fallback:"scale"}),yt.describe("scale.ticks",{_scriptable:t=>"backdropPadding"!==t&&"callback"!==t,_indexable:t=>"backdropPadding"!==t});const Es=(t,e,i)=>"top"===e||"left"===e?t[e]+i:t[e]-i;function Is(t,e){const i=[],s=t.length/e,n=t.length;let o=0;for(;oa+r)))return h}function Fs(t){return t.drawTicks?t.tickLength:0}function Bs(t,e){if(!t.display)return 0;const i=ui(t.font,e),s=di(t.padding);return(X(t.text)?t.text.length:1)*i.lineHeight+s.height}function Vs(t,e,i){let n=s(t);return(i&&"right"!==e||!i&&"right"===e)&&(n=(t=>"left"===t?"right":"right"===t?"left":t)(n)),n}class Ns extends Os{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:s}=this;return t=G(t,Number.POSITIVE_INFINITY),e=G(e,Number.NEGATIVE_INFINITY),i=G(i,Number.POSITIVE_INFINITY),s=G(s,Number.NEGATIVE_INFINITY),{min:G(t,i),max:G(e,s),minDefined:K(t),maxDefined:K(e)}}getMinMax(t){let e,{min:i,max:s,minDefined:n,maxDefined:o}=this.getUserBounds();if(n&&o)return{min:i,max:s};const a=this.getMatchingVisibleMetas();for(let r=0,l=a.length;rs?s:i,s=n&&i>s?i:s,{min:G(i,G(s,i)),max:G(s,G(i,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){tt(this.options.beforeUpdate,[this])}update(t,e,i){const{beginAtZero:s,grace:n,ticks:o}=this.options,a=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+i.left+i.right:this.height+i.top+i.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=gi(this,n,s),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const r=a=n||i<=1||!this.isHorizontal())return void(this.labelRotation=s);const h=this._getLabelSizes(),c=h.widest.width,d=h.highest.height,u=Qt(this.chart.width-c,0,this.maxWidth);o=t.offset?this.maxWidth/i:u/(i-1),c+6>o&&(o=u/(i-(t.offset?.5:1)),a=this.maxHeight-Fs(t.grid)-e.padding-Bs(t.title,this.chart.options.font),r=Math.sqrt(c*c+d*d),l=Ut(Math.min(Math.asin(Qt((h.highest.height+6)/o,-1,1)),Math.asin(Qt(a/r,-1,1))-Math.asin(Qt(d/r,-1,1)))),l=Math.max(s,Math.min(n,l))),this.labelRotation=l}afterCalculateLabelRotation(){tt(this.options.afterCalculateLabelRotation,[this])}afterAutoSkip(){}beforeFit(){tt(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:i,title:s,grid:n}}=this,o=this._isVisible(),a=this.isHorizontal();if(o){const o=Bs(s,e.options.font);if(a?(t.width=this.maxWidth,t.height=Fs(n)+o):(t.height=this.maxHeight,t.width=Fs(n)+o),i.display&&this.ticks.length){const{first:e,last:s,widest:n,highest:o}=this._getLabelSizes(),r=2*i.padding,l=Yt(this.labelRotation),h=Math.cos(l),c=Math.sin(l);if(a){const e=i.mirror?0:c*n.width+h*o.height;t.height=Math.min(this.maxHeight,t.height+e+r)}else{const e=i.mirror?0:h*n.width+c*o.height;t.width=Math.min(this.maxWidth,t.width+e+r)}this._calculatePadding(e,s,c,h)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,i,s){const{ticks:{align:n,padding:o},position:a}=this.options,r=0!==this.labelRotation,l="top"!==a&&"x"===this.axis;if(this.isHorizontal()){const a=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1);let c=0,d=0;r?l?(c=s*t.width,d=i*e.height):(c=i*t.height,d=s*e.width):"start"===n?d=e.width:"end"===n?c=t.width:"inner"!==n&&(c=t.width/2,d=e.width/2),this.paddingLeft=Math.max((c-a+o)*this.width/(this.width-a),0),this.paddingRight=Math.max((d-h+o)*this.width/(this.width-h),0)}else{let i=e.height/2,s=t.height/2;"start"===n?(i=0,s=t.height):"end"===n&&(i=e.height,s=0),this.paddingTop=i+o,this.paddingBottom=s+o}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){tt(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return"top"===e||"bottom"===e||"x"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){let e,i;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,i=t.length;e{const i=t.gc,s=i.length/2;let n;if(s>e){for(n=0;n({width:n[t]||0,height:o[t]||0});return{first:v(0),last:v(e-1),widest:v(_),highest:v(y),widths:n,heights:o}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return te(this._alignToPixels?xe(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&ta*s?a/i:r/s:r*s0}_computeGridLineItems(t){const e=this.axis,i=this.chart,s=this.options,{grid:n,position:o}=s,a=n.offset,r=this.isHorizontal(),l=this.ticks.length+(a?1:0),h=Fs(n),c=[],d=n.setContext(this.getContext()),u=d.drawBorder?d.borderWidth:0,f=u/2,g=function(t){return xe(i,t,u)};let p,m,b,x,_,y,v,w,M,k,S,P;if("top"===o)p=g(this.bottom),y=this.bottom-h,w=p-f,k=g(t.top)+f,P=t.bottom;else if("bottom"===o)p=g(this.top),k=t.top,P=g(t.bottom)-f,y=p+f,w=this.top+h;else if("left"===o)p=g(this.right),_=this.right-h,v=p-f,M=g(t.left)+f,S=t.right;else if("right"===o)p=g(this.left),M=t.left,S=g(t.right)-f,_=p+f,v=this.left+h;else if("x"===e){if("center"===o)p=g((t.top+t.bottom)/2+.5);else if(q(o)){const t=Object.keys(o)[0],e=o[t];p=g(this.chart.scales[t].getPixelForValue(e))}k=t.top,P=t.bottom,y=p+f,w=y+h}else if("y"===e){if("center"===o)p=g((t.left+t.right)/2);else if(q(o)){const t=Object.keys(o)[0],e=o[t];p=g(this.chart.scales[t].getPixelForValue(e))}_=p-f,v=_-h,M=t.left,S=t.right}const D=Z(s.ticks.maxTicksLimit,l),C=Math.max(1,Math.ceil(l/D));for(m=0;me.value===t));if(i>=0){return e.setContext(this.getContext(i)).lineWidth}return 0}drawGrid(t){const e=this.options.grid,i=this.ctx,s=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let n,o;const a=(t,e,s)=>{s.width&&s.color&&(i.save(),i.lineWidth=s.width,i.strokeStyle=s.color,i.setLineDash(s.borderDash||[]),i.lineDashOffset=s.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(e.display)for(n=0,o=s.length;n{this.drawBackground(),this.drawGrid(t),this.drawTitle()}},{z:i+1,draw:()=>{this.drawBorder()}},{z:e,draw:t=>{this.drawLabels(t)}}]:[{z:e,draw:t=>{this.draw(t)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),i=this.axis+"AxisID",s=[];let n,o;for(n=0,o=e.length;n{const s=i.split("."),n=s.pop(),o=[t].concat(s).join("."),a=e[i].split("."),r=a.pop(),l=a.join(".");yt.route(o,n,l,r)}))}(e,t.defaultRoutes);t.descriptors&&yt.describe(e,t.descriptors)}(t,o,i),this.override&&yt.override(t.id,t.overrides)),o}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,s=this.scope;i in e&&delete e[i],s&&i in yt[s]&&(delete yt[s][i],this.override&&delete mt[i])}}var Hs=new class{constructor(){this.controllers=new Ws(Cs,"datasets",!0),this.elements=new Ws(Os,"elements"),this.plugins=new Ws(Object,"plugins"),this.scales=new Ws(Ns,"scales"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each("register",t)}remove(...t){this._each("unregister",t)}addControllers(...t){this._each("register",t,this.controllers)}addElements(...t){this._each("register",t,this.elements)}addPlugins(...t){this._each("register",t,this.plugins)}addScales(...t){this._each("register",t,this.scales)}getController(t){return this._get(t,this.controllers,"controller")}getElement(t){return this._get(t,this.elements,"element")}getPlugin(t){return this._get(t,this.plugins,"plugin")}getScale(t){return this._get(t,this.scales,"scale")}removeControllers(...t){this._each("unregister",t,this.controllers)}removeElements(...t){this._each("unregister",t,this.elements)}removePlugins(...t){this._each("unregister",t,this.plugins)}removeScales(...t){this._each("unregister",t,this.scales)}_each(t,e,i){[...e].forEach((e=>{const s=i||this._getRegistryForType(e);i||s.isForType(e)||s===this.plugins&&e.id?this._exec(t,s,e):et(e,(e=>{const s=i||this._getRegistryForType(e);this._exec(t,s,e)}))}))}_exec(t,e,i){const s=dt(t);tt(i["before"+s],[],i),e[t](i),tt(i["after"+s],[],i)}_getRegistryForType(t){for(let e=0;et.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(s(e,i),t,"stop"),this._notify(s(i,e),t,"start")}}function $s(t,e){return e||!1!==t?!0===t?{}:t:null}function Ys(t,e,i,s){const n=t.pluginScopeKeys(e),o=t.getOptionScopes(i,n);return t.createResolver(o,s,[""],{scriptable:!1,indexable:!1,allKeys:!0})}function Us(t,e){const i=yt.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||"x"}function Xs(t,e){return"x"===t||"y"===t?t:e.axis||("top"===(i=e.position)||"bottom"===i?"x":"left"===i||"right"===i?"y":void 0)||t.charAt(0).toLowerCase();var i}function qs(t){const e=t.options||(t.options={});e.plugins=Z(e.plugins,{}),e.scales=function(t,e){const i=mt[t.type]||{scales:{}},s=e.scales||{},n=Us(t.type,e),o=Object.create(null),a=Object.create(null);return Object.keys(s).forEach((t=>{const e=s[t];if(!q(e))return console.error(`Invalid scale configuration for scale: ${t}`);if(e._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${t}`);const r=Xs(t,e),l=function(t,e){return t===e?"_index_":"_value_"}(r,n),h=i.scales||{};o[r]=o[r]||t,a[t]=rt(Object.create(null),[{axis:r},e,h[r],h[l]])})),t.data.datasets.forEach((i=>{const n=i.type||t.type,r=i.indexAxis||Us(n,e),l=(mt[n]||{}).scales||{};Object.keys(l).forEach((t=>{const e=function(t,e){let i=t;return"_index_"===t?i=e:"_value_"===t&&(i="x"===e?"y":"x"),i}(t,r),n=i[e+"AxisID"]||o[e]||e;a[n]=a[n]||Object.create(null),rt(a[n],[{axis:e},s[n],l[t]])}))})),Object.keys(a).forEach((t=>{const e=a[t];rt(e,[yt.scales[e.type],yt.scale])})),a}(t,e)}function Ks(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const Gs=new Map,Zs=new Set;function Js(t,e){let i=Gs.get(t);return i||(i=e(),Gs.set(t,i),Zs.add(i)),i}const Qs=(t,e,i)=>{const s=ct(e,i);void 0!==s&&t.add(s)};class tn{constructor(t){this._config=function(t){return(t=t||{}).data=Ks(t.data),qs(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Ks(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),qs(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return Js(t,(()=>[[`datasets.${t}`,""]]))}datasetAnimationScopeKeys(t,e){return Js(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]]))}datasetElementScopeKeys(t,e){return Js(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]]))}pluginScopeKeys(t){const e=t.id;return Js(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let s=i.get(t);return s&&!e||(s=new Map,i.set(t,s)),s}getOptionScopes(t,e,i){const{options:s,type:n}=this,o=this._cachedScopes(t,i),a=o.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>Qs(r,t,e)))),e.forEach((t=>Qs(r,s,t))),e.forEach((t=>Qs(r,mt[n]||{},t))),e.forEach((t=>Qs(r,yt,t))),e.forEach((t=>Qs(r,bt,t)))}));const l=Array.from(r);return 0===l.length&&l.push(Object.create(null)),Zs.has(e)&&o.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,mt[e]||{},yt.datasets[e]||{},{type:e},yt,bt]}resolveNamedOptions(t,e,i,s=[""]){const n={$shared:!0},{resolver:o,subPrefixes:a}=en(this._resolverCache,t,s);let r=o;if(function(t,e){const{isScriptable:i,isIndexable:s}=Te(t);for(const n of e){const e=i(n),o=s(n),a=(o||e)&&t[n];if(e&&(ft(a)||sn(a))||o&&X(a))return!0}return!1}(o,e)){n.$shared=!1;r=Ae(o,i=ft(i)?i():i,this.createResolver(t,i,a))}for(const t of e)n[t]=r[t];return n}createResolver(t,e,i=[""],s){const{resolver:n}=en(this._resolverCache,t,i);return q(e)?Ae(n,e,void 0,s):n}}function en(t,e,i){let s=t.get(e);s||(s=new Map,t.set(e,s));const n=i.join();let o=s.get(n);if(!o){o={resolver:Oe(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes("hover")))},s.set(n,o)}return o}const sn=t=>q(t)&&Object.getOwnPropertyNames(t).reduce(((e,i)=>e||ft(t[i])),!1);const nn=["top","bottom","left","right","chartArea"];function on(t,e){return"top"===t||"bottom"===t||-1===nn.indexOf(t)&&"x"===e}function an(t,e){return function(i,s){return i[t]===s[t]?i[e]-s[e]:i[t]-s[t]}}function rn(t){const e=t.chart,i=e.options.animation;e.notifyPlugins("afterRender"),tt(i&&i.onComplete,[t],e)}function ln(t){const e=t.chart,i=e.options.animation;tt(i&&i.onProgress,[t],e)}function hn(t){return ie()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const cn={},dn=t=>{const e=hn(t);return Object.values(cn).filter((t=>t.canvas===e)).pop()};function un(t,e,i){const s=Object.keys(t);for(const n of s){const s=+n;if(s>=e){const o=t[n];delete t[n],(i>0||s>e)&&(t[s+i]=o)}}}class fn{constructor(t,e){const s=this.config=new tn(e),n=hn(t),o=dn(n);if(o)throw new Error("Canvas is already in use. Chart with ID '"+o.id+"' must be destroyed before the canvas can be reused.");const r=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||cs(n)),this.platform.updateConfig(s);const l=this.platform.acquireContext(n,r.aspectRatio),h=l&&l.canvas,c=h&&h.height,d=h&&h.width;this.id=Y(),this.ctx=l,this.canvas=h,this.width=d,this.height=c,this._options=r,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new js,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=i((t=>this.update(t)),r.resizeDelay||0),this._dataChanges=[],cn[this.id]=this,l&&h?(a.listen(this,"complete",rn),a.listen(this,"progress",ln),this._initialize(),this.attached&&this.update()):console.error("Failed to create chart: can't acquire context from the given item")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:i,height:s,_aspectRatio:n}=this;return U(t)?e&&n?n:s?i/s:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}_initialize(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():ue(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}clear(){return _e(this.canvas,this.ctx),this}stop(){return a.stop(this),this}resize(t,e){a.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this.options,s=this.canvas,n=i.maintainAspectRatio&&this.aspectRatio,o=this.platform.getMaximumSize(s,t,e,n),a=i.devicePixelRatio||this.platform.getDevicePixelRatio(),r=this.width?"resize":"attach";this.width=o.width,this.height=o.height,this._aspectRatio=this.aspectRatio,ue(this,a,!0)&&(this.notifyPlugins("resize",{size:o}),tt(i.onResize,[this,o],this),this.attached&&this._doResize(r)&&this.render())}ensureScalesHaveIDs(){et(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this.options,e=t.scales,i=this.scales,s=Object.keys(i).reduce(((t,e)=>(t[e]=!1,t)),{});let n=[];e&&(n=n.concat(Object.keys(e).map((t=>{const i=e[t],s=Xs(t,i),n="r"===s,o="x"===s;return{options:i,dposition:n?"chartArea":o?"bottom":"left",dtype:n?"radialLinear":o?"category":"linear"}})))),et(n,(e=>{const n=e.options,o=n.id,a=Xs(o,n),r=Z(n.type,e.dtype);void 0!==n.position&&on(n.position,a)===on(e.dposition)||(n.position=e.dposition),s[o]=!0;let l=null;if(o in i&&i[o].type===r)l=i[o];else{l=new(Hs.getScale(r))({id:o,type:r,ctx:this.ctx,chart:this}),i[l.id]=l}l.init(n,t)})),et(s,((t,e)=>{t||delete i[e]})),et(i,(t=>{Xi.configure(this,t,t.options),Xi.addBox(this,t)}))}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,i=t.length;if(t.sort(((t,e)=>t.index-e.index)),i>e){for(let t=e;te.length&&delete this._stacks,t.forEach(((t,i)=>{0===e.filter((e=>e===t._dataset)).length&&this._destroyDatasetMeta(i)}))}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let i,s;for(this._removeUnreferencedMetasets(),i=0,s=e.length;i{this.getDatasetMeta(e).controller.reset()}),this)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){const e=this.config;e.update();const i=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),s=this._animationsDisabled=!i.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),!1===this.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0}))return;const n=this.buildOrUpdateControllers();this.notifyPlugins("beforeElementsUpdate");let o=0;for(let t=0,e=this.data.datasets.length;t{t.reset()})),this._updateDatasets(t),this.notifyPlugins("afterUpdate",{mode:t}),this._layers.sort(an("z","_idx"));const{_active:a,_lastEvent:r}=this;r?this._eventHandler(r,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){et(this.scales,(t=>{Xi.removeBox(this,t)})),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),i=new Set(t.events);gt(e,i)&&!!this._responsiveListeners===t.responsive||(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:i,start:s,count:n}of e){un(t,s,"_removeElements"===i?-n:n)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,i=e=>new Set(t.filter((t=>t[0]===e)).map(((t,e)=>e+","+t.splice(1).join(",")))),s=i(0);for(let t=1;tt.split(","))).map((t=>({method:t[1],start:+t[2],count:+t[3]})))}_updateLayout(t){if(!1===this.notifyPlugins("beforeLayout",{cancelable:!0}))return;Xi.update(this,this.width,this.height,t);const e=this.chartArea,i=e.width<=0||e.height<=0;this._layers=[],et(this.boxes,(t=>{i&&"chartArea"===t.position||(t.configure&&t.configure(),this._layers.push(...t._layers()))}),this),this._layers.forEach(((t,e)=>{t._idx=e})),this.notifyPlugins("afterLayout")}_updateDatasets(t){if(!1!==this.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})){for(let t=0,e=this.data.datasets.length;t=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this.ctx,i=t._clip,s=!i.disabled,n=this.chartArea,o={meta:t,index:t.index,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetDraw",o)&&(s&&we(e,{left:!1===i.left?0:n.left-i.left,right:!1===i.right?this.width:n.right+i.right,top:!1===i.top?0:n.top-i.top,bottom:!1===i.bottom?this.height:n.bottom+i.bottom}),t.controller.draw(),s&&Me(e),o.cancelable=!1,this.notifyPlugins("afterDatasetDraw",o))}isPointInArea(t){return ve(t,this.chartArea,this._minPadding)}getElementsAtEventForMode(t,e,i,s){const n=Ei.modes[e];return"function"==typeof n?n(this,t,i,s):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let s=i.filter((t=>t&&t._dataset===e)).pop();return s||(s={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(s)),s}getContext(){return this.$context||(this.$context=pi(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return"boolean"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,i){const s=i?"show":"hide",n=this.getDatasetMeta(t),o=n.controller._resolveAnimations(void 0,s);ut(e)?(n.data[e].hidden=!i,this.update()):(this.setDatasetVisibility(t,i),o.update(n,{visible:i}),this.update((e=>e.datasetIndex===t?s:void 0)))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),a.remove(this),t=0,e=this.data.datasets.length;t{e.addEventListener(this,i,s),t[i]=s},s=(t,e,i)=>{t.offsetX=e,t.offsetY=i,this._eventHandler(t)};et(this.options.events,(t=>i(t,s)))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(i,s)=>{t[i]&&(e.removeEventListener(this,i,s),delete t[i])},n=(t,e)=>{this.canvas&&this.resize(t,e)};let o;const a=()=>{s("attach",a),this.attached=!0,this.resize(),i("resize",n),i("detach",o)};o=()=>{this.attached=!1,s("resize",n),this._stop(),this._resize(0,0),i("attach",a)},e.isAttached(this.canvas)?a():o()}unbindEvents(){et(this._listeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._listeners={},et(this._responsiveListeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._responsiveListeners=void 0}updateHoverStyle(t,e,i){const s=i?"set":"remove";let n,o,a,r;for("dataset"===e&&(n=this.getDatasetMeta(t[0].datasetIndex),n.controller["_"+s+"DatasetHoverStyle"]()),a=0,r=t.length;a{const i=this.getDatasetMeta(t);if(!i)throw new Error("No dataset found at index "+t);return{datasetIndex:t,element:i.data[e],index:e}}));!it(i,e)&&(this._active=i,this._lastEvent=null,this._updateHoverStyles(i,e))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}_updateHoverStyles(t,e,i){const s=this.options.hover,n=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),o=n(e,t),a=i?t:n(t,e);o.length&&this.updateHoverStyle(o,s.mode,!1),a.length&&s.mode&&this.updateHoverStyle(a,s.mode,!0)}_eventHandler(t,e){const i={event:t,replay:e,cancelable:!0,inChartArea:this.isPointInArea(t)},s=e=>(e.options.events||this.options.events).includes(t.native.type);if(!1===this.notifyPlugins("beforeEvent",i,s))return;const n=this._handleEvent(t,e,i.inChartArea);return i.cancelable=!1,this.notifyPlugins("afterEvent",i,s),(n||i.changed)&&this.render(),this}_handleEvent(t,e,i){const{_active:s=[],options:n}=this,o=e,a=this._getActiveElements(t,s,i,o),r=pt(t),l=function(t,e,i,s){return i&&"mouseout"!==t.type?s?e:t:null}(t,this._lastEvent,i,r);i&&(this._lastEvent=null,tt(n.onHover,[t,a,this],this),r&&tt(n.onClick,[t,a,this],this));const h=!it(a,s);return(h||e)&&(this._active=a,this._updateHoverStyles(a,s,e)),this._lastEvent=l,h}_getActiveElements(t,e,i,s){if("mouseout"===t.type)return[];if(!i)return e;const n=this.options.hover;return this.getElementsAtEventForMode(t,n.mode,n,s)}}const gn=()=>et(fn.instances,(t=>t._plugins.invalidate())),pn=!0;function mn(){throw new Error("This method is not implemented: Check that a complete date adapter is provided.")}Object.defineProperties(fn,{defaults:{enumerable:pn,value:yt},instances:{enumerable:pn,value:cn},overrides:{enumerable:pn,value:mt},registry:{enumerable:pn,value:Hs},version:{enumerable:pn,value:"3.8.0"},getChart:{enumerable:pn,value:dn},register:{enumerable:pn,value:(...t)=>{Hs.add(...t),gn()}},unregister:{enumerable:pn,value:(...t)=>{Hs.remove(...t),gn()}}});class bn{constructor(t){this.options=t||{}}formats(){return mn()}parse(t,e){return mn()}format(t,e){return mn()}add(t,e,i){return mn()}diff(t,e,i){return mn()}startOf(t,e,i){return mn()}endOf(t,e){return mn()}}bn.override=function(t){Object.assign(bn.prototype,t)};var xn={_date:bn};function _n(t){const e=t.iScale,i=function(t,e){if(!t._cache.$bar){const i=t.getMatchingVisibleMetas(e);let s=[];for(let e=0,n=i.length;et-e)))}return t._cache.$bar}(e,t.type);let s,n,o,a,r=e._length;const l=()=>{32767!==o&&-32768!==o&&(ut(a)&&(r=Math.min(r,Math.abs(o-a)||r)),a=o)};for(s=0,n=i.length;sMath.abs(r)&&(l=r,h=a),e[i.axis]=h,e._custom={barStart:l,barEnd:h,start:n,end:o,min:a,max:r}}(t,e,i,s):e[i.axis]=i.parse(t,s),e}function vn(t,e,i,s){const n=t.iScale,o=t.vScale,a=n.getLabels(),r=n===o,l=[];let h,c,d,u;for(h=i,c=i+s;ht.x,i="left",s="right"):(e=t.base=i?1:-1)}(c,e,o)*n,d===o&&(p-=c/2);const t=e.getPixelForDecimal(0),i=e.getPixelForDecimal(1),s=Math.min(t,i),a=Math.max(t,i);p=Math.max(Math.min(p,a),s),h=p+c}if(p===e.getPixelForValue(o)){const t=Bt(c)*e.getLineWidthForValue(o)/2;p+=t,c-=t}return{size:c,base:p,head:h,center:h+c/2}}_calculateBarIndexPixels(t,e){const i=e.scale,s=this.options,n=s.skipNull,o=Z(s.maxBarThickness,1/0);let a,r;if(e.grouped){const i=n?this._getStackCount(t):e.stackCount,l="flex"===s.barThickness?function(t,e,i,s){const n=e.pixels,o=n[t];let a=t>0?n[t-1]:null,r=t=0;--i)e=Math.max(e,t[i].size(this.resolveDataElementOptions(i))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,{xScale:i,yScale:s}=e,n=this.getParsed(t),o=i.getLabelForValue(n.x),a=s.getLabelForValue(n.y),r=n._custom;return{label:e.label,value:"("+o+", "+a+(r?", "+r:"")+")"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a}=this._cachedMeta,r=this.resolveDataElementOptions(e,s),l=this.getSharedOptions(r),h=this.includeOptions(s,l),c=o.axis,d=a.axis;for(let r=e;r""}}}};class On extends Cs{constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,s=this._cachedMeta;if(!1===this._parsing)s._parsed=i;else{let n,o,a=t=>+i[t];if(q(i[t])){const{key:t="value"}=this._parsing;a=e=>+ct(i[e],t)}for(n=t,o=t+e;nJt(t,r,l,!0)?1:Math.max(e,e*i,s,s*i),g=(t,e,s)=>Jt(t,r,l,!0)?-1:Math.min(e,e*i,s,s*i),p=f(0,h,d),m=f(Et,c,u),b=g(Ot,h,d),x=g(Ot+Et,c,u);s=(p-b)/2,n=(m-x)/2,o=-(p+b)/2,a=-(m+x)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:a}}(c,h,r),p=(i.width-o)/d,m=(i.height-o)/u,b=Math.max(Math.min(p,m)/2,0),x=Q(this.options.radius,b),_=(x-Math.max(x*r,0))/this._getVisibleDatasetWeightTotal();this.offsetX=f*x,this.offsetY=g*x,s.total=this.calculateTotal(),this.outerRadius=x-_*this._getRingWeightOffset(this.index),this.innerRadius=Math.max(this.outerRadius-_*l,0),this.updateElements(n,0,n.length,t)}_circumference(t,e){const i=this.options,s=this._cachedMeta,n=this._getCircumference();return e&&i.animation.animateRotate||!this.chart.getDataVisibility(t)||null===s._parsed[t]||s.data[t].hidden?0:this.calculateCircumference(s._parsed[t]*n/At)}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.chartArea,r=o.options.animation,l=(a.left+a.right)/2,h=(a.top+a.bottom)/2,c=n&&r.animateScale,d=c?0:this.innerRadius,u=c?0:this.outerRadius,f=this.resolveDataElementOptions(e,s),g=this.getSharedOptions(f),p=this.includeOptions(s,g);let m,b=this._getRotation();for(m=0;m0&&!isNaN(t)?At*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=ni(e._parsed[t],i.options.locale);return{label:s[t]||"",value:n}}getMaxBorderWidth(t){let e=0;const i=this.chart;let s,n,o,a,r;if(!t)for(s=0,n=i.data.datasets.length;s"spacing"!==t,_indexable:t=>"spacing"!==t},On.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label(t){let e=t.label;const i=": "+t.formattedValue;return X(e)?(e=e.slice(),e[0]+=i):e+=i,e}}}}};class An extends Cs{initialize(){this.enableOptionSharing=!0,this.supportsDecimation=!0,super.initialize()}update(t){const e=this._cachedMeta,{dataset:i,data:s=[],_dataset:n}=e,o=this.chart._animationsDisabled;let{start:a,count:r}=function(t,e,i){const s=e.length;let n=0,o=s;if(t._sorted){const{iScale:a,_parsed:r}=t,l=a.axis,{min:h,max:c,minDefined:d,maxDefined:u}=a.getUserBounds();d&&(n=Qt(Math.min(wt(r,a.axis,h).lo,i?s:wt(e,l,a.getPixelForValue(h)).lo),0,s-1)),o=u?Qt(Math.max(wt(r,a.axis,c).hi+1,i?0:wt(e,l,a.getPixelForValue(c)).hi+1),n,s)-n:s-n}return{start:n,count:o}}(e,s,o);this._drawStart=a,this._drawCount=r,function(t){const{xScale:e,yScale:i,_scaleRanges:s}=t,n={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!s)return t._scaleRanges=n,!0;const o=s.xmin!==e.min||s.xmax!==e.max||s.ymin!==i.min||s.ymax!==i.max;return Object.assign(s,n),o}(e)&&(a=0,r=s.length),i._chart=this.chart,i._datasetIndex=this.index,i._decimated=!!n._decimated,i.points=s;const l=this.resolveDatasetElementOptions(t);this.options.showLine||(l.borderWidth=0),l.segment=this.options.segment,this.updateElement(i,void 0,{animated:!o,options:l},t),this.updateElements(s,a,r,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a,_stacked:r,_dataset:l}=this._cachedMeta,h=this.resolveDataElementOptions(e,s),c=this.getSharedOptions(h),d=this.includeOptions(s,c),u=o.axis,f=a.axis,{spanGaps:g,segment:p}=this.options,m=Wt(g)?g:Number.POSITIVE_INFINITY,b=this.chart._animationsDisabled||n||"none"===s;let x=e>0&&this.getParsed(e-1);for(let h=e;h0&&Math.abs(i[u]-x[u])>m,p&&(g.parsed=i,g.raw=l.data[h]),d&&(g.options=c||this.resolveDataElementOptions(h,e.active?"active":s)),b||this.updateElement(e,h,g,s),x=i}this.updateSharedOptions(c,s,h)}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,i=e.options&&e.options.borderWidth||0,s=t.data||[];if(!s.length)return i;const n=s[0].size(this.resolveDataElementOptions(0)),o=s[s.length-1].size(this.resolveDataElementOptions(s.length-1));return Math.max(i,n,o)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}}An.id="line",An.defaults={datasetElementType:"line",dataElementType:"point",showLine:!0,spanGaps:!1},An.overrides={scales:{_index_:{type:"category"},_value_:{type:"linear"}}};class Tn extends Cs{constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=ni(e._parsed[t].r,i.options.locale);return{label:s[t]||"",value:n}}parseObjectData(t,e,i,s){return He.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}getMinMax(){const t=this._cachedMeta,e={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};return t.data.forEach(((t,i)=>{const s=this.getParsed(i).r;!isNaN(s)&&this.chart.getDataVisibility(i)&&(se.max&&(e.max=s))})),e}_updateRadius(){const t=this.chart,e=t.chartArea,i=t.options,s=Math.min(e.right-e.left,e.bottom-e.top),n=Math.max(s/2,0),o=(n-Math.max(i.cutoutPercentage?n/100*i.cutoutPercentage:1,0))/t.getVisibleDatasetCount();this.outerRadius=n-o*this.index,this.innerRadius=this.outerRadius-o}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.options.animation,r=this._cachedMeta.rScale,l=r.xCenter,h=r.yCenter,c=r.getIndexAngle(0)-.5*Ot;let d,u=c;const f=360/this.countVisibleElements();for(d=0;d{!isNaN(this.getParsed(i).r)&&this.chart.getDataVisibility(i)&&e++})),e}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?Yt(this.resolveDataElementOptions(t,e).angle||i):0}}Tn.id="polarArea",Tn.defaults={dataElementType:"arc",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:"number",properties:["x","y","startAngle","endAngle","innerRadius","outerRadius"]}},indexAxis:"r",startAngle:0},Tn.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label:t=>t.chart.data.labels[t.dataIndex]+": "+t.formattedValue}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};class Ln extends On{}Ln.id="pie",Ln.defaults={cutout:0,rotation:0,circumference:360,radius:"100%"};class Rn extends Cs{getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(i[e.axis])}}parseObjectData(t,e,i,s){return He.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta,i=e.dataset,s=e.data||[],n=e.iScale.getLabels();if(i.points=s,"resize"!==t){const e=this.resolveDatasetElementOptions(t);this.options.showLine||(e.borderWidth=0);const o={_loop:!0,_fullLoop:n.length===s.length,options:e};this.updateElement(i,void 0,o,t)}this.updateElements(s,0,s.length,t)}updateElements(t,e,i,s){const n=this._cachedMeta.rScale,o="reset"===s;for(let a=e;a"",label:t=>"("+t.label+", "+t.formattedValue+")"}}},scales:{x:{type:"linear"},y:{type:"linear"}}};var In=Object.freeze({__proto__:null,BarController:Dn,BubbleController:Cn,DoughnutController:On,LineController:An,PolarAreaController:Tn,PieController:Ln,RadarController:Rn,ScatterController:En});function zn(t,e,i){const{startAngle:s,pixelMargin:n,x:o,y:a,outerRadius:r,innerRadius:l}=e;let h=n/r;t.beginPath(),t.arc(o,a,r,s-h,i+h),l>n?(h=n/l,t.arc(o,a,l,i+h,s-h,!0)):t.arc(o,a,n,i+Et,s-Et),t.closePath(),t.clip()}function Fn(t,e,i,s){const n=li(t.options.borderRadius,["outerStart","outerEnd","innerStart","innerEnd"]);const o=(i-e)/2,a=Math.min(o,s*e/2),r=t=>{const e=(i-Math.min(o,t))*s/2;return Qt(t,0,Math.min(o,e))};return{outerStart:r(n.outerStart),outerEnd:r(n.outerEnd),innerStart:Qt(n.innerStart,0,a),innerEnd:Qt(n.innerEnd,0,a)}}function Bn(t,e,i,s){return{x:i+t*Math.cos(e),y:s+t*Math.sin(e)}}function Vn(t,e,i,s,n){const{x:o,y:a,startAngle:r,pixelMargin:l,innerRadius:h}=e,c=Math.max(e.outerRadius+s+i-l,0),d=h>0?h+s+i+l:0;let u=0;const f=n-r;if(s){const t=((h>0?h-s:0)+(c>0?c-s:0))/2;u=(f-(0!==t?f*t/(t+s):f))/2}const g=(f-Math.max(.001,f*c-i/Ot)/c)/2,p=r+g+u,m=n-g-u,{outerStart:b,outerEnd:x,innerStart:_,innerEnd:y}=Fn(e,d,c,m-p),v=c-b,w=c-x,M=p+b/v,k=m-x/w,S=d+_,P=d+y,D=p+_/S,C=m-y/P;if(t.beginPath(),t.arc(o,a,c,M,k),x>0){const e=Bn(w,k,o,a);t.arc(e.x,e.y,x,k,m+Et)}const O=Bn(P,m,o,a);if(t.lineTo(O.x,O.y),y>0){const e=Bn(P,C,o,a);t.arc(e.x,e.y,y,m+Et,C+Math.PI)}if(t.arc(o,a,d,m-y/d,p+_/d,!0),_>0){const e=Bn(S,D,o,a);t.arc(e.x,e.y,_,D+Math.PI,p-Et)}const A=Bn(v,p,o,a);if(t.lineTo(A.x,A.y),b>0){const e=Bn(v,M,o,a);t.arc(e.x,e.y,b,p-Et,M)}t.closePath()}function Nn(t,e,i,s,n){const{options:o}=e,{borderWidth:a,borderJoinStyle:r}=o,l="inner"===o.borderAlign;a&&(l?(t.lineWidth=2*a,t.lineJoin=r||"round"):(t.lineWidth=a,t.lineJoin=r||"bevel"),e.fullCircles&&function(t,e,i){const{x:s,y:n,startAngle:o,pixelMargin:a,fullCircles:r}=e,l=Math.max(e.outerRadius-a,0),h=e.innerRadius+a;let c;for(i&&zn(t,e,o+At),t.beginPath(),t.arc(s,n,h,o+At,o,!0),c=0;c=At||Jt(n,a,r),f=ee(o,l+d,h+d);return u&&f}getCenterPoint(t){const{x:e,y:i,startAngle:s,endAngle:n,innerRadius:o,outerRadius:a}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius","circumference"],t),{offset:r,spacing:l}=this.options,h=(s+n)/2,c=(o+a+l+r)/2;return{x:e+Math.cos(h)*c,y:i+Math.sin(h)*c}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:i}=this,s=(e.offset||0)/2,n=(e.spacing||0)/2;if(this.pixelMargin="inner"===e.borderAlign?.33:0,this.fullCircles=i>At?Math.floor(i/At):0,0===i||this.innerRadius<0||this.outerRadius<0)return;t.save();let o=0;if(s){o=s/2;const e=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(e)*o,Math.sin(e)*o),this.circumference>=Ot&&(o=s)}t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor;const a=function(t,e,i,s){const{fullCircles:n,startAngle:o,circumference:a}=e;let r=e.endAngle;if(n){Vn(t,e,i,s,o+At);for(let e=0;er&&o>r;return{count:s,start:l,loop:e.loop,ilen:h(a+(h?r-t:t))%o,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=n[x(0)],t.moveTo(d.x,d.y)),c=0;c<=r;++c){if(d=n[x(c)],d.skip)continue;const e=d.x,i=d.y,s=0|e;s===u?(ig&&(g=i),m=(b*m+e)/++b):(_(),t.lineTo(e,i),u=s,b=0,f=g=i),p=i}_()}function Xn(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||i)?Un:Yn}Wn.id="arc",Wn.defaults={borderAlign:"center",borderColor:"#fff",borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0},Wn.defaultRoutes={backgroundColor:"backgroundColor"};const qn="function"==typeof Path2D;function Kn(t,e,i,s){qn&&!e.options.segment?function(t,e,i,s){let n=e._path;n||(n=e._path=new Path2D,e.path(n,i,s)&&n.closePath()),Hn(t,e.options),t.stroke(n)}(t,e,i,s):function(t,e,i,s){const{segments:n,options:o}=e,a=Xn(e);for(const r of n)Hn(t,o,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+s-1})&&t.closePath(),t.stroke()}(t,e,i,s)}class Gn extends Os{constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this.options;if((i.tension||"monotone"===i.cubicInterpolationMode)&&!i.stepped&&!this._pointsUpdated){const s=i.spanGaps?this._loop:this._fullLoop;Ke(this._points,i,t,s,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=Mi(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this.options,s=t[e],n=this.points,o=wi(this,{property:e,start:s,end:s});if(!o.length)return;const a=[],r=function(t){return t.stepped?ei:t.tension||"monotone"===t.cubicInterpolationMode?ii:ti}(i);let l,h;for(l=0,h=o.length;l"borderDash"!==t&&"fill"!==t};class Jn extends Os{constructor(t){super(),this.options=void 0,this.parsed=void 0,this.skip=void 0,this.stop=void 0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.options,{x:n,y:o}=this.getProps(["x","y"],i);return Math.pow(t-n,2)+Math.pow(e-o,2){ro(t)}))}var ho={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(t,e,i)=>{if(!i.enabled)return void lo(t);const s=t.width;t.data.datasets.forEach(((e,n)=>{const{_data:o,indexAxis:a}=e,r=t.getDatasetMeta(n),l=o||e.data;if("y"===fi([a,t.options.indexAxis]))return;if(!r.controller.supportsDecimation)return;const h=t.scales[r.xAxisID];if("linear"!==h.type&&"time"!==h.type)return;if(t.options.parsing)return;let{start:c,count:d}=function(t,e){const i=e.length;let s,n=0;const{iScale:o}=t,{min:a,max:r,minDefined:l,maxDefined:h}=o.getUserBounds();return l&&(n=Qt(wt(e,o.axis,a).lo,0,i-1)),s=h?Qt(wt(e,o.axis,r).hi+1,n,i)-n:i-n,{start:n,count:s}}(r,l);if(d<=(i.threshold||4*s))return void ro(e);let u;switch(U(o)&&(e._data=l,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),i.algorithm){case"lttb":u=function(t,e,i,s,n){const o=n.samples||s;if(o>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(o-2);let l=0;const h=e+i-1;let c,d,u,f,g,p=e;for(a[l++]=t[p],c=0;cu&&(u=f,d=t[s],g=s);a[l++]=d,p=g}return a[l++]=t[h],a}(l,c,d,s,i);break;case"min-max":u=function(t,e,i,s){let n,o,a,r,l,h,c,d,u,f,g=0,p=0;const m=[],b=e+i-1,x=t[e].x,_=t[b].x-x;for(n=e;nf&&(f=r,c=n),g=(p*g+o.x)/++p;else{const i=n-1;if(!U(h)&&!U(c)){const e=Math.min(h,c),s=Math.max(h,c);e!==d&&e!==i&&m.push({...t[e],x:g}),s!==d&&s!==i&&m.push({...t[s],x:g})}n>0&&i!==d&&m.push(t[i]),m.push(o),l=e,p=0,u=f=r,h=c=d=n}}return m}(l,c,d,s);break;default:throw new Error(`Unsupported decimation algorithm '${i.algorithm}'`)}e._decimated=u}))},destroy(t){lo(t)}};function co(t,e,i,s){if(s)return;let n=e[t],o=i[t];return"angle"===t&&(n=Zt(n),o=Zt(o)),{property:t,start:n,end:o}}function uo(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function fo(t,e,i,s){return t&&e?s(t[i],e[i]):t?t[i]:e?e[i]:0}function go(t,e){let i=[],s=!1;return X(t)?(s=!0,i=t):i=function(t,e){const{x:i=null,y:s=null}=t||{},n=e.points,o=[];return e.segments.forEach((({start:t,end:e})=>{e=uo(t,e,n);const a=n[t],r=n[e];null!==s?(o.push({x:a.x,y:s}),o.push({x:r.x,y:s})):null!==i&&(o.push({x:i,y:a.y}),o.push({x:i,y:r.y}))})),o}(t,e),i.length?new Gn({points:i,options:{tension:0},_loop:s,_fullLoop:s}):null}function po(t,e,i){let s=t[e].fill;const n=[e];let o;if(!i)return s;for(;!1!==s&&-1===n.indexOf(s);){if(!K(s))return s;if(o=t[s],!o)return!1;if(o.visible)return s;n.push(s),s=o.fill}return!1}function mo(t,e,i){const s=function(t){const e=t.options,i=e.fill;let s=Z(i&&i.target,i);void 0===s&&(s=!!e.backgroundColor);if(!1===s||null===s)return!1;if(!0===s)return"origin";return s}(t);if(q(s))return!isNaN(s.value)&&s;let n=parseFloat(s);return K(n)&&Math.floor(n)===n?function(t,e,i,s){"-"!==t&&"+"!==t||(i=e+i);if(i===e||i<0||i>=s)return!1;return i}(s[0],e,n,i):["origin","start","end","stack","shape"].indexOf(s)>=0&&s}function bo(t,e,i){const s=[];for(let n=0;n=0;--e){const i=n[e].$filler;i&&(i.line.updateControlPoints(o,i.axis),s&&vo(t.ctx,i,o))}},beforeDatasetsDraw(t,e,i){if("beforeDatasetsDraw"!==i.drawTime)return;const s=t.getSortedVisibleDatasetMetas();for(let e=s.length-1;e>=0;--e){const i=s[e].$filler;i&&vo(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const s=e.meta.$filler;s&&!1!==s.fill&&"beforeDatasetDraw"===i.drawTime&&vo(t.ctx,s,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}};const Do=(t,e)=>{let{boxHeight:i=e,boxWidth:s=e}=t;return t.usePointStyle&&(i=Math.min(i,e),s=Math.min(s,e)),{boxWidth:s,boxHeight:i,itemHeight:Math.max(e,i)}};class Co extends Os{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){this.maxWidth=t,this.maxHeight=e,this._margins=i,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=tt(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter((e=>t.filter(e,this.chart.data)))),t.sort&&(e=e.sort(((e,i)=>t.sort(e,i,this.chart.data)))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display)return void(this.width=this.height=0);const i=t.labels,s=ui(i.font),n=s.size,o=this._computeTitleHeight(),{boxWidth:a,itemHeight:r}=Do(i,n);let l,h;e.font=s.string,this.isHorizontal()?(l=this.maxWidth,h=this._fitRows(o,n,a,r)+10):(h=this.maxHeight,l=this._fitCols(o,n,a,r)+10),this.width=Math.min(l,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,i,s){const{ctx:n,maxWidth:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.lineWidths=[0],h=s+a;let c=t;n.textAlign="left",n.textBaseline="middle";let d=-1,u=-h;return this.legendItems.forEach(((t,f)=>{const g=i+e/2+n.measureText(t.text).width;(0===f||l[l.length-1]+g+2*a>o)&&(c+=h,l[l.length-(f>0?0:1)]=0,u+=h,d++),r[f]={left:0,top:u,row:d,width:g,height:s},l[l.length-1]+=g+a})),c}_fitCols(t,e,i,s){const{ctx:n,maxHeight:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.columnSizes=[],h=o-t;let c=a,d=0,u=0,f=0,g=0;return this.legendItems.forEach(((t,o)=>{const p=i+e/2+n.measureText(t.text).width;o>0&&u+s+2*a>h&&(c+=d+a,l.push({width:d,height:u}),f+=d+a,g++,d=u=0),r[o]={left:f,top:u,col:g,width:p,height:s},d=Math.max(d,p),u+=s+a})),c+=d,l.push({width:d,height:u}),c}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:i,labels:{padding:s},rtl:o}}=this,a=mi(o,this.left,this.width);if(this.isHorizontal()){let o=0,r=n(i,this.left+s,this.right-this.lineWidths[o]);for(const l of e)o!==l.row&&(o=l.row,r=n(i,this.left+s,this.right-this.lineWidths[o])),l.top+=this.top+t+s,l.left=a.leftForLtr(a.x(r),l.width),r+=l.width+s}else{let o=0,r=n(i,this.top+t+s,this.bottom-this.columnSizes[o].height);for(const l of e)l.col!==o&&(o=l.col,r=n(i,this.top+t+s,this.bottom-this.columnSizes[o].height)),l.top=r,l.left+=this.left+s,l.left=a.leftForLtr(a.x(l.left),l.width),r+=l.height+s}}isHorizontal(){return"top"===this.options.position||"bottom"===this.options.position}draw(){if(this.options.display){const t=this.ctx;we(t,this),this._draw(),Me(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:i,ctx:s}=this,{align:a,labels:r}=t,l=yt.color,h=mi(t.rtl,this.left,this.width),c=ui(r.font),{color:d,padding:u}=r,f=c.size,g=f/2;let p;this.drawTitle(),s.textAlign=h.textAlign("left"),s.textBaseline="middle",s.lineWidth=.5,s.font=c.string;const{boxWidth:m,boxHeight:b,itemHeight:x}=Do(r,f),_=this.isHorizontal(),y=this._computeTitleHeight();p=_?{x:n(a,this.left+u,this.right-i[0]),y:this.top+u+y,line:0}:{x:this.left+u,y:n(a,this.top+y+u,this.bottom-e[0].height),line:0},bi(this.ctx,t.textDirection);const v=x+u;this.legendItems.forEach(((w,M)=>{s.strokeStyle=w.fontColor||d,s.fillStyle=w.fontColor||d;const k=s.measureText(w.text).width,S=h.textAlign(w.textAlign||(w.textAlign=r.textAlign)),P=m+g+k;let D=p.x,C=p.y;h.setWidth(this.width),_?M>0&&D+P+u>this.right&&(C=p.y+=v,p.line++,D=p.x=n(a,this.left+u,this.right-i[p.line])):M>0&&C+v>this.bottom&&(D=p.x=D+e[p.line].width+u,p.line++,C=p.y=n(a,this.top+y+u,this.bottom-e[p.line].height));!function(t,e,i){if(isNaN(m)||m<=0||isNaN(b)||b<0)return;s.save();const n=Z(i.lineWidth,1);if(s.fillStyle=Z(i.fillStyle,l),s.lineCap=Z(i.lineCap,"butt"),s.lineDashOffset=Z(i.lineDashOffset,0),s.lineJoin=Z(i.lineJoin,"miter"),s.lineWidth=n,s.strokeStyle=Z(i.strokeStyle,l),s.setLineDash(Z(i.lineDash,[])),r.usePointStyle){const o={radius:m*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},a=h.xPlus(t,m/2);ye(s,o,a,e+g)}else{const o=e+Math.max((f-b)/2,0),a=h.leftForLtr(t,m),r=ci(i.borderRadius);s.beginPath(),Object.values(r).some((t=>0!==t))?Ce(s,{x:a,y:o,w:m,h:b,radius:r}):s.rect(a,o,m,b),s.fill(),0!==n&&s.stroke()}s.restore()}(h.x(D),C,w),D=o(S,D+m+g,_?D+P:this.right,t.rtl),function(t,e,i){Pe(s,i.text,t,e+x/2,c,{strikethrough:i.hidden,textAlign:h.textAlign(i.textAlign)})}(h.x(D),C,w),_?p.x+=P+u:p.y+=v})),xi(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,i=ui(e.font),o=di(e.padding);if(!e.display)return;const a=mi(t.rtl,this.left,this.width),r=this.ctx,l=e.position,h=i.size/2,c=o.top+h;let d,u=this.left,f=this.width;if(this.isHorizontal())f=Math.max(...this.lineWidths),d=this.top+c,u=n(t.align,u,this.right-f);else{const e=this.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);d=c+n(t.align,this.top,this.bottom-e-t.labels.padding-this._computeTitleHeight())}const g=n(l,u,u+f);r.textAlign=a.textAlign(s(l)),r.textBaseline="middle",r.strokeStyle=e.color,r.fillStyle=e.color,r.font=i.string,Pe(r,e.text,g,d,i)}_computeTitleHeight(){const t=this.options.title,e=ui(t.font),i=di(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){let i,s,n;if(ee(t,this.left,this.right)&&ee(e,this.top,this.bottom))for(n=this.legendHitBoxes,i=0;it.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:s,textAlign:n,color:o}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const a=t.controller.getStyle(i?0:void 0),r=di(a.borderWidth);return{text:e[t.index].label,fillStyle:a.backgroundColor,fontColor:o,hidden:!t.visible,lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:(r.width+r.height)/4,strokeStyle:a.borderColor,pointStyle:s||a.pointStyle,rotation:a.rotation,textAlign:n||a.textAlign,borderRadius:0,datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:t=>!t.startsWith("on"),labels:{_scriptable:t=>!["generateLabels","filter","sort"].includes(t)}}};class Ao extends Os{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this.options;if(this.left=0,this.top=0,!i.display)return void(this.width=this.height=this.right=this.bottom=0);this.width=this.right=t,this.height=this.bottom=e;const s=X(i.text)?i.text.length:1;this._padding=di(i.padding);const n=s*ui(i.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=n:this.width=n}isHorizontal(){const t=this.options.position;return"top"===t||"bottom"===t}_drawArgs(t){const{top:e,left:i,bottom:s,right:o,options:a}=this,r=a.align;let l,h,c,d=0;return this.isHorizontal()?(h=n(r,i,o),c=e+t,l=o-i):("left"===a.position?(h=i+t,c=n(r,s,e),d=-.5*Ot):(h=o-t,c=n(r,e,s),d=.5*Ot),l=s-e),{titleX:h,titleY:c,maxWidth:l,rotation:d}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const i=ui(e.font),n=i.lineHeight/2+this._padding.top,{titleX:o,titleY:a,maxWidth:r,rotation:l}=this._drawArgs(n);Pe(t,e.text,0,0,i,{color:e.color,maxWidth:r,rotation:l,textAlign:s(e.align),textBaseline:"middle",translation:[o,a]})}}var To={id:"title",_element:Ao,start(t,e,i){!function(t,e){const i=new Ao({ctx:t.ctx,options:e,chart:t});Xi.configure(t,i,e),Xi.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;Xi.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const s=t.titleBlock;Xi.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Lo=new WeakMap;var Ro={id:"subtitle",start(t,e,i){const s=new Ao({ctx:t.ctx,options:i,chart:t});Xi.configure(t,s,i),Xi.addBox(t,s),Lo.set(t,s)},stop(t){Xi.removeBox(t,Lo.get(t)),Lo.delete(t)},beforeUpdate(t,e,i){const s=Lo.get(t);Xi.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Eo={average(t){if(!t.length)return!1;let e,i,s=0,n=0,o=0;for(e=0,i=t.length;e-1?t.split("\n"):t}function Fo(t,e){const{element:i,datasetIndex:s,index:n}=e,o=t.getDatasetMeta(s).controller,{label:a,value:r}=o.getLabelAndValue(n);return{chart:t,label:a,parsed:o.getParsed(n),raw:t.data.datasets[s].data[n],formattedValue:r,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:i}}function Bo(t,e){const i=t.chart.ctx,{body:s,footer:n,title:o}=t,{boxWidth:a,boxHeight:r}=e,l=ui(e.bodyFont),h=ui(e.titleFont),c=ui(e.footerFont),d=o.length,u=n.length,f=s.length,g=di(e.padding);let p=g.height,m=0,b=s.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(b+=t.beforeBody.length+t.afterBody.length,d&&(p+=d*h.lineHeight+(d-1)*e.titleSpacing+e.titleMarginBottom),b){p+=f*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(b-f)*l.lineHeight+(b-1)*e.bodySpacing}u&&(p+=e.footerMarginTop+u*c.lineHeight+(u-1)*e.footerSpacing);let x=0;const _=function(t){m=Math.max(m,i.measureText(t).width+x)};return i.save(),i.font=h.string,et(t.title,_),i.font=l.string,et(t.beforeBody.concat(t.afterBody),_),x=e.displayColors?a+2+e.boxPadding:0,et(s,(t=>{et(t.before,_),et(t.lines,_),et(t.after,_)})),x=0,i.font=c.string,et(t.footer,_),i.restore(),m+=g.width,{width:m,height:p}}function Vo(t,e,i,s){const{x:n,width:o}=i,{width:a,chartArea:{left:r,right:l}}=t;let h="center";return"center"===s?h=n<=(r+l)/2?"left":"right":n<=o/2?h="left":n>=a-o/2&&(h="right"),function(t,e,i,s){const{x:n,width:o}=s,a=i.caretSize+i.caretPadding;return"left"===t&&n+o+a>e.width||"right"===t&&n-o-a<0||void 0}(h,t,e,i)&&(h="center"),h}function No(t,e,i){const s=i.yAlign||e.yAlign||function(t,e){const{y:i,height:s}=e;return it.height-s/2?"bottom":"center"}(t,i);return{xAlign:i.xAlign||e.xAlign||Vo(t,e,i,s),yAlign:s}}function Wo(t,e,i,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,h=n+o,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=ci(a);let g=function(t,e){let{x:i,width:s}=t;return"right"===e?i-=s:"center"===e&&(i-=s/2),i}(e,r);const p=function(t,e,i){let{y:s,height:n}=t;return"top"===e?s+=i:s-="bottom"===e?n+i:n/2,s}(e,l,h);return"center"===l?"left"===r?g+=h:"right"===r&&(g-=h):"left"===r?g-=Math.max(c,u)+n:"right"===r&&(g+=Math.max(d,f)+n),{x:Qt(g,0,s.width-e.width),y:Qt(p,0,s.height-e.height)}}function Ho(t,e,i){const s=di(i.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-s.right:t.x+s.left}function jo(t){return Io([],zo(t))}function $o(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}class Yo extends Os{constructor(t){super(),this.opacity=0,this._active=[],this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.chart=t.chart||t._chart,this._chart=this.chart,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this._cachedAnimations;if(t)return t;const e=this.chart,i=this.options.setContext(this.getContext()),s=i.enabled&&e.options.animation&&i.animations,n=new ms(this.chart,s);return s._cacheable&&(this._cachedAnimations=Object.freeze(n)),n}getContext(){return this.$context||(this.$context=(t=this.chart.getContext(),e=this,i=this._tooltipItems,pi(t,{tooltip:e,tooltipItems:i,type:"tooltip"})));var t,e,i}getTitle(t,e){const{callbacks:i}=e,s=i.beforeTitle.apply(this,[t]),n=i.title.apply(this,[t]),o=i.afterTitle.apply(this,[t]);let a=[];return a=Io(a,zo(s)),a=Io(a,zo(n)),a=Io(a,zo(o)),a}getBeforeBody(t,e){return jo(e.callbacks.beforeBody.apply(this,[t]))}getBody(t,e){const{callbacks:i}=e,s=[];return et(t,(t=>{const e={before:[],lines:[],after:[]},n=$o(i,t);Io(e.before,zo(n.beforeLabel.call(this,t))),Io(e.lines,n.label.call(this,t)),Io(e.after,zo(n.afterLabel.call(this,t))),s.push(e)})),s}getAfterBody(t,e){return jo(e.callbacks.afterBody.apply(this,[t]))}getFooter(t,e){const{callbacks:i}=e,s=i.beforeFooter.apply(this,[t]),n=i.footer.apply(this,[t]),o=i.afterFooter.apply(this,[t]);let a=[];return a=Io(a,zo(s)),a=Io(a,zo(n)),a=Io(a,zo(o)),a}_createItems(t){const e=this._active,i=this.chart.data,s=[],n=[],o=[];let a,r,l=[];for(a=0,r=e.length;at.filter(e,s,n,i)))),t.itemSort&&(l=l.sort(((e,s)=>t.itemSort(e,s,i)))),et(l,(e=>{const i=$o(t.callbacks,e);s.push(i.labelColor.call(this,e)),n.push(i.labelPointStyle.call(this,e)),o.push(i.labelTextColor.call(this,e))})),this.labelColors=s,this.labelPointStyles=n,this.labelTextColors=o,this.dataPoints=l,l}update(t,e){const i=this.options.setContext(this.getContext()),s=this._active;let n,o=[];if(s.length){const t=Eo[i.position].call(this,s,this._eventPosition);o=this._createItems(i),this.title=this.getTitle(o,i),this.beforeBody=this.getBeforeBody(o,i),this.body=this.getBody(o,i),this.afterBody=this.getAfterBody(o,i),this.footer=this.getFooter(o,i);const e=this._size=Bo(this,i),a=Object.assign({},t,e),r=No(this.chart,i,a),l=Wo(i,a,r,this.chart);this.xAlign=r.xAlign,this.yAlign=r.yAlign,n={opacity:1,x:l.x,y:l.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==this.opacity&&(n={opacity:0});this._tooltipItems=o,this.$context=void 0,n&&this._resolveAnimations().update(this,n),t&&i.external&&i.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,i,s){const n=this.getCaretPosition(t,i,s);e.lineTo(n.x1,n.y1),e.lineTo(n.x2,n.y2),e.lineTo(n.x3,n.y3)}getCaretPosition(t,e,i){const{xAlign:s,yAlign:n}=this,{caretSize:o,cornerRadius:a}=i,{topLeft:r,topRight:l,bottomLeft:h,bottomRight:c}=ci(a),{x:d,y:u}=t,{width:f,height:g}=e;let p,m,b,x,_,y;return"center"===n?(_=u+g/2,"left"===s?(p=d,m=p-o,x=_+o,y=_-o):(p=d+f,m=p+o,x=_-o,y=_+o),b=p):(m="left"===s?d+Math.max(r,h)+o:"right"===s?d+f-Math.max(l,c)-o:this.caretX,"top"===n?(x=u,_=x-o,p=m-o,b=m+o):(x=u+g,_=x+o,p=m+o,b=m-o),y=x),{x1:p,x2:m,x3:b,y1:x,y2:_,y3:y}}drawTitle(t,e,i){const s=this.title,n=s.length;let o,a,r;if(n){const l=mi(i.rtl,this.x,this.width);for(t.x=Ho(this,i.titleAlign,i),e.textAlign=l.textAlign(i.titleAlign),e.textBaseline="middle",o=ui(i.titleFont),a=i.titleSpacing,e.fillStyle=i.titleColor,e.font=o.string,r=0;r0!==t))?(t.beginPath(),t.fillStyle=n.multiKeyBackground,Ce(t,{x:e,y:g,w:l,h:r,radius:a}),t.fill(),t.stroke(),t.fillStyle=o.backgroundColor,t.beginPath(),Ce(t,{x:i,y:g+1,w:l-2,h:r-2,radius:a}),t.fill()):(t.fillStyle=n.multiKeyBackground,t.fillRect(e,g,l,r),t.strokeRect(e,g,l,r),t.fillStyle=o.backgroundColor,t.fillRect(i,g+1,l-2,r-2))}t.fillStyle=this.labelTextColors[i]}drawBody(t,e,i){const{body:s}=this,{bodySpacing:n,bodyAlign:o,displayColors:a,boxHeight:r,boxWidth:l,boxPadding:h}=i,c=ui(i.bodyFont);let d=c.lineHeight,u=0;const f=mi(i.rtl,this.x,this.width),g=function(i){e.fillText(i,f.x(t.x+u),t.y+d/2),t.y+=d+n},p=f.textAlign(o);let m,b,x,_,y,v,w;for(e.textAlign=o,e.textBaseline="middle",e.font=c.string,t.x=Ho(this,p,i),e.fillStyle=i.bodyColor,et(this.beforeBody,g),u=a&&"right"!==p?"center"===o?l/2+h:l+2+h:0,_=0,v=s.length;_0&&e.stroke()}_updateAnimationTarget(t){const e=this.chart,i=this.$animations,s=i&&i.x,n=i&&i.y;if(s||n){const i=Eo[t.position].call(this,this._active,this._eventPosition);if(!i)return;const o=this._size=Bo(this,t),a=Object.assign({},i,this._size),r=No(e,t,a),l=Wo(t,a,r,e);s._to===l.x&&n._to===l.y||(this.xAlign=r.xAlign,this.yAlign=r.yAlign,this.width=o.width,this.height=o.height,this.caretX=i.x,this.caretY=i.y,this._resolveAnimations().update(this,l))}}_willRender(){return!!this.opacity}draw(t){const e=this.options.setContext(this.getContext());let i=this.opacity;if(!i)return;this._updateAnimationTarget(e);const s={width:this.width,height:this.height},n={x:this.x,y:this.y};i=Math.abs(i)<.001?0:i;const o=di(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=i,this.drawBackground(n,t,s,e),bi(t,e.textDirection),n.y+=o.top,this.drawTitle(n,t,e),this.drawBody(n,t,e),this.drawFooter(n,t,e),xi(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this._active,s=t.map((({datasetIndex:t,index:e})=>{const i=this.chart.getDatasetMeta(t);if(!i)throw new Error("Cannot find a dataset at index "+t);return{datasetIndex:t,element:i.data[e],index:e}})),n=!it(i,s),o=this._positionChanged(s,e);(n||o)&&(this._active=s,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,i=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;const s=this.options,n=this._active||[],o=this._getActiveElements(t,n,e,i),a=this._positionChanged(o,t),r=e||!it(o,n)||a;return r&&(this._active=o,(s.enabled||s.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),r}_getActiveElements(t,e,i,s){const n=this.options;if("mouseout"===t.type)return[];if(!s)return e;const o=this.chart.getElementsAtEventForMode(t,n.mode,n,i);return n.reverse&&o.reverse(),o}_positionChanged(t,e){const{caretX:i,caretY:s,options:n}=this,o=Eo[n.position].call(this,t,e);return!1!==o&&(i!==o.x||s!==o.y)}}Yo.positioners=Eo;var Uo={id:"tooltip",_element:Yo,positioners:Eo,afterInit(t,e,i){i&&(t.tooltip=new Yo({chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip;if(e&&e._willRender()){const i={tooltip:e};if(!1===t.notifyPlugins("beforeTooltipDraw",i))return;e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",i)}},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:{beforeTitle:$,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,s=i?i.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(s>0&&e.dataIndex"filter"!==t&&"itemSort"!==t&&"external"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]},Xo=Object.freeze({__proto__:null,Decimation:ho,Filler:Po,Legend:Oo,SubTitle:Ro,Title:To,Tooltip:Uo});function qo(t,e,i,s){const n=t.indexOf(e);if(-1===n)return((t,e,i,s)=>("string"==typeof e?(i=t.push(e)-1,s.unshift({index:i,label:e})):isNaN(e)&&(i=null),i))(t,e,i,s);return n!==t.lastIndexOf(e)?i:n}class Ko extends Ns{constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){const e=this._addedLabels;if(e.length){const t=this.getLabels();for(const{index:i,label:s}of e)t[i]===s&&t.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if(U(t))return null;const i=this.getLabels();return((t,e)=>null===t?null:Qt(Math.round(t),0,e))(e=isFinite(e)&&i[e]===t?e:qo(i,t,Z(e,t),this._addedLabels),i.length-1)}determineDataLimits(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let{min:i,max:s}=this.getMinMax(!0);"ticks"===this.options.bounds&&(t||(i=0),e||(s=this.getLabels().length-1)),this.min=i,this.max=s}buildTicks(){const t=this.min,e=this.max,i=this.options.offset,s=[];let n=this.getLabels();n=0===t&&e===n.length-1?n:n.slice(t,e+1),this._valueRange=Math.max(n.length-(i?0:1),1),this._startValue=this.min-(i?.5:0);for(let i=t;i<=e;i++)s.push({value:i});return s}getLabelForValue(t){const e=this.getLabels();return t>=0&&te.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}}function Go(t,e,{horizontal:i,minRotation:s}){const n=Yt(s),o=(i?Math.sin(n):Math.cos(n))||.001,a=.75*e*(""+t).length;return Math.min(e/o,a)}Ko.id="category",Ko.defaults={ticks:{callback:Ko.prototype.getLabelForValue}};class Zo extends Ns{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return U(t)||("number"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){const{beginAtZero:t}=this.options,{minDefined:e,maxDefined:i}=this.getUserBounds();let{min:s,max:n}=this;const o=t=>s=e?s:t,a=t=>n=i?n:t;if(t){const t=Bt(s),e=Bt(n);t<0&&e<0?a(0):t>0&&e>0&&o(0)}if(s===n){let e=1;(n>=Number.MAX_SAFE_INTEGER||s<=Number.MIN_SAFE_INTEGER)&&(e=Math.abs(.05*n)),a(n+e),t||o(s-e)}this.min=s,this.max=n}getTickLimit(){const t=this.options.ticks;let e,{maxTicksLimit:i,stepSize:s}=t;return s?(e=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,e>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`),e=1e3)):(e=this.computeTickLimit(),i=i||11),i&&(e=Math.min(i,e)),e}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let i=this.getTickLimit();i=Math.max(2,i);const s=function(t,e){const i=[],{bounds:s,step:n,min:o,max:a,precision:r,count:l,maxTicks:h,maxDigits:c,includeBounds:d}=t,u=n||1,f=h-1,{min:g,max:p}=e,m=!U(o),b=!U(a),x=!U(l),_=(p-g)/(c+1);let y,v,w,M,k=Vt((p-g)/f/u)*u;if(k<1e-14&&!m&&!b)return[{value:g},{value:p}];M=Math.ceil(p/k)-Math.floor(g/k),M>f&&(k=Vt(M*k/f/u)*u),U(r)||(y=Math.pow(10,r),k=Math.ceil(k*y)/y),"ticks"===s?(v=Math.floor(g/k)*k,w=Math.ceil(p/k)*k):(v=g,w=p),m&&b&&n&&jt((a-o)/n,k/1e3)?(M=Math.round(Math.min((a-o)/k,h)),k=(a-o)/M,v=o,w=a):x?(v=m?o:v,w=b?a:w,M=l-1,k=(w-v)/M):(M=(w-v)/k,M=Ht(M,Math.round(M),k/1e3)?Math.round(M):Math.ceil(M));const S=Math.max(Xt(k),Xt(v));y=Math.pow(10,U(r)?S:r),v=Math.round(v*y)/y,w=Math.round(w*y)/y;let P=0;for(m&&(d&&v!==o?(i.push({value:o}),v0?i:null;this._zero=!0}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=K(t)?Math.max(0,t):null,this.max=K(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let i=this.min,s=this.max;const n=e=>i=t?i:e,o=t=>s=e?s:t,a=(t,e)=>Math.pow(10,Math.floor(Ft(t))+e);i===s&&(i<=0?(n(1),o(10)):(n(a(i,-1)),o(a(s,1)))),i<=0&&n(a(s,-1)),s<=0&&o(a(i,1)),this._zero&&this.min!==this._suggestedMin&&i===a(this.min,0)&&n(a(i,-1)),this.min=i,this.max=s}buildTicks(){const t=this.options,e=function(t,e){const i=Math.floor(Ft(e.max)),s=Math.ceil(e.max/Math.pow(10,i)),n=[];let o=G(t.min,Math.pow(10,Math.floor(Ft(e.min)))),a=Math.floor(Ft(o)),r=Math.floor(o/Math.pow(10,a)),l=a<0?Math.pow(10,Math.abs(a)):1;do{n.push({value:o,major:Qo(o)}),++r,10===r&&(r=1,++a,l=a>=0?1:l),o=Math.round(r*Math.pow(10,a)*l)/l}while(an?{start:e-i,end:e}:{start:e,end:e+i}}function sa(t){const e={l:t.left+t._padding.left,r:t.right-t._padding.right,t:t.top+t._padding.top,b:t.bottom-t._padding.bottom},i=Object.assign({},e),s=[],n=[],o=t._pointLabels.length,a=t.options.pointLabels,r=a.centerPointLabels?Ot/o:0;for(let d=0;de.r&&(r=(s.end-e.r)/o,t.r=Math.max(t.r,e.r+r)),n.starte.b&&(l=(n.end-e.b)/a,t.b=Math.max(t.b,e.b+l))}function oa(t){return 0===t||180===t?"center":t<180?"left":"right"}function aa(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function ra(t,e,i){return 90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e),t}function la(t,e,i,s){const{ctx:n}=t;if(i)n.arc(t.xCenter,t.yCenter,e,0,At);else{let i=t.getPointPosition(0,e);n.moveTo(i.x,i.y);for(let o=1;o{const i=tt(this.options.pointLabels.callback,[t,e],this);return i||0===i?i:""})).filter(((t,e)=>this.chart.getDataVisibility(e)))}fit(){const t=this.options;t.display&&t.pointLabels.display?sa(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,i,s){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((i-s)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,i,s))}getIndexAngle(t){return Zt(t*(At/(this._pointLabels.length||1))+Yt(this.options.startAngle||0))}getDistanceFromCenterForValue(t){if(U(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if(U(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t=0;n--){const e=s.setContext(t.getPointLabelContext(n)),o=ui(e.font),{x:a,y:r,textAlign:l,left:h,top:c,right:d,bottom:u}=t._pointLabelItems[n],{backdropColor:f}=e;if(!U(f)){const t=ci(e.borderRadius),s=di(e.backdropPadding);i.fillStyle=f;const n=h-s.left,o=c-s.top,a=d-h+s.width,r=u-c+s.height;Object.values(t).some((t=>0!==t))?(i.beginPath(),Ce(i,{x:n,y:o,w:a,h:r,radius:t}),i.fill()):i.fillRect(n,o,a,r)}Pe(i,t._pointLabels[n],a,r+o.lineHeight/2,o,{color:e.color,textAlign:l,textBaseline:"middle"})}}(this,n),s.display&&this.ticks.forEach(((t,e)=>{if(0!==e){a=this.getDistanceFromCenterForValue(t.value);!function(t,e,i,s){const n=t.ctx,o=e.circular,{color:a,lineWidth:r}=e;!o&&!s||!a||!r||i<0||(n.save(),n.strokeStyle=a,n.lineWidth=r,n.setLineDash(e.borderDash),n.lineDashOffset=e.borderDashOffset,n.beginPath(),la(t,i,o,s),n.closePath(),n.stroke(),n.restore())}(this,s.setContext(this.getContext(e-1)),a,n)}})),i.display){for(t.save(),o=n-1;o>=0;o--){const s=i.setContext(this.getPointLabelContext(o)),{color:n,lineWidth:l}=s;l&&n&&(t.lineWidth=l,t.strokeStyle=n,t.setLineDash(s.borderDash),t.lineDashOffset=s.borderDashOffset,a=this.getDistanceFromCenterForValue(e.ticks.reverse?this.min:this.max),r=this.getPointPosition(o,a),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(r.x,r.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,i=e.ticks;if(!i.display)return;const s=this.getIndexAngle(0);let n,o;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(s),t.textAlign="center",t.textBaseline="middle",this.ticks.forEach(((s,a)=>{if(0===a&&!e.reverse)return;const r=i.setContext(this.getContext(a)),l=ui(r.font);if(n=this.getDistanceFromCenterForValue(this.ticks[a].value),r.showLabelBackdrop){t.font=l.string,o=t.measureText(s.label).width,t.fillStyle=r.backdropColor;const e=di(r.backdropPadding);t.fillRect(-o/2-e.left,-n-l.size/2-e.top,o+e.width,l.size+e.height)}Pe(t,s.label,0,-n,l,{color:r.color})})),t.restore()}drawTitle(){}}ha.id="radialLinear",ha.defaults={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:Ts.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:t=>t,padding:5,centerPointLabels:!1}},ha.defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"},ha.descriptors={angleLines:{_fallback:"grid"}};const ca={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},da=Object.keys(ca);function ua(t,e){return t-e}function fa(t,e){if(U(e))return null;const i=t._adapter,{parser:s,round:n,isoWeekday:o}=t._parseOpts;let a=e;return"function"==typeof s&&(a=s(a)),K(a)||(a="string"==typeof s?i.parse(a,s):i.parse(a)),null===a?null:(n&&(a="week"!==n||!Wt(o)&&!0!==o?i.startOf(a,n):i.startOf(a,"isoWeek",o)),+a)}function ga(t,e,i,s){const n=da.length;for(let o=da.indexOf(t);o=e?i[s]:i[n]]=!0}}else t[e]=!0}function ma(t,e,i){const s=[],n={},o=e.length;let a,r;for(a=0;a=0&&(e[l].major=!0);return e}(t,s,n,i):s}class ba extends Ns{constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit="day",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e){const i=t.time||(t.time={}),s=this._adapter=new xn._date(t.adapters.date);rt(i.displayFormats,s.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:fa(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this.options,e=this._adapter,i=t.time.unit||"day";let{min:s,max:n,minDefined:o,maxDefined:a}=this.getUserBounds();function r(t){o||isNaN(t.min)||(s=Math.min(s,t.min)),a||isNaN(t.max)||(n=Math.max(n,t.max))}o&&a||(r(this._getLabelBounds()),"ticks"===t.bounds&&"labels"===t.ticks.source||r(this.getMinMax(!1))),s=K(s)&&!isNaN(s)?s:+e.startOf(Date.now(),i),n=K(n)&&!isNaN(n)?n:+e.endOf(Date.now(),i)+1,this.min=Math.min(s,n-1),this.max=Math.max(s+1,n)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this.options,e=t.time,i=t.ticks,s="labels"===i.source?this.getLabelTimestamps():this._generate();"ticks"===t.bounds&&s.length&&(this.min=this._userMin||s[0],this.max=this._userMax||s[s.length-1]);const n=this.min,o=kt(s,n,this.max);return this._unit=e.unit||(i.autoSkip?ga(e.minUnit,this.min,this.max,this._getLabelCapacity(n)):function(t,e,i,s,n){for(let o=da.length-1;o>=da.indexOf(i);o--){const i=da[o];if(ca[i].common&&t._adapter.diff(n,s,i)>=e-1)return i}return da[i?da.indexOf(i):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=i.major.enabled&&"year"!==this._unit?function(t){for(let e=da.indexOf(t)+1,i=da.length;e+t.value)))}initOffsets(t){let e,i,s=0,n=0;this.options.offset&&t.length&&(e=this.getDecimalForValue(t[0]),s=1===t.length?1-e:(this.getDecimalForValue(t[1])-e)/2,i=this.getDecimalForValue(t[t.length-1]),n=1===t.length?i:(i-this.getDecimalForValue(t[t.length-2]))/2);const o=t.length<3?.5:.25;s=Qt(s,0,o),n=Qt(n,0,o),this._offsets={start:s,end:n,factor:1/(s+1+n)}}_generate(){const t=this._adapter,e=this.min,i=this.max,s=this.options,n=s.time,o=n.unit||ga(n.minUnit,e,i,this._getLabelCapacity(e)),a=Z(n.stepSize,1),r="week"===o&&n.isoWeekday,l=Wt(r)||!0===r,h={};let c,d,u=e;if(l&&(u=+t.startOf(u,"isoWeek",r)),u=+t.startOf(u,l?"day":o),t.diff(i,e,o)>1e5*a)throw new Error(e+" and "+i+" are too far apart with stepSize of "+a+" "+o);const f="data"===s.ticks.source&&this.getDataTimestamps();for(c=u,d=0;ct-e)).map((t=>+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}_tickFormatFunction(t,e,i,s){const n=this.options,o=n.time.displayFormats,a=this._unit,r=this._majorUnit,l=a&&o[a],h=r&&o[r],c=i[e],d=r&&h&&c&&c.major,u=this._adapter.format(t,s||(d?h:l)),f=n.ticks.callback;return f?tt(f,[u,e,i],this):u}generateTickLabels(t){let e,i,s;for(e=0,i=t.length;e0?a:1}getDataTimestamps(){let t,e,i=this._cache.data||[];if(i.length)return i;const s=this.getMatchingVisibleMetas();if(this._normalized&&s.length)return this._cache.data=s[0].controller.getAllParsedValues(this);for(t=0,e=s.length;t=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=wt(t,"pos",e)),({pos:s,time:o}=t[r]),({pos:n,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=wt(t,"time",e)),({time:s,pos:o}=t[r]),({time:n,pos:a}=t[l]));const h=n-s;return h?o+(a-o)*(e-s)/h:o}ba.id="time",ba.defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",major:{enabled:!1}}};class _a extends ba{constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=xa(e,this.min),this._tableRange=xa(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:i}=this,s=[],n=[];let o,a,r,l,h;for(o=0,a=t.length;o=e&&l<=i&&s.push(l);if(s.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(o=0,a=s.length;o=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), -a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), -null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" - \ No newline at end of file diff --git a/v1/inc/entry_ajax.php b/v1/inc/entry_ajax.php deleted file mode 100644 index 9e42db1..0000000 --- a/v1/inc/entry_ajax.php +++ /dev/null @@ -1,51 +0,0 @@ -request)){ - $request = $postData->request; -} - -// Get Test -if($request == 'getTest'){ - $result = array();$data = array(); - - if(isset($postData->control)){ - $control = $postData->control; - $sql = "select dt.id, dt.name from CONTROL_TEST ct left join DICT_TEST dt on dt.id=ct.testid where ct.controlid='$control'"; - $stmt = sqlsrv_query( $conn1, $sql ); - if( $stmt == false) { die( print_r( sqlsrv_errors(), true) ); } - while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC ) ) { - $id = $row[0]; - $name = $row[1]; - $data[] = array( "id" => $id, "name" => $name ); - } - } - - echo json_encode($data); - die; -} - -// Get Control -elseif($request == 'getControl'){ - $result = array();$data = array(); - - if(isset($postData->dates)){ - $dates = $postData->dates; - $dept = $postData->dept; - $sql = "select id, name, lot from DICT_CONTROL where expdate > '$dates' and deptID='$dept'"; - $stmt = sqlsrv_query( $conn1, $sql ); - if( $stmt == false) { die( print_r( sqlsrv_errors(), true) ); } - while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC ) ) { - $id = $row[0]; - $name = $row[1]; - $lot = $row[2]; - $data[] = array( "id" => $id, "name" => "$name - $lot" ); - } - } - - echo json_encode($data); - die; -} \ No newline at end of file diff --git a/v1/inc/entry_daily.php b/v1/inc/entry_daily.php deleted file mode 100644 index 8df7026..0000000 --- a/v1/inc/entry_daily.php +++ /dev/null @@ -1,74 +0,0 @@ - '$date' "; -$stmt = sqlsrv_query( $conn1, $sql ); -if( $stmt == false) { die( print_r( sqlsrv_errors(), true) ); } -?> -
- - - - - - - - - - - -
Dept. : - -
Date :
Control :
-
- - \ No newline at end of file diff --git a/v1/inc/entry_daily_1.php b/v1/inc/entry_daily_1.php deleted file mode 100644 index 6387539..0000000 --- a/v1/inc/entry_daily_1.php +++ /dev/null @@ -1,85 +0,0 @@ - - - - - QC APP - - - - -
-
-

Tanggal

- - - - - - - "; - } - ?> - -
Test Value Mean (SD) $tname$tmean ($tsd)
-
- - - -
-
- - - $value) { - if($value != '') { - $sql = "if exists (select * from DAILY_RESULT where controlid='$controlid' and testid='$testid' and resdate='$date 00:00') - update DAILY_RESULT set resvalue='$value' where controlid='$controlid' and testid='$testid' and resdate='$date 00:00' - else - insert into DAILY_RESULT(controlid, testid, resvalue, resdate) values ('$controlid', '$testid', '$value', '$date 00:00')"; - } else { - $sql = "if exists (select * from DAILY_RESULT where controlid='$controlid' and testid='$testid' and resdate='$date 00:00') - delete from DAILY_RESULT where controlid='$controlid' and testid='$testid' and resdate='$date 00:00'"; - } - //echo "
$sql

"; - $stmt = sqlsrv_query( $conn1, $sql ); - if( $stmt == false) { die( print_r( sqlsrv_errors(), true) ); } - } - echo "Data updated..."; -} -?> \ No newline at end of file diff --git a/v1/inc/entry_monthly.php b/v1/inc/entry_monthly.php deleted file mode 100644 index 6ed4c49..0000000 --- a/v1/inc/entry_monthly.php +++ /dev/null @@ -1,192 +0,0 @@ - - - - - QC APP - - - - -
-
- Periode
- - - - - -
Mean
SD
Range -
-
-
- - - "; - if(isset($data[$i])) { echo ""; } - else { echo ""; } - if(isset($comment[$i])) { echo ""; } - else { echo ""; } - } - ?> - - -
Day Result Comment
$i
Comment:
- - - -
-
-
- - -0) {$rdata[$i]=$data1;} - $i++; -} -$data = $rdata; -$hari = date("t",strtotime("$date-1")); -$sql = "SELECT id,resdate FROM DAILY_RESULT WHERE convert(varchar(7),resdate,126) ='$date' and controlid='$control' and testid='$testid'"; -//echo $sql; -$stmt = sqlsrv_query( $conn1, $sql); -while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC ) ) { - $id = $row[0]; - $cday = date_format($row[1],"j"); - $resid[$cday] = $id; -} -///* -for($i=1;$i<=$hari;$i++) { - if( isset($data[$i]) ) { - if( isset($resid[$i]) ) { $dataUpdate[$resid[$i]] = $data[$i]; $commentUpdate[$resid[$i]]= $comment[$i]; } // data update - else { $dataInsert[$i] = $data[$i]; } // data insert - } - elseif( isset($resid[$i]) ) { $dataDelete[] = $resid[$i]; } // data delete -} - -//INSERT -if(isset($dataInsert)) { - $sql = "INSERT INTO DAILY_RESULT (controlid, testid, resdate, resvalue, rescomment ) VALUES "; - foreach($dataInsert as $day => $data1) { - if($day < 10) { $day="0$day"; } - $sql.= "('$control', '$testid', '$date-$day', '$data1','$comment[$day]'),"; - } - $sql = substr($sql,0,-1); - $stmt = sqlsrv_query( $conn1, $sql); - if( $stmt === false ) { die( print_r( sqlsrv_errors(), true)); } - echo "inserting new control result done...
"; -} - -//UPDATE -if(isset($dataUpdate)) { - foreach($dataUpdate as $drid => $data1) { - $sql = "update DAILY_RESULT set resvalue='$data1', rescomment='$commentUpdate[$drid]' where id='$drid'"; - $stmt = sqlsrv_query( $conn1, $sql); - if( $stmt === false ) { die( print_r( sqlsrv_errors(), true)); } - //echo "update $drid
"; - } - echo "updating control result done...
"; -} - -//DELETE -if(isset($dataDelete)) { - foreach($dataDelete as $drid ) { - $sql = "delete from DAILY_RESULT where id='$drid'"; - $stmt = sqlsrv_query( $conn1, $sql); - if( $stmt === false ) { die( print_r( sqlsrv_errors(), true)); } - //echo "delete $drid $sql
"; - } - echo "deleting control result done...
"; -} - -$comtext = $_POST['monthlycomment']; -if( $comtext != '' ) { - $sql = "if exists (select * from MONTHLY_COMMENT with (updlock,serializable) where commonth='$date' and controlid='$control' and testid='$testid') - begin - update MONTHLY_COMMENT set comtext='$comtext' - where commonth='$date' and controlid='$control' and testid='$testid' - end - else - begin - insert into MONTHLY_COMMENT (controlid, testid, commonth, comtext ) - values ('$control', '$testid', '$date', '$comtext') - end"; - echo $sql; - $stmt = sqlsrv_query( $conn1, $sql); - if( $stmt === false ) { die( print_r( sqlsrv_errors(), true)); } - echo "updating comment done
"; -} else { - $sql = "delete from MONTHLY_COMMENT where commonth='$date' and controlid='$control' and testid='$testid'"; - $stmt = sqlsrv_query( $conn1, $sql); - if( $stmt === false ) { die( print_r( sqlsrv_errors(), true)); } - echo "deleting comment done
"; -} - -//echo "
redirecting ...."; -echo "
redirecting ...."; -//*/ -} -?> \ No newline at end of file diff --git a/v1/inc/qc.php b/v1/inc/qc.php deleted file mode 100644 index 3a2c079..0000000 --- a/v1/inc/qc.php +++ /dev/null @@ -1,326 +0,0 @@ -1) { - // meanMVA = total/n - $meanMVA[$ccode] = round($total/$n[$ccode],3); - // CV = sqrt ( ( E(x^2) - (total^2 / n) ) / n - 1 ) - $cv[$ccode] = round(sqrt(($total2 - ($total*$total)/$n[$ccode]) / ($n[$ccode] - 1)),3); - // %CV = CV / (total/n) - $pcv[$ccode] = round( $cv[$ccode] * 100 / $n[$ccode] ,3); -} else { - // meanMVA = total/n - $meanMVA[$ccode] = 0; - // CV = sqrt ( ( E(x^2) - (total^2 / n) ) / n - 1 ) - $cv[$ccode] = 0; - // %CV = CV / (total/n) - $pcv[$ccode] = 0; -} -} -?> - - -
- "; }?> -
- -
- Periode :
- Test :
- - $ccode"; ?> - $mean1"; ?> - $sd1"; ?> - $min[$ccode] - $max[$ccode]"; ?> - - ".$meanMVA[$ccode].""; ?> - ".$cv[$ccode].""; ?> - ".$pcv[$ccode].""; ?> -
QC Code
Mean
1SD
Range
Mean MVA
SD
%CV
-
-
- - $ccode"; ?> - "; - foreach($qccode as $ccode){ - if(isset($val[$ccode][$i][$j])) echo ""; - else echo ""; - } - $k++; - echo ""; - } - } - ?> -
No Datetime
$k $i - $monthName".$val[$ccode][$i][$j]."
-
-
- - "; - foreach($qccode as $ccode){ - if(isset($val[$ccode][$i][$j])) echo ""; - else echo ""; - } - $k++; - echo ""; - } - } - ?> -
$k $i - $monthName".$val[$ccode][$i][$j]."
-
- -
- diff --git a/v1/inc/report.php b/v1/inc/report.php deleted file mode 100644 index 2315ebc..0000000 --- a/v1/inc/report.php +++ /dev/null @@ -1,74 +0,0 @@ -"; - $data['control'] = $control; - $data['lot'] = $lot; - $stmt = sqlsrv_query( $conn1, $sql ); - if( $stmt == false) { die( print_r( sqlsrv_errors(), true) ); } - while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC ) ) { - $day = date_format($row[0],"j"); - $data['result'] [$day] = $row[1]; - if(is_numeric($row[1])) { - $data['resultx'] [$day] = ( $row[1] - $data['mean'] ) / $data['sd']; - } else { $data['resultx'] [$day] = 0; } - } - - // mean and sd - $data['+2s'] = $data['mean'] + (2*$data['sd']); - $data['-2s'] = $data['mean'] - (2*$data['sd']); - $data['cv'] = number_format($data['sd'] / $data['mean'] * 100,3); - - // sample mean and sd - $num_of_elements = count($data['result']); - $variance = 0.0; - $data['means'] = array_sum($data['result'])/$num_of_elements; - foreach($data['result'] as $i) { - if(is_numeric($i)) { $variance += pow(($i - $data['mean']), 2); } - } - $data['sds'] = (float)sqrt($variance/$num_of_elements); - - $data['means'] = number_format($data['means'],3); - $data['sds'] = number_format($data['sds'],3); - - if($data['means'] != 0) { - $data['cvs'] = number_format($data['sds'] / $data['means'] * 100,3); - }else { $data['cvs'] = 0; } - - $data['bias'] = abs($data['mean']- $data['means']); - $data['bias'] = number_format($data['bias'] / $data['mean'] * 100,3); - - $data['te'] = $data['bias'] + ( 2 * $data['cvs'] ); - - ksort($data['result']); ksort($data['resultx']); - return $data; - } - - $control1 = $_POST['control1']; - if(isset($_POST['control2'])) { $control2 = $_POST['control2']; } - else { $control2 = 0; } - if(isset($_POST['control3'])) { $control3 = $_POST['control3']; } - else { $control3 = 0; } - $dates = $_POST['dates']; - $lastday = date("t", strtotime($dates)); - $testid = $_POST['test']; - - if( $control3 != 0) { require("report_3c.php"); } - else if( $control2 != 0) { require("report_2c.php"); } - else { require("report_1c.php"); } - \ No newline at end of file diff --git a/v1/inc/report_1c.php b/v1/inc/report_1c.php deleted file mode 100644 index a5a452b..0000000 --- a/v1/inc/report_1c.php +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - -
-
-

QC Internal

-

Kimia Klinik

-
TRISENSA DIAGNOSTIC CENTRE
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
INSTITUTION Laboratorium GleneaglesInstrument TMS 50i
TEST NAME Control Name
REAGENT Lot No.
METHOD VALUES -2S Target +2S
UNIT
PERIODE
-
- -
- - - - - $res) { - if( is_numeric($res) ) { $res = number_format($res,3); } - echo ""; - } - ?> -
Tanggal Hasil
$day $res
-
- -
- -
- - -
- - - \ No newline at end of file diff --git a/v1/inc/report_2c.php b/v1/inc/report_2c.php deleted file mode 100644 index a6699a3..0000000 --- a/v1/inc/report_2c.php +++ /dev/null @@ -1,190 +0,0 @@ - - - $length) { $length = $length_2; } - // repair jumping control - $key1 = array_keys($data1['resultx']); - $key2 = array_keys($data2['resultx']); - $keys = array_merge($key1,$key2); - $keys = array_unique($keys); - asort($keys); - /* - echo "
"; 
-	print_r($data1['resultx']);
-	print_r($data2['resultx']);
-	print_r($keys);
-	echo "
"; - */ - ?> - - - - - - - - -
-
-

QC Internal

-

Kimia Klinik

-
TRISENSA DIAGNOSTIC CENTRE
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
INSTITUTION Laboratorium GleneaglesInstrument TMS 50i
TEST NAME Control C 1 : / C 2 :
REAGENT Lot No. Lot 1 : / Lot 2 :
METHOD VALUES -2S TARGET +2S
UNIT VALUES
PERIODE
-
- -
- - - - - "; } - } - ?> -
Tanggal Hasil 1 Hasil 2
$i $res1 $res2
-
- -
- -
- - -
- - - \ No newline at end of file diff --git a/v1/inc/report_3c.php b/v1/inc/report_3c.php deleted file mode 100644 index d285584..0000000 --- a/v1/inc/report_3c.php +++ /dev/null @@ -1,204 +0,0 @@ - - - $length) { $length = $length_2; } - if($length_3 > $length) { $length = $length_3; } - // repair jumping control - $key1 = array_keys($data1['resultx']); - $key2 = array_keys($data2['resultx']); - $key3 = array_keys($data3['resultx']); - $keys = array_merge($key1,$key2,$key3); - $keys = array_unique($keys); - asort($keys); - /* - echo "
"; 
-	print_r($data1['resultx']);
-	print_r($data2['resultx']);
-	print_r($keys);
-	echo "
"; - */ - ?> - - - - - - - - -
-
-

QC Internal

-

Kimia Klinik

-
TRISENSA DIAGNOSTIC CENTRE
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
INSTITUTION Laboratorium GleneaglesInstrument TMS 50i
TEST NAME Control C 1 : / C 2 : / C 3 :
REAGENT Lot No. Lot 1 : / Lot 2 : / Lot 3 :
METHOD VALUES -2S TARGET +2S
UNIT VALUES
PERIODE
-
- -
- - - - - "; } - } - ?> -
Tanggal Hasil 1 Hasil 2 Hasil 3
$i $res1 $res2 $res3
-
- -
- -
- - -
- - - \ No newline at end of file diff --git a/v1/inc/test_add.php.bak b/v1/inc/test_add.php.bak deleted file mode 100644 index b4cb69b..0000000 --- a/v1/inc/test_add.php.bak +++ /dev/null @@ -1,32 +0,0 @@ - -
-Test Name
-
-Unit
-
-Method
-
-CVA
-
-BA
-
-TEA
-
- -
-"; -} -?> \ No newline at end of file diff --git a/v1/inc/test_del.php b/v1/inc/test_del.php deleted file mode 100644 index eefc6fd..0000000 --- a/v1/inc/test_del.php +++ /dev/null @@ -1,7 +0,0 @@ -"; -?> \ No newline at end of file diff --git a/v1/inc/test_edit.php b/v1/inc/test_edit.php deleted file mode 100644 index daa7f2f..0000000 --- a/v1/inc/test_edit.php +++ /dev/null @@ -1,72 +0,0 @@ - -
-Dept.
- -
-Name
-
-Unit
-
-Method
-
-CVA
-
-BA
-
-TEA
-
-
- -
-"; -} -?> \ No newline at end of file diff --git a/v1/inc/test_index.php b/v1/inc/test_index.php deleted file mode 100644 index 9f17945..0000000 --- a/v1/inc/test_index.php +++ /dev/null @@ -1,28 +0,0 @@ -

Test

-New Test
- - - - "; - $i++; -} -?> -
ID Dept. Name Method Unit BA CVA TEA
$i $dname $tname $method $unit $ba $cva $teaedit - - del -
\ No newline at end of file diff --git a/v1/inc/view.php b/v1/inc/view.php deleted file mode 100644 index 9b0c3b0..0000000 --- a/v1/inc/view.php +++ /dev/null @@ -1,113 +0,0 @@ - -
- - - - - - -
Date :
Test :
Control 1 :
Control 2 :
-
- - \ No newline at end of file diff --git a/v1/inc/view_ajax.php b/v1/inc/view_ajax.php deleted file mode 100644 index 71108c8..0000000 --- a/v1/inc/view_ajax.php +++ /dev/null @@ -1,55 +0,0 @@ -request)){ - $request = $postData->request; -} - -// Get Test -if($request == 'getTest'){ - $dates = 0; - $result = array();$data = array(); - - if(isset($postData->dates)){ - $dates = $postData->dates; - $sql = "select distinct testid, dt.name from DAILY_RESULT dr left join DICT_TEST dt on dt.id=dr.testid where convert(varchar(7), resdate, 126)='$dates'"; - $stmt = sqlsrv_query( $conn1, $sql ); - if( $stmt == false) { die( print_r( sqlsrv_errors(), true) ); } - while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC ) ) { - $id = $row[0]; - $name = $row[1]; - $data[] = array( "id" => $id, "name" => $name ); - } - } - - echo json_encode($data); - die; -} - -// Get control -if($request == 'getControl'){ - $test = 0; - $result = array();$data = array(); - - if(isset($postData->test)){ - $test = $postData->test; - $dates = $postData->dates; - - $sql = "select distinct dr.controlid, dc.name, dc.lot from DAILY_RESULT dr - left join DICT_CONTROL dc on dc.id=dr.controlid - where convert(varchar(7), dr.resdate, 126)='$dates' and dr.testid='$test'"; - $stmt = sqlsrv_query( $conn1, $sql ); - if( $stmt == false) { die( print_r( sqlsrv_errors(), true) ); } - while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC ) ) { - $id = "$row[0]|$row[2]"; - $name = "$row[1] - $row[2]"; - $data[] = array( "id" => $id, "name" => $name ); - } - } - - echo json_encode($data); - die; -} \ No newline at end of file diff --git a/v1/index.php b/v1/index.php deleted file mode 100644 index 39fec57..0000000 --- a/v1/index.php +++ /dev/null @@ -1,57 +0,0 @@ - - - - -QC APP - - - - - - - \ No newline at end of file diff --git a/v1/qc20260114.bak b/v1/qc20260114.bak deleted file mode 100644 index 04c5f375cef675c33d0a93296d247b401ba0ebee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8625664 zcmeEP2Y^+@)t>wIZLjQ7ZM!rP5m=OtxNli{SBj`8OA}E9q*xH;iM<;&YAgx%5@U=p zi6$l?rWs8!-Q-WvXo4DBG$zCt`Oi0J&b@QX+g%sTs+oa%&)jd$IWzN3xpT|AJGXK6 z1f}xSWvaqcZ3roKVSZ}nZ{Ex&T^M*|Ylnl>aZ06Cb?rS1KhfEnp;oG;YMol6*3)*p z+Mw#x9Cf&wuH|w{IaOiL;fTg5;}NUlL%ko9f5-RM6<+q!^;54t?5gabY4h&+oKkOi zlrM7UGR&FXsO|Q*iZZmDPIf!TfMcKq2IfqhF^-b6D%G~}uT<5ABaFYvE%3=6xz>F z6}0KG-lRsWNwlz=pk~s33N7>eF?xkHMsIdwG$7W+90MK9z>GOf7|3)U57vJe-*&K% zQ)=|yNSkpu+f|fVnw`nn%=R^mo8jf{*D^gbX)zkKl|y<%RZZ>^eWomfefG6`zBliipC5O3*B6hu`Gsd{VO>O9FG~9(IqD0g z_YtzBo2v`~SEOX>o#a}Rkd#1Jc#RdFp65)QH03qYk^C#vvzm*jD}S{|33i!mZf)GQ zw|R-`*!J(IZL*YslsVdNcHXnq5p)`wp&CgZrRGeWGV>v-%6Xzv$1T58_dxxX293UMiu;HaKSxasc7H3XW82OPW$d%(;hu` z=1paX&ws2X9^o*Wt`v_Mq|K|jq3izV{;s7i12q>M10OpECPZdKELa!P7{%Sm6|`SW z*Q0fG6}pnHL6_52=0ch~+III6nsdy3%^_;28e|>Mp#|{~YQEmvdJE|)w^7ZdZDFKb zgQy(K=w2yitjB5o@lUXIdXm!ZLX%Z+p#H7Lb61+N?ooTSHe(sf6746t!@NqtpRw38 zgKgjcr~7RSzI}7y`1>C}`?W)kxaN-NjD%x3E5mCvz3n+UO~=5;mx1VvwTNaW%vB%O znM=wyh{~yFF!Nl-UH^Z4`>3ngN1K5ebH+EK28UYL|K=9HUokpeTj8)8KJZkd9^YAY zou$y#-QTmga#6>?hl7C`hhvB|YboE}}1C^c#Cnyx@`d4V;0 zBSjFG@Dp{}l@iY->*@X&!f;U-rY@&{SE^5_PpVI;Thy)Uv+7IgoAmG7>ig;`^%M0Q z^|sojioF`Iw>Qum>ot1Q=-*M^%Fw?vJp4P?yWG3i`=a-4?~mRNuOW?pjp=FWS?M|H zBh%4ag8HQqxZv3nN1%Zy6Rst?u z%rOwYII{V0s};k>GMZLaP~20?Qj_j}@Z$5v-!|}^K?9a{zAB*0O)CKxF6J0;(@N;o ztfbWnZcg#*Gtrl4g6`v{m4FKua}4C3R_KPXrsseDmhEvgt(>55*&g+?ap`lGuNrsl z!QUM;`q7c@-ijMPj)5EuxO*$D+*@g;Y2|!9tCE@+toyXN3M9#0MBg)<&FX@l$;l90QI4$ADwNG2j?* z3^)cH1C9a5fMdWh;23ZWI0hU8jseGjW56-s7;p?Y1{?#90mp!2z%lT@zyLop|AwOH z|M;_{1*9jseGjW56-s7;p?Y z1{?#90mp!2z%k$$a11yG90QI4$ADwNG2j?*3^)cH1C9a5fMdWh@V~%-e*W*J@%w-C zSRWq)Kv<$mX#b0{Gpmb8BC(dX15JFn(SH5s7oAH`i(wxnKG{!Ny-{zVuG{i2z?TOI z^3;*)1hs+wtyQDdVET8O{x^vBhp0hnjasKx5PGnxr+-5zwm{8L)72b$PvHc$T%D{I z6V5qR@A}M*^q~TF+m{knt25MG+SZbyD4n=`!I!AwtTeWvj;qE@TD*vZQ`-B4B@Brnq$1=c?qTc56w ziMr8nQ1(L>C7lENBw z5-A7W=9<4RK6@`w=ttgAi51kx7Sldx_&=ZeO!3~LRvW9tCpJ7YY9C4NP039$mGAUX zYF|;=n`$@SuiN9dU3VIn)vo--kMS; zDt$>|1|`o@)5uRi;`#F)ncg!{!l=g>K}Fa3p57c*_hv6q8l#zBt!5K(>xpTMx>HGg zN}_4WOBL7l7Smy*0^dATa~rMr=S}6rjdX8JBlcvp;k3O}UrF9q_t{{MS^uxS$L=qQ zJ*k8z=zb9>EZ=loSwB&zr4D_DuCcIo$*{$@A0Ww6*O_f9_8b2^dRu=n9ZVf&wI*nV zuJtmS(!L4-dZS~SQe%Co|L5~{;i%LJ;^|+r-p?IM7&%)s^ZF?IH;m~#9149yPde&izY< zi9w?=Xwr-zk9Aa(S(KZcM%Pmdg>yXjs>_!Se?JbUQxjl0Aw_<(epA^9aZsz<3;9a& z-|IKMGE$OzQs!6z*$V&p>zN0Q5{16ha!8CT-F?t#QR+utlGQeB{#3;nQNw9}IWZm- zb=~Gqy>_T1qbyN{H4p9m*Ri6|-(<2x&qgR!a0Xqo>6u#&6UE-tKA2>~D$lQf|G3NCNqSjZJ z66=Jp(%&EMPA5DwKkln}3p~8C_NaykP2P$&Q$|vN+RlwmHHBOB6(P9@xS7<8_H*i zTCKmt5ifr_rTbyCB^l>XnSw;&&u1(sJ6sfS4&_CmBsV>I)=@`Da(}YNWNXh%qWH;+ zPZ=;r6bDifS5ZY}`id?KE4uGhKUb9d>!v!LPO9K(1=THBXTS4*nSJMpA{KCK$TNBe z7Aed8PI&6|XWu$s)JB<7wlp0|spnsJ;i4nOaI9sxit^yK4Z6jA-E3GQ;Yf@(UH6U4 z7l^TNGlx{xQ622!Ejjh{LyrtsVrpSc+y@|9@}ZdWbp>DZ#Xa8fhI$c`#j}1Irp1avO(-=%b z(O4?aAZvrhQW}D*$O;#g%hgzFyX6$eg#`K#G}h8FE?Y5!;@SZ#NV$p_ODB1p=!dFd zRH>!3jU@lrmeRjbv=CqqSeM}Bzn=b~@#Rd01vR&WsTyvurS1&8yI}Of5GKT z#b5%p!A5F#zJY>MBPM4)i8q-=3Knx{JM=EP@AND6@=YWaU2E>#wacSxuJzPW)>HBt zy7R+58yyV2Tv7KpP~mEFPF>G*THy|edI38L---E~X#Bw&x+rH0Ke)POKe$N}_Va_B zey~8s33!=b9;~$4kNz@ds5~#{^m96qggUO(eoz1x90QI4$ADwNG2j?*3^)cH1CD_Y zGXsOugVPtK#^#;iO(`xao?Y=u$y=p6y;I8Tyo&Tb`9~FgyX2qgv6Vy0@ArOP^lJW> zD>kODFWakZRoVB;uP^v(+3Uqm7T;KYZ)#QLCo6xQ_fzkU@(1&-%&SdxE%`<17xJsi zf0jBdbxCnW!4c*66wOZ`oBDCt)A?U1y&-+E*W}$^*g3B;|LW3JdB3h0R&sCg{E}a! zpDg@aYFgQM3VN45)9IwrK83HVfd#7a?SgI}&UYZ{9aQKkn|XFCKIA3(wT5oj*r2heDQ) za3cx{mo8jf{*D^gbX)zkKl|y<%RXzT-Q_)c{?vx6XMOUfDaRi_>$&e;p{^bG+|YN% z-LmcZlJ^cAI}wk@sYit>)0N7-mXJK$-1-1RFY^6IssNsa-dc91x0d=>G~9XotLn1* zlzO^Q;nf4R0~&Xv@%sXVVfUR{r8riRYGW|Ng&}0zV&= zcy7O(G7>-Vb-^*<7;p?Y1{?#90mp!2z%k$$a11yG90QI4$ADwNG2j?*3^)cH1C9a5 zfMdWh;23ZWI0hU8|HBOE@BgRh_t*aS|M5j}gk}0U|L?jiEH0%ZJd4L~xSMH{Hv}lE zc67ZOABSx*6u?+-^n-8uY$XMJBR_!g^KT6!rvS#+)HIA=WCt*8HH_b-2Qa>ACFdzL z7?sm7K1Ub8sGNrP3c;wHhVc=+KpU0QFg~Roz^I&t@%i)s?kq4qogToboYuzs6akFN zX}B%~qjDPV8G=zc4KEA9sGNqEhhS7r!^ekUR8GSyLNF?);S)kIDyQLdDZZ-Li@;64Jc4Z-*xfp&6A2;N`dbs-qvV%OUE z3}Vna2MD|&1oszsV+cM_;8R2J0D(^n!FT~kXL))E9w_h`A$X9$PlVvX0{CR}f|5)U?QtP^vcTg*@Dzb3gy5+H zPYl7+1fCRvrwcqe1mlAOy3wYD;F$uSAh7Ppvj}daO{GKdY=KcjT}!QvPcCTfe1Ubh zKSJP@A$X3!Cx&1YPCGd%1kV$ARS2Fh@W~8bq2ZZl5roZ$^*4-k>r4&7{waD|2*#(Ewf6K7jQ12Z zJR<}z7IY*Tui%=3FUx;B z{fG4T(+{RUm98uJTG7vn{x5%X!5u}H7oC)zn;x6qKV6yLnfF}YlX+jvyE*Utyw!O} z=4JBw=T+zZJM}{9N2xETK9jmAbxP{!R8#7pRF~9y-VX0+?@{kI?^17rcdR$j8|-!W zJnv=obM=_IQ(ZxS6RlbQ{vVGUIN;trLP{0UKCO1v;vTwvE8C7kv-N=c>TL_2sw2hs zn}hoTK-<`LT8;t7fMdWh;23ZWI0hU8jseGjW56-s7;p?Y1{?#90mp!2z%k$$a11yG z90QI4$ADwNG4OF^V7qz#AN>A5c>a&4@c8~ee$S3L-UGnT(($Wu3E#W&FZgkME8+b- z|7TbDd2n0b0&q|NTcO`2I|dvBjseGjW56-s7;p?Y1{?#90mp!2z%k$$a11yG90QI4 z$ADwNG2j?*3^)cH1C9a5z{j2e{r!KBKES`#Q}|f5r|@-egfR-=5dUP^H8uEfJ)Xs{ zrR^E|P{1!qN*Ma3Z{q9aErxpXx!~@n=#%4kRp9m4X@}1Z6p>SW{5bgZ03F~3gRG~f zs8iKqwMwm|KSQusZ6LWutyX~}yoxXqAMQ@85?JZ-Q7x>%j%JbBa&&V#( zbuuBV2?^Zc4TmG*=k;}jx2-~uSc17l039yH+DFlH_Hz!u6MQRDT+dySp zOne6}E6McEJ88FT7druK8GOs$5A5<7?O-*TuTy7GrBT`S^bZwZPRC1#$z_xR*H6Cw zMf$Qk3RhoGJ8ljJ!tY+N>qc_3fgEj68z~kzKvCM{U; zXN2inq?YPle5x)gT15KwBC5tZO4~^METU>Hvnm1_+T{M27TljenXM+bt0?QB4Adq^$HW|QkJv!Y7n5sDQeoG7V8Y}vWIUOKMQD>x7zcZF$b#}3*R5&gJuLn|O21X<)t#c-{#j@C_!X+gHgT+U(Lj-?_n zUWsz0FLaOMrQcP?7SQu_wCHFn%_`dROz z|4$&!7E{yUax>_<>;%2PO|2WAZ=>e|cGl*}yR~xxyKD3G9WGn+T)@uSJdsb*v&3@h zW5LXeW^utW;23ZWI0hU8jseGjW56-s82DH-Fui71^@G(*tM{uuziM>V-zx8^Twb|f z<#U~WUvYXxkBT3cpIe?Of2-_{vLnmR>-28vy`@K&mXodO^T|AuT0@yWGmtQ{Qkc$`LZ%-#WRxK z@BiCCl2dUEI0hU8jseGjW56-s7;p?Y1{?#90mp!2z%k$$a11yG90QI4$ADwNG2j?* z3^)cH1CD`@Ed$MJZNC2fKiFb{azzIiaPaxiq)}A@SATre;M;PQ6_sN_i4C2oac<{*)2D=H! z5eB;p$Pos62*?oz@ydht$q@$k6_6tg_7adI4E7h0BMcrSAV(M+B;bJ*QJxJ_L%>|X zA&8=y9AV9a1>^{WhX}|K28RpC5e7#H$Pord3rKnSx$`$62;m58a-7PE$S$-gwPprJ zC?`i4Y!r|q3^obag(6bT@dDPxK*~se=)kZvK{U}uVm?Vgw5EWQ1?**kQv~c|fl~$K z2$yr3fE;0PrhvMCnj+zy8C`e$zCv<8MnL@bPr!u&Vo(Wqtbls#8J~D(M*Hk%X);KJ z>~DdKM6*5ylICCwY!=O-7PweIJ)%wSsGWW#h$CEg5UxRvFbHln$Pot7fi=hx2GRdD z$PorH5HvV|B0>mywFWuDn&{OULD5|wS1z7Xt2Tp(HS&YV}WR54Pp`ymYM||W`Sr; zt*IwflRMfg4`Y)fTu!u?206kYnnQzVBgqJ@ph1qXW|M%JX+;y%X-!O(0;2G~xq!_A zqTvKYNzy1MM}i`0aG<4$s6H8C1`~5cm6uX#l#Z}DgA~W-Vnma&U~_a80m+cTF)@&m z#>PPMi3w25>5$D2vp^nGlwCs%B%h5jkep;JkQILgTp&IoZ` zPL2eiE+;@KC*r!>aD+8^f+e4r+oeeUtc$rl3{sKo&cLIO%rS~ZvrNYc#3&AflKu&IoaB&JhOngaA#B1fbRgC>iNK08NgtCgNI?BMj;j7Bo2$fLarv_(WWj%#lD- zlMFD=)Ll=T@W~O@L|psiNC0Y|0HxvTDGpuw1wR67BCgFj!k}KLK$9Z@s5Jpf;q{3C znjB$G#I+_z7}R4Qnj8s0tqD+k9!PN0~9`Ii8)7D6LD?M5eD`7h+zGCx^yrGX%d(NKW1zK z)aD!s%=IK-YvPQfr(a!7W3F2P*T0w*#V3Q5(R=~-GJhZsntEP>xet=&0!y>Aj+3Tl z$z-J43+6|QCN%+rmh~osVw>0&@d5#4R7R{{|s85&3=-e1cg+I>%hlu(47N~m&nwTS$BXtJEb!XrRgSt7O$q^f* zj4rTzLP48zB+%6JXH-*9>CluZ{b22iGP=<6$soD9CsB=bvSV8nc= zm|tdT4ioTl3mh)s6&5%`z$+~f>m1!}u8M(Fq))^^D$>;!I7-KfkZWQfnO_?NBj%&U z{F9a@t^#zCuCu^H1-#w@`4Wb5zrh0a%z$3^sTfGP-)Mn)W`O2RF)*T;(F&w_v!&T6 z;4Kz7PQXuFpq>EHKRH6oP)|l&cSVi_pzd`5rPt|s3FaJOO~kc1M*>ir0~GTnifcYU zqa&=zAjP-EK&tz#7C2tVDfioAAerAD10&`W#QY9RbE1HE#z69UR}3VdcU#~jF~27U zlKH(cFk(Jg%3eM5HCRM@Y<7q#6;moUJH(VqC>2{Mc#-T% zDHWR?ic%4!GD^i}hmvT)%PAF`9b!rql#0y`RZ&lsl#0y`vD#HpDmFXBvg<^t*z6Ef zs-{$Ic8Dp}P%1V%#FRQyDmFXBl)6wVHaor&Py10SHao;>S4*kb>=4OL zpMY>?3WZ3g(@QHl8-+tmi6%eXS_y@iQks&n*&(KsPpR1K;Dy^x9|8)6m{K7nW3xm0 z$35`x(H?j7xUxs59`APF(f#Y)@9BO`_p`gN>^`^qf!$U2F5Umy?fPyfciY-+LAMLK zF6=s~>%m>$>hgy!4|lnw%V)Z5?9#JKS(iU`ex&n{I^W*;v6{PUuC6(&=7gF#HJ$0V z^S`Wqxq5r`s_G-FM^*NztgIYbdR6i9#b*{DUVLbAb#cGq{}jDg^o^pQ7u{Plpr~t+ zSM*BZ%>@@0tSdOS;MS7K1&0*uS5REgSpN6?g0es6Ut9F+!YA{;l)o+i()?5N7w2!T zxU6J){)qfu`Q`aL)6b`WoSsnDyX4XI9qB96o6^hE+46(RXQyX%PIvom*D>k8mF}PZ zX8D$)PU*)B-_6Su?a2FC-q-W)pOo-H}8q@rYO#S6s`mEKix zU|tux>Gs#uuTtMi-JiNXwKa8eYC)Z`@+)T?FnWv_d`^}g#p=-uS4 zDf?8}1>Py%x62lKCzW?ApX811+_&@VUH?+^VAtPtI@sIS`(0^~_m=vD`hlvcc&U6w z$;0Zt@)L{RsrYk6ZRuy!CG^S1W?J4*ukgEAKb4|B>8U2&4W6yIq#Cmsy6JN2VU@Jm zedyOiUWtxRyS;V1O5c4uN_+8Gu)~6_VcjzIB^t+-q|T=Ynjy1!Y>hKF4Hy>5*7^Fe zc^6vf@lKDOkoG8frEhIY&O^Y12wOh^Lmf)#?;XH;0_`PlW6h^!PtMNpz)j`17d1z3UB7DD zN31bMi8U6Sf0XlLePgy(9YoVr#G2dPljcX>QR@P=7v)+>C%n?AHBN7oH;d%F3sfyR zt)z2Bj5VD1$eM+*4ysIvn58i3cO&a=(Y$d&Bx@FS-hqp>8bAk?bWVunjqXF%ENpAS zP2ju}OO8`0S+hvC?y0&^zoWWQ{UV&>+)CCgjI}PbZh4)1ks6{|J21{UPP$~x!nO|T zU8~9{?@F~ZZjG}sS+ihk?&msNy{ptWR4ZvA9cyni23fPPt%J2!iQ203-ZyTIQ!`n! zVC!gKD^)k>dSiBou!eIsS+lV7)(c==@ zvo#Cbx`#ivRH<{xx|4of5y|^Nwr0WB(R#PQ+5om@k;{6J=DaRm@`Ko#g zV76w#))TjCBY&5#=ay<33$fl(&(8-A$Dv$J(3~TOi1i@^5$7yyYhy~HObsV%zPgK86PvJRVO#GHdUYsOV|3pA z=qO@6f*`VHA=YTISAFYZRY%7)G^f@?TWlm-vta9JKkuw&(Ns}M58z@gHj1rTuywq> z@21guZC+X2dNfE z?xH?V6LuXvVXKSgjYSxhoP}-e`I#50T0O5N%G-?DD&>>VcH@sHkGYeur;^$Bb30QKwm*u>C5(r^)%8T)>zoq zCy6n&H_qwRO zK3lU$wk}ZpY4Kl4eJy5vBwMpcw$4*W(mjkyVmxMjG+VPU)_R04p#%t$LKyE3&>=iM{T+CsKwVOwJ+xeWg;E_9X+w({&S6G*v*6T%2y12P_Zjr_zSP$u)(4O^8L?pN zDCb4Gz4>Nlf;Ht0YouU{=FQfLy`>MSlM##Lyi3({OQD37W+ZQzQQj;#HJW$1>U%!w zT^_IZ{_v_i7Hl1@cd5FW<`%w7AITeLlsAjyyerfzG#z4Yu{h`Vv<8qhJ&0prth0n! zA*ISF%Tl^06PwR*IYZVg*gCB(QAPH&BEj@M!qc0mG{AH&BD&R zmv2jLMb?!xgIM+Es~RlpDQ^~RJ>IfIG_5+3bq$rAgEcc@SwPk-Z0jExUECqABJ1j; zym5jfYZj*7Sr}eO797(0IYT#Er*_kTl{c34WX;01Hl{i`XNzHBPSz}pwKn8@*hkP} zIJWZ6&>>l~U~6vgDoT)0LbWKP`(XIfHKEy|i4Mt{g`KxpLgsAm32e=RttVgOr+a|Fv8iw3f0VduR>Yw`{=8qZ8Pwyd#e zAZr%3^)e`$fS%KX`YG;Zg{*PfCuxo(4Oh*b-=MFS!G{hQi0n^*9EKJ@J>lS9@ zz1f-tTl2hDq4UKqMSm{_Z}R0E#Nr$m4U{*FRrGZ#x3$TYlj2bngv@&S>uu~rIN?aL^z31$yu0^>-_B9mDGHnpxGg2eK1?IuuG1* zNXU6E!GuP6voIwWBO`f)Rws>6OlV}y!Y(=Zkr4Fr2y2)Y$eM+*&WaVww5p>>EnWNT zWt%;|F}TQ@g`GEB^1eTb0ZE)UQvzADNUnF9)_Jflp|uBs)z?5R{nUsBTWb|%_m&cZ zs>qsyWsQa=YZmXjG7FKcOSMU6>U8(OA#v+(DkcQ zqv>~~ILn9Xt;d4r;qPzxd0(QH{9OUvalrb#K7RJc#SoPo){^(ci+n>J$S5|8L+KtD?umvc8^-HyB~*cyNIs~vf38a)rz?Z{hqe9yxls`B&Rit+@3?pn~nAbKklGQ>Gw z{I>TR7$*^8?WOwLnE^UVp$ar~B;@NmWJ=W$fbyZm%#2J?SofNDJu^T@Y|S%2QVZx0 zGa_Ks60z>B6Fe528osJY(L9V*EW9LI(^UO;kot~+BvEs#w`zlsd460~WZe%ft*B_$w=+%!rf}iP}-UqKiLIvOdznmiV z6qoRW2mkS&#B<3i{gWkl3tpTUqF=o+UraN2mL$DDWuE)f+cj0TCEicKCYJn~1_2bZ zw80_2!w|JZ&e)=s(9Y6UMQ=24>7tf+xdYqzkRE%5_$r0Z8kL#4%wjM(Ts4jrPU z#p{enk6Yr!6KucBVOeL=5@emgvpca#`Z-Eu_cm343h0Eb%!7&LiNKkEO?#a*@mnSfoxNOB-I|hE6G6_h zv_1DFn`n>cJf+9~#BeLEf?Tq+(ffvaM8xxy9)EU@R_RBU{DxGtp3>uUSz@f{w;`?Z z$)%MZFP71I_9x3|k7rBi@nRY62?NM7+T+<$dc0Uh^Bhc;(1|mI_xiBqvcyZA`rW@+ zJ@JMawp^BY1r_P>JTV-xiKRV0vxH-O@{oAeKH3v7KK(vp&MTa!jO@dV<>z=9lRlRgFKtFgHd|tkEth3alO8XvjO<*N{m7D= zIOqwSr;P0BrnFIR2a;uUWV5A=Y{@ffi5HKfBbzN{War9rELlcJHkTe<2OIm5&$AOi zAxj(DlDk(>Pqsw$Ocg1H7psGir6{yGJ!&bvPxN1>9EzT12e3pPqrH#wL}{=w3rf9S zlnPr?QIT%9C-*75UW)ApT$#|>0s7#UUqKB@%dG?hV+6(6`7?7k*s`@&sUyqeR>2I&vmiw% zY+<4IS=#rZjnktHVSMu#rw9cu3CFV}4x)|Iqn2_;V%>Nj!kiyHBe8cmBjvJ0D@D&p zY$vSoC9ZqdB)E=wY5 ze6nS0;}fGSIzHL5wefiXSw_bvTSmucw6s{)N5>~yM#pEg4`Gx=$7f%{_^irjR(%*d zJD}B~XI{2!tq-A&(K((iTk1n71x9srj%UkgAKF0+i=wB2a=nO{v%XzydoSnrF}6MZP! z``9wp`y!U;L($&Hma*O!DeXVWGU$CuKchQJ(;2O&%@7p&&=##HTSn{odFsUW{hF%P2#3X|pE3C_`)+WhiP%wTm&tmQjXmZjoowy>YgTGPH!W?SQj= zzz{u8@1FdxPbc~J!utjNNvCG|oC4LKDW#%MP*>94qd#bfS#Wj1;2t#P=rfXh|DSsqffVLG^UlE> z%e}ACAGT)}s9$gd>YjeE;;DOd{9L`4RLMk+X$bFRM?5)`BaW~mF5{)z1zOAVv&rp< z=P*oB@S%gJ>PX5SgP;EZ2NFq92Vp8GQ4gI;=^TNUC~J#Wc7Y>257F;Ga0GUq{)3OQ z$E}67lxSaZ#1VG1T!XwnzKxE0i6f4%qYWC|ruQ55ehlpqMzP?(WlZs)YW?X*SB)dk z^VCUtzeev@={?#Gfj_;)jN&+ObPyeBM;t+-r*6@E^h8ge4%@;Jrg!a#BXmTEZ4W_- zI9syi2s@gl-SK|9j!VChOyoFlgvXn@L>ys9*tabNj)s$gcEk~wdup@Zb32};$-1nHi-Oz*GN`^)uS2C0m-GC~o85*=$T6$jwc5qt>Hzj<6%_+ZKWnO(g?eB96e^)1Nbw z{Su9|UZQE@h$HN1g$8+lLK_`n_Mnfw@n1#ad_8rVHs<~5ZFJO29C3t>$m@2!->LUk z>wRz9BlKjUZ%ZQ@aD=g{OT-Z*diqb%%KlW1w9XNRn0CYwc7zkXrzRJcOk|zmI|9xTEH@DFd`k{8j5jrBT zlgY8CF4FsJG$I{QrV;cygn(>xAMJ=ENc7ZI*8USZ-a6SR2p+5HKc|OvBphwh`!DJJ znR;JBdjy$s<5Mjr#$80WvS&!{&AcB-3UosVUaY_mH|(mRv*=di2y{I)L+@wn{Y$XE5k@IK{f^Avwa1F4V@nzgWk`0V(Pr z$H5Spuk|RMBhV6MZPCgu>_}G)j&`RX!Cvki40_B-Mk zo=U`#_B+}~O2m=fbEI1hj&`TjV6R(^BkeEINHW!Ab7c1%>8ioe?o_Q_O2m=&muRp! z;z;`)@nVDe5l7nZ2zLZD*&J!VqXWeeM|RJVZZ$aComPXr?vNa5e~AW=spg0yyXQz( z4UTrFYP@Qp=I2QJO9XpeB964*5pE1=jyTeOM_t7cN80abt~laI`yCx6jySS=jx^bD zv^&i|OG?C%_Lm437rNCr(tbz1#Sur^@2Iah;z;`)9UzW4vU`qntHIIkv|1l25l7lz zBG~H^aisl@_J=8T0Q#G}66m1KAz1psUiTx8z(e~T>8im|`^d&45`HAK$L1ql8_Y)> z+E=wbIo}D>;7!Lz3hq7Z+E$^qNeD{!gC4_>Gb{bk%g}p+*NRF z!FOt2s{TRo8QuQUy|jDhf(2Di<;_UJvU51r^ud=M`*8EZV zZ=~-|AD4cm?8xeutGc9rn0Id8=)AwBHh21Nr;6%(QfJm|t6r3Q}SZx&vdS;s4gk*+^K9{*Rv|$RQIZ8^=gU!YhrvZBu3)j|Cbf_ zsg#-_!f?4GVSMG^FyLDW$F-6kBzx*oI>4X9#r{gYFQhzMYNwHMn?G>lVvYgFfMdWh z;23ZWI0hU8jseGjW56-s7;p?Y1{?#90mp!2z%k$$a11yG90QI4$ADwNG2j^ZpJG6N z|G$K)tY3;l)r05%_&rpC`bVw2C=0bJ+FrCC#&4}m*{=)4|^k_c#E{IaEO|9Cu zHG=BN=b=-L6DSwpb%Q?Y`Jye}`NkNZPrbYNSL)@PloCwjGrvBv;WroWd+5O4?~FOD z`5*XZXNQEblqdK;pV{+vORj;d@%scZvnBs(TV-5*kv}%_&qls$WDSU+aG;TmMlLXNjgc1^d5e(`8~K!xe=_o4 zMpmWSZ$BdsGjg7htBgF?$QzCPf{{-c`9~xFVPtte`|V@o7$c7`a;1@3Bd<5|0VBU_ z)1LboIn2oEMpo%wi9U$H zlB&wE{7Hsv1A2iEZ_6mf8_4$I48aK525{xWDnmzlLy>$~cYAdGhN5H`Zw~p|+5rLC z27EchhXW_&$#7*djBf!aIKj(H2{688k^p0hOMrVM!+R&gmDar5&$?)c6_$(U^rUJzLEP0BdOf#t%OlYBj{r2aZ~bTVCV_fx0(1!S6_edx%WHxcYFaZ>C?mN;L}Z`%^*D<>b*&^Y~pL;Fs- zT5nk9bi`7pHx(Zn&SbpAxu`LDiIdGx^=bR>2I@SaFqXJS=x!1Q8;OpMaIBFVjJ(vy z+l+kF$fu3mVI=*nJRQ22_B_bQCL@nF@)RR4GV(Jd|2DGPEN%K5nKAN6 zBUc-FzL7T@`9&k2H1atkcN$q~_}Je_?!{%}xHgezKY zjp8J9Hm~>Lww|`(Cfk6|1p8TT%K!u%I-3V237^d~TA8%*XX$(=!N`uCh@nqYeX{n! z$?!58&SdC_LbhQ!?Gv(GVZ(uT?6i$4Wg9~0=Ro^p+euKJ&}lo+4xP5)m$%SqTSJtR zZP+8H?HnhD9A^Mz9-@jnTPg}u`KW+-F_-{4$wy&!5}MP4TGpQX>y3Vv%m+EoWb&bV!L%)-J#fk|2G51 zCARS7{ljrwhHM7B(FSQYPWf-`g26Yg7suj%29xlbv&{h@OPIFr-k=)lxq@H?}==TTQ{y~VGSM?~vNDKG1 zpi}*TYU}$c*4l6K2m;{yT=?qW+b`+!V4_aP9w{VJO_EYQQ+lk?b~kvtCY zvA}kSkInYWaQHG9T_^+r~*fjvy>H z;;=YH$UWi$4L#yM?``pJV;i1SpX=jYPLuyF1{2ALQfrgg0m7p^WeX<%ePvS2bU=|p zSw=@(tx4@?WRa0Pnfv9|GX*thnC_5gciC*W$+T?T!Lf&5ViF(MEg1$8AMH+IR zrmJUM1K&@}pidZQxV9W-ELByXnQb zRc=@gEF-Tr@@^yLqVcEZ_%BBO+sG>8r>~KtjhtoVG9#-rOTi6|#);G^ z7~IFd`k6S>2eTQ@Aloo;jt|!Rno|Pv?Y`!exuRKj-*_>fT_>Q*_?okueDDI_=bR+X zIee9dCJwG5=LWee-{(BvJiAk_TpH&4pi2AT0)V>=G3qpOjgfPJ*+}SsTM&&CC(fKQ zadzFDy15hQ*Da{Sn^760o|B^8))ei}O_8&!QZ(gFJugLm&PkQvxQy;t6s9UjD>m|^ zYnWN`)yOQ_(89?3?0xrj_?<#JLFhN6z@LAy7|b>qf;%)sXUSttX_gy_vmL@<7HXoA zeDRpc@L}YZ-#v{2qx!n@Qr))~_~!IkN>=VpUxmedaiiAPciPM}NL>nM)n zr>Ti=Hu3tIO5HATI=>#;iw>A|-zV-iNWM7DzP#pDbs61l5KJT`QTTA3W^ocD7{yNh`+J%DA-ONmiXs>S87d#jNwQ-C-siJ}%>AD;;FpYS@f=VU zUh(^lE;DDgA@sOe*BG^KFprzjfnGI_l68LBNg3&Uayp<{Ue6b%Jc0Q9whSMnGuIuk zY}JnO-)abTqTZB>3=opQZBAMlYe(32OBxj$YYJ%V5FY&*LD(K^$1NE{?HEK3`(enKka?^*$hCy1O@Qg zMx}V8Ge7`mGjv3O-g}|F?__%hAYiN)d^qrp{_4Yud?REV(6xP-W@sIvuVZHfrc0GT zdz%mA>e_b_%zfe4y?kw4ErqmsTEumm4=Z0Ao!Ey1-{|8BFlO}xc<&gTQB--%kO|sN z49n2gt20cM(sz?54``U%3pu72Or|aSfJW;+f~&&1gf~q3gmQT{K?74|P>yXmG+HkQ z&o7uvBf0R@6ZE}(DMO#Ki}``d6G!MqKyVdZNdWWzz19B9LEfRJq%M0>v^ zfi^Die0Y0?jwoasa68k71MML;JlpquunlK?_z)Ye_u=6-98?Eq{~$|Wdt?aC&=G}f z16Fswb})KJ+wij)I--zm7(;tsJE-NMHk|dd#MOka9WaQQ&WD3?XKXm|4R5}7z@Qmn zyl@UKn8(}NLAf!>`cASLI--zmm_&OY4t!6x;b;8nOtInZ8Kro`yM75yu<}oU@yd`7 z2bG_l3?E^`K>_F5a5h6n6tWHTXz%+*;SjP7^J(wHnG8U{N76ok{aPMn!+~#n$Tvaz z7#rS}p(6^}hK02EwV%xZ1dJ834{y%^1biIreK_cYi)=XPKFu~9I9Y7Nfs-XRob_uN zegU6gBxM`T3;5itf-E;Kyy{H9fI*fIWY62|!`m{H6NPNUjyq02i(q+c+rKmqCOf?@ zbazsiusyYx^O5+gHIaTsVpW5n8#lO&lyz6=!lxJMVSRu=YbPw@-JKMsV^8g)&E@W- z>?vmBe)0&Cjb|a6AcG;0!K_6a$&Lvh|2rvIkxGwGUi|ka4bRY@tbxmemNl^WZ(SqR zVlI6`KKgXNxn@(%f|`L9r4^~p&(?gY;+l%#HJxi-D*r~!DHXFSzF+>Yic^cfUwA=& zS*lrWEnQzI&;P$d1;O)wtlV+m5^Kaw-evottx?8Jv~8n^+#RDsHCGKj6SAeCPp7yV zLx)B%^Yae6yD7eKUHcDnQ>;QODJp@4EdBofma+8XxDLJ5f-+)5Yv6kJ>OS9Uq?-@4 zsm#@VZY9}qCy+?S5XIK>?*1c0zIA~Ot;%U zbSRFK=W=L(7KGT%58p>H#nmO;V!!x{94ht>A_v)6l|RW;{`mH*4gfr*29#BQ`J} zZAuvWE#fZ=^+?9~Hqv}AQ}fABM$vqqG7rr!f*T4V`KaSZ3Th@>Fp`U!J}l*nj%1t& z5pbsy0rwdZiddM@8kB#MJz6o`lbRUVBn;UMZA!njSmn2r-_p{P%$(hg=4`vAZ)vfm zKU{M*U({!*x;|67>ZpE4g=kC5yG2_}fi5&s=Inm{F=`_tDcjIAtFBH@+kgxGjyz|& zhW(ivZqVe>;f{_37tr_T?{mnZs!U@q1K95tQf|{NaGTcd7Ta3v7E)|-+(AJGKjeq8 zTgdz>^wgS&G=DJgQF^~SH=sV$Ua{ulI{Mc~KaMolZ7nvJ8^zKLxn#7tWE4*{2Fas0 z7^YD3N3VRB~)|!!V?oH7;Kzv*WAE-PBp;yBfl!Rx~ zdvZ2tw&8DYyfLN&+Ax&mR64@;QJGEuVW!XbjGT>AB83%3o^9kOjlAE;ZyWhrBmZV( z5l)#DYK@wUMtGnU7O1g?)^~&+-wb8oAiW(~Z2+$h(aE zx{<#y@~=jw`1YXcVPw6LlZ-sh$c;u`X5{Tge$~jI8u_A;yNv8gs{(|9Mvgb~7$esi zd9jh(jQom`KQ{8uM!sug4X!OH9B5>tkqeAmW8?)!-eTm#Mm}ZapN#yMkyWN2^fU4> zBj*{p%E)t#ywS)n82N;ee>9SxjLSruZTQ!JcI_hS0~kr!hJPo+|4D{-MPV>OZ>PPN z=({)>E=`8Zli|uJ%vn|?!_~=fw`6$lD9oJfn+(?`!#$JX-cgv#-6t6y5QVuU1C!yw z$?%Y5_>g3HSTZ~!86K4kk4c8dCc_QMaAPvulnhTuh9@P%QtTmI-|cwsVpTr%983@=HBmnFl;C&MQs!zU)gtCHc>$?)1_cwI8Q zAsIe389qH3-job)PKM8p!ra7LlHpT!B~Fj)li`iY@M+2L8OiXO$?#dp@Rlgd)%j!; z=B{~tGW@Az_@*e#zOkp%(M6E$2w3IG1?S5)5uE%z-a{)F0|I*?AeYq@Nn#Oy1^%R+p#=)vxPSVI{NJZ6dX$~ zY~gDU|DjBVk~%b?Tz1%L4l+jK1yh98Ed0O3aI-o7qLEJ;`J9o#ViEvmhsZ4io-lBQ zlCbo|g+K^~Iay>PuyGQFSvxNV6VTdsLUq5x-9sTJ`O$B;RyALst5oxQk7TZec@vhx>&<^#%hW7d>w3R#z&ro?0WCbH_SEXwqeT>^IieWIt+A;DZ z1TU9JKfsu~*Sypqb|Q5lJ_KWq%fao4Rfh=~lGr*tNIOYEgj?a!A5RI7I7Aoi@NkRm z@ZlOyT$OBwij9qej&rnw_R+boZI3vt@kHgO;S*i9VETxTDy&MSdCly26#Y>LdsUkI z{g7+}R;3-iGQ}@7v7s8=gYgR~S(QFQ@s4d#nY5^QIy`0g{+3w{{lLf*O!`em{=&$7 zv>S!tMlLn-W+Q)T5V*JaUcKJE-0|pP?V})1$-OpueiCUxbV8w9!fQJ@d6{4Q(P^Hq>Jo`CF~dAXAjS4aE`yqK2&&ub(O28v6Ru>fE&$Vbs=>%2J}2 zD}6?5_1RaOt+A-Y%wXDijGCfm(no)0(fchkR3p9MK84~lsTt>}CN)`2&}d>S^rp7m zNUgn!xL;~{w|ddO)N9V5&3^|1uRLKpz--V(z>L;Xhf8V$o7UVd6>z$ON{f!XAyjTI zAm)h-ZE8CP#diEs{+v=8hubmpZO^Nu!vb0~dIhw4%oOg2!@lOw%co!MdLHf0$*)Jk zFgnZ|LvCc!^iPv!Kq@n_;!OaG>VVT^(JcP%f*F^30yD`FAF5^N$MH0Y=1DkBqB)|c zNnAuk-URqE-Mo0s$kY=uv>CCi@CcIN9K8TK%(O*kQbTXrjP8QLWxJIoYXREX` zfA&L9!WNzVY6*LP<%?!P{gYcR1KQ3>)7~q>eH>(m;Lkyk*Bz!rZaIGRdaeF-Lq=Cp z$uAxFs3Z2#Uc1B;;tNJTYNYg9I$7wD*x~v{dS{~2z=)D`jaGYIDPd7 z5Ba?`rn6W_LhnMbPG)k#gMP_JX!`p&p3JbyN;sKi8IH9kPG|_pcZ87|Xi#71qp*09 z&WrXgb?puQ+8uWH8lN6FhTn5RN%SoM{5|1Vd&@(u-0dA`xb|*$tL8S`-S*B>lO~Ms zXXsKTslDa)V(#`1H2n6KlN82xnH%4^8?y~5yW8Fv!U^qN$8czTW8_M9$?Xk|;2B6= z!qaJJ$XX`Z2hIn$TZjT2KH?|1t(t8ujz`|h{*pdN>Hd%JT(_0;0W z3*X6~nLedzpS*+8CFwiz-buZf_r1KWdChr;@sHwCp8j4up8xan{8on&?Tv9K!F=WgIimZ?_^k(s;#t6x(8h-!pTNnWaRBee#6M$ z82NW2E6p3f2O2rS$YvwYH1awlzhLAKjoe`*KGu$~uaP5-oMYr_Bjt_ZJIwJnjr^^V zZyQ;qJGW8;jGSoXVk0*jdA*Sj8Tlh4Uo-NgNK(oirkM5~jW!#mMAN!i1E=YHB=53O_xbM2OFP zN`>eZD{vS|5-V_+BkADWN#HPt6*!C}Nik5bND?8s@Y8Z9p-1I~>m^p`HaU_|_#8>F zN+&x+Q|?Mm((^Ya#rUYyGjDPd=~FW&TIsQzoTSHca*`g)$w|0|&XE^xp5#cc7izH<@N#BGCCuK|$CWjm)tj(QN7f+HB_K7C}LGu2&llmnj zW!P#!JW28z7*A5h3KLO|dZCL(lQNta22mtQ@*0^tX>{%+y*vvuFAnwN`Q)TbZinL} z$zMO}Q9x*Hb*(k9ER`itvIaVR;De%l)Dh)dygFlreA~z>vnCv1y3QK$R8Q`qLF!e z0#|B3BS#rI*GT#G*(K)qP9wJ)`F}?K!^lo%t$2`;lZ;$qr)Q>de6woMlLn-Y$HEq6-cm>^w2g* z7-*3sDF#lDIg;>*Hb)Z9oH>#b7UL)-^4nu8ZYlhL+{M5-&?=!#)Sz&ZID@RuorKe) zQWfz{#0=bf!!bx^s3kT0DsmP4CQjl32}-CuK5hg%e*6qK*tF>B1YUW8z7Y*RkOw%?4RP zE=ouu2$s#^Byk40B%VZww!-9)UJc$t9579*$Bu*9lZt!Cy^iBD0;OMB%v7*(9(JV6C?qWq*6qJ zB-^SioMc-?F2`-Finx_@HvQ-ed0he>3jS4@EctU^a|IgI^ZKY4=t+5<$6hciHs-kI zg2spKFIsX{bi1INQV?qSs3Z15ujD<~L>3y!*NIAD5=Y4BJr=OA+&PX9=?g!4@BpjF z3W7qm0e`)e^@4tqXY~T5db;2ka11yG90MOQ1|Bb2(EWvyX8-s9S(@?j{2yyQkM3CD z;`3(pyIL&paJt?^+hmI9#R|m{nuj$1fn&M%dZmE-U*?=I&;Q>k-r}8Y%=E1j^ZXwR zWdxBp5A`fR0>$ajfZN#EPz`fVZ6t=w`LpBhxe6&luN-eO_vGF%38g7c+26=UBNrNZ znvqu<`8gw>F!FgL-!rmD9{U?=wXA(p|4RGX5?%mPcrfXBX2eGF(ZF%zmemOTx4W$ zV-hT2eaghpKAyyNO-$nK5|cQm#3X%rfgIy`eWaiFag(GgdecHJN)vn<d#?;rLVL0WE4Mh%qJ>%b7 z$q?M3LFko2Tw>NJR~z}D;rjbV{=vw%jVv>3zTQTTHd5XpJ;5ArG4eViWexcqbNqis zzG-B!Sp(J?DbM|9n&ah0ZZ`57Bkwa(z7g<@Iey*90^L37`J|CUjhtrW5+lzr@+u?m zHd5X({iQj6#mGEfFZpZCA?A3pk&BEx)yT_@l=lL@W{!VmAWJ;C4q#|fi2PydfGRw(4z&GpW0mQ{K}m4x@!_D{Sa>GDn4`jQhL8*% ztod+I?ol=z_{L%)q|If=Bpib2m}-ej<^&k^^5MXD#)gBEG}>@b`6e3)0?%K(+x3RUhVx1IA~*ShP4w)Qkf+&m;m~u?cGnE>N|n< zcG^@X^hcP30-8U3}Iz({I)NvA3UJcT@3k>55>Jn z>;QoisBFQ?V1M*n3fYVn9k`3G3~EhT`Wb0%DwtD?UvBw(5JJ1(Ts6k7Ks6`)j0z{D zKtng^0Q$v!TO0I8Kb(%~q(cL$fDMiMQE1Sc3|qGwd4Q4T#G+p(1$45(&oh$O5>=Ra zDeyq@NAttu1O^R0JllscLIc=$5?ZIIj5r}pXvaDe^NX>ct1|@}x-+e%Z*%<~c~ijb zu%gA;L59`vzKw*%P6O3GF!Yy9Dm8k9~vq5uHP}oolN-;FtWkO`9{k7#^;&i zn~Z$ONckpNbioY{{B9qN9n-&AJ9xStT8C#cFjh3u#?#(+lFa}FJdySR?5_(IRVjco z(1ms?1UCwtw&86)Twudi0kgJmKg)3;I3vC%+A#iTEJC)SV5{Y1dq$(Ejt$Fsn&68p z?M$G3u?1%Xm|jQmD<5bV5a`2!?-aexkN~G`SoyvSY}oRhwVedoTP--yo|p`e%ce7a zNrEgV+OSpbt(JDkci<#|$6aJ;Z}ST{(T0O8Qe>;|*ej+%s~Zp=V@# z_t!qXw>%?DojH?^*n5&w59fbl&g(+4~YWDT?d= znqhCQ!GtV(Bk}$}u|UHaXY3=#xv<_E zkc)*7ip(|MS6a`D{lIQ77)#CUHQxD_CRkyz*f4J!FGkcWtbukWRwKPuOP27e0w9&t zs2=~Z{lf6ET^skeBl2L2Cvx`!m}jy49)68I-(c}87R&wcQnVYP(&ED{KGEXw7Rzs# zerV6{wD=K=U$po`i;LL!fDRV-uz0Y=V=TVN;-wbfZt=qwKX36?i{ z?=0S8@n;q{X=MDcpT&JFKE>kmEWX0xxmYVju)H*9Rm-N)i1EFNm{1dA`X z_(vA6w)ioNU$*!oi%XiAaywew)8Z2>9%u0-7GG=e&n>RA_|F!9U~!>&zCpFO_%Mr) zw|KP0b1nY9#kX1fYl}Bo{5Ol^b`of7ah1i#T6~Vhvn{T*_!f&FwD?aJziaUhi(A_z z#UU0Cu=p&CXIQ+*;*}QPZ}Br0zish$i(A+$cL!PA*WwWtPqTP|#Xq)qoyAXC{D#H< zw7A?}K-%Bpqb)ww;>i|YW$}#`|I*?oEq>kNPc3e2$IDI@_qKSL#gi;fS$w_4cUkfW}GMQ{(k;=7q-?h>$3d-CB-a-FvOv$y{hMQ$?g z;0+mNFV}^XFL))B%sq3ey6WIwk7sZjm8&{T$|Mif+<%?#?%zK?@Q)c}Q=N|w{Cy_b6w<2el^Zj-O(8S4tcW5%TlZuX`Igh#{wbo6>kc_C zid-^baVFUq*ksh>nPk&CosawNvl(SC*Ogybx8b=AvT^MCL?3>uH1N0KzWVN0GRa2e zcTT#B_lg5n zd-fwy-2CMT z?wfyge28RUreozA|HA7ZBgX2habE-qL80mGAoLF^zBQd$anqa=}fYz z<=mDRyc$tLAPv) z;2!k(-hYW8FZp6^6uD*VbKc0{HqG$L_pXQ{f8OoBOtLZXi~9$@8BxeXAB~M7KljqB zQRI8iF5vUQL9iK1eq7u)ihS00MrV?ZC1)J?Q6||G((&ZpZ%35fb;?;$ z+WVr&8_qBOYed;)%@2zr54r2OOtKm9E zb(v(-#6^QYiy|+abo@sVW#9S7nke#_r(K;%{#;M!x3)g@9}$Jj{q>4Wa+T&jsLSh7 zDMONek)w`lUfXmZx$O=e4*|DmE7%6iv+JQj!8WgVO3k1PoL z8dSOPcR#A`vR8*;-S3YjKmYPym;Ywo%B0S^+hSFaEW7-JMKd>jR4tdL)0ej6rjYC# zDdsVRBkwGV^}bUnkrQmBQq}yKJ1=q9*JW<{hY78tZ!k2u>hyjpxU`LH6{%#Cs}Ac& z43=*k>=mW7-n=)x!gixV;_HaE!cC4&iZ>|3w;|?C_`9n0ZI$-*zk9GJ+6p(BJa`Xy z4|orF4}6^-c&DN!egFSHtN?ib{~nFY^!@+kWt&^=g&Ba0gNu=d;(*Tw2>ki>qA%n) z7uFLmS6jg%Nl&~Dis!{nXTbp8vYq~~6Z99sKhPAV1b1uH|LDT5xA*DWa9!`t>#pzJ z_pU{~Ez38G4uLi%E|SbGo>X6@rpmJzNwYZO0_oeaNSbNy-^+XNCt6?6v-moT*I2y4 z;#VyGhsC9~-6}0U+~N~09&hob7XQ%VJ1u_1V)>51hxWY4K1_X-HSaHYZevyH`vS}flg z7-`SVr6rX#LilzC4p2mJ#fcfXJ(WRDl1MUpLYliSNg~NyRi(+PB#9*R)@4Apk6Wdx z+qh)jZghS>6%^7g%pIuA_@PvJUoZijA4&z>2O=|V$;u>o$=wD2Bglt_$$=#qTfv}^ z?qTjg9To`m5{0)jQ?qJV9AMLa!~fL zFgcmT8Nm6CQ!1&cAfJhYblF?d!$pzM)h^2#)K#;=x=Ae%HQ%v}evNu$H$WV)7P z!sMznIpbGLB%9Qy*NThNb_cy-_Q<7|q{%6$B&4eCvsXfdCYbrW64AeP_j>(d1P4qey29)xS0 zrBi|)%98r9p8kn@Mg4GlAPXaod4#0?&yk$D+O-m*<3A8q# zr58`e5saK9uUZr|m=}|Ynr(W~mQJzn;i|`#BDndW9>@~I={{f|0L#A08o{AQzQ1GS+iX3| zdR%RL$#hE-jI3|nt47nkL_P4W?IoOt3F8e)Zw3ul!r?9(4i{LOU|Ri$r=PC(L6g0PiRPulA@%JI zho07tM_W7;b`vHTq%ODkM;5QP_%VxLw)i89OKdqEEjD4)H61S`r-zR>($N(UlehFW zg*p4Mx}=a%Ku}03&CLlRU3Rc&w6SO`sZ4V-(9+y1lQ;vUs@Z61axzIG$$St$P3CAw zz#0JmL6#^?$GK_xT#LrTAr)}wIOi>mtLOy)hrQUXpR3t-Dg1gzlhW9ni2>%UKK|1z zNoFFZO>d>!xjt+P>vR_fd2c_3?M7>g&(p1Ge}$1})CxFsYYxY#H9ypvO>Jxb&bFpt zTD;$J&FlRK@{Bkgb-?M?OnrM>a|0a*c-kPvT^M1AL8`{$Sr#v}c!kAlEiTu!UEj}~ zB7$`nrw2NuBRQ6)-IwNzr)j|i$!l1qychdQc?D_O@-(e5O$&yoBG7`ExKK^PSMA5E z*=mLwt!CkDnwpAtt4`C$%;~C*LCz#K8OP()F#MmQbH}Swa6Cgv3H`t`6&(COAx~*1 zfMX{94BxJn*AFF5Q|D`qUDW_ckA_9lplLXcr)c^>@Q`bUW0~Qe0K29^FY7oKwK^Gf zru`S;MTTS5MC7q8l62=4jL+oW_+QuL0Gw9fn$Z=laD5|IF%}ucmms6~S1MbAp0av0d*+T1H&MkQUrD`UJ;)agzHIY(i-9h%(a6%J| zEWo#G%r?_cDjC|O5ICO(9 z#IP-;ut5*W(V)M$^PuYej=Q$r7n^hl6K9qG9~$&?*r~xzgGqaOy2Vp1zS?3Lu773E ze{b<$EH;6VOqx??2Trm{4Un$~UF{=s>r|LU1_AFr2$R`qO`@OEg#=`-^&`j`yX1ho ziQ$$Q(~){OXcGC+Khe+RNcw9@@Yo&(X#gqKUrREc`2XWt(tqr;M?Y*>-S&6Iw-;Ys zJhpgYiwB!M+vKrEKQ65?_y4bq>F>kv{yztl824QA~^uUw^L)>b+V7)b^waekpF11w3nB%(S;27-oP{(4BGkpr!7d5R0plcy<`g(2 ztzjHCExT9`8ZZ^RlU+7T9N-G>)V%$zdDGM!Xv|rQ!!6rPu#D9kMppWwozP!xKRj)R%DAeGdiCb71k8VcxL)7z;TWtkZ+NEQ0J{-xRwc;o)wmo!t!y zO)#g z1e;@-`%_6&pp)d&TJd;Ty71{$ELb^32`fTUsr4G@+ z*4&h{HNPDXBXIl8#LoTyLu-CLmpUYBL(NQQn8}-%9b1nMLdLn7Q=`Z#>2RBZ;w~9w zutiETIWT7C=U3b5*U0lBdW|7*MeMFI zC?E}CABJOdg?c1=6JH@NTx>46k{~p}EG^qDhWbtZr#(z`i)pU%exY8@<0P``4P<&3 z18g@}KeU9KESBCCxqUkvyRF&SrA)&<&+NFlfgXq3s?)HkywmyBcvqI>@ zB<(RP5NT@NvyUa2d4TA_dk}K+a~!u*jwCqDn3!u4$>h)@3>Uz%CT7T<_A~P$Rar&} zMixO@z?{{?f4Z58&I(NceT^xpq`~#~fA1>RtAks$ZSkvCKWOz?^XHr2S^i~{k&TaRT+#T`Mw=Sl)9CCL2bGO1 zIiaXV-~TV-+FnC*ySI+(E2NX#E-k7Aoy-0d5?7?yNu}Yhb>HFrqr8B-3k}THVXS_# zbR2H}U4SiM<$v8@e|4l9iJOtUqiLR?odO>mgS(u3_I4)nvTx~C;$G*;*fbOKZs&#i zKRHjaIo(tb+yf2HPr*&qVfd^U|A+ZT;;CBRfb9!vW=kB3b{U5ooBw?+Qa?2|ch1-^ z`r-Od+-Z$bhz7<-{n%C?TEDIRLR#Wbw21E?Uw>qnevx-F@tNKO-UHqP-UHqP-UHqP z-UHqP-UHqP-UHqP-UHqP-UHqP-UHqP-UHqP-UHqP-UE3(Ft-8j|MOR_aTPO+XIlQa z{sC-}`n2QTpfIxpDT#wp%R%($_m5u^I?Zu-P7ZoDIhOuiR(4)4N-z1bM=l0W_a5*b z@E-6U@E-6U@E-6U@E-6U@E-6U@E-6U@E-6U@E-6U@E-6U@E-6U@E-6U@E-6U@E-6U z@E-UN_rSvn_y76h{J6dSukg}m4MmFI(LS={gK8gO=3a!v*OIkG5?K5A`t#*D7nb)0 zOurNyF;&D*YqPuq%qhRO%+m(=hg?Hds?eO4eYO5O$W)c)^u4NEn$X<2`qaOmYHttT z1KtDP1KtDP1KtDP1KtDP1KtDP1KtDP1KtDP1KtDP1KtDP1KtDP1KtDP1KtDP1KtDP z1KtDw)gHK9tx&(fTgJb~`~Nw9|IcsT^Y{Pz0^@dj`uG21a4hgx(@Pu5ac=zY{QjTC zQQNMA|NZ~2`^s~A4|orF4|orF4|orF4|orF4|orF4|orF4|orF4|orF4|orF4|orF z4|orF4|orF4|orF4|os!XL`W={vY36zEWPHSPq=JMw(*KY#yU z6uLeC-u|C|3{qa`+=|&0is9?^6V)vIO;<;%uK1gYZ=X-Z7wxC0(KzOJ=qG_P15YN* zL^>CohvIx1=w0pC?uo~P<3i0jUiH)5=WAM5eDi*WKA)kCR@Nb=F8|uKPQ~}Z2f(7y z_S@}7djqZgnmwTXMEGD9%0E}vdbB>Crl!J6UDe5Iwyym}Di@crhF{l?sju6bfoPfW zux!>&tSQviT)78)lP?~^Z899bo1#5s{K5B9#MA>{vjyS!?2lHQs@re^+H3}*g>6cj zwA@(O*HxVW>P-AiLe2y=3>>q;Io`%}v9|lZZ=v1CphlC>1ID8_xK{J)Au;vBx6o?W z+Z>J9+s0>&G;EJ?wpC0FaZHS;Ye8_Q~+f)iqzNp`Mv}e|(v$oB|{?~2W&SO5xHq!$Ze9b)|Q**fW z*>?XP%yZa>10FbJNumU48}hi%+Vrp0sw_5IjRtJ(vLq1}=>gaV-i1gXA)_VIO7L$` zW7HVH=B`T;wTCWA$X0DVjt>Wv#gb||j;ZS(kf}kUo}$J7k%>u=O!FFi`wpq^3B z07gP)Gm@e1`hT~c_XAd<9NNx}V^Gg4)s=uvpodHUGvGz=)8Vubv=iuApp0Y$Of!jsgcUG!O-&mck9^}un_ub`=<~M z>iL!W3c&VIDwQ;=2&H}jr~^N3{tWy#kRZvl8tn>ldwK;k%bRqmBQ@3RFcpJBBlYOONYcp=8q=DAS_v#9#$%DA}lbP`*IzU^P^q%1aWP-d^nJXHI@N zAF%MSC5Z~uuQ^x;APxG%9ja^bgt7^MZ0VT(ZswZU8e4;G4%Upj;iE0?4q$vd06mpR zivX<6(4YQXjV<^>eF4}D=h!{J0Hp2)%mv@VBanb8yB3R_jcScrTX3zq7C=7gX`WPA zVN;epiqJlEY$%!kt70-~bU=nkW%4NH`Z;F(yaV9!`g89A?*Z?Dum@)1ZNj{^auKcy z@Cw0yJNy<~uu-6Qo@?;gc!Yk@jS{~e3V{=Bt0 zP4&kug7Nw`25%k?0c9-CCgbQNW?6R!dyp|1VOXcHAG7@csY&L-+rmZ+h7hE071BlP51TE0%uRAd{Z&%>Vj7 zpLcwo_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+ z_kj0+_kj1ne}e}e=I{S`KR+H*g}^bjznZJ@NvbEvrDbQdIslj~7b87@1Ad1_U|y4} z_}Ra_P=zx2Ek2gf(0;#7pNN#nG@p7t0`L8wtUqNuOHr^-K0%WS!Ovsra4pDh3Q;VX zPt0WI665Fl(q{5RAc=!GvZ(Dae8qTdT2nLTRN`MWn3|1Nqtxm6lEEl^R-7L{8U^w2 z-*+5J51nhO!cWirpB41Tp`b4c&)GI6(^T4RoBsI(O=gsnnUmAWCew(0M?1Njb~EV> zkRn^gWQK*hYoP)83^bWh1`f<8W-@b$<*XOQBzVI0B0XolOlEey_yy0LEoL&K3>=hC z%w!s|!*pL_KRPa-h{<$Cj?X7zGNX)RPEPNcOd}Td-r#(?OlFiW=H%36GL2YR*NORb znM@-Tc#qVadQ7H>$Z&E}J}o8_B53{0@os27F_US;0^^3|6ET@lnug~SGnuZYQ}c!Tg-v(PSE(eI4Nm_`p3o%<1`zHknaI zpOH_@WabjfSyzflUBiLQC;W1b9wrmIvZhq#$qef=eB zm&t?>%*k{Hb8_l3nMN$!mpBRTk(K6QSqs6wx@Df)+^eO8kokQ|+Ct zmAhvt;7Z!;7WRmX+{O4|_z0OO*ds1-7vo_Cd&EUzElt?A z?1EXq#!<0`*hA8r47fc~S+}`*V4p<=M^hV8de;zRud`q>O~AQZn`-dn6f~L9f`cKr zMQ<))+3ie2dyPZ@N&_#PhL3XPf7g50;39Fu2!%U!HkMtq8 z4SFb}Ac-365e3;bFassGZhIt(cs(P06{CkbLWe08?2$&!c2S^Uk2JCyrcwiLi1&z# zvTM*wyNC+*h>NmoU=*+o_COSMQ@!#uGQU>+f1FFYsqCI?8oBqLY6G_)9A-Nj73`5V zaBDyX3M1+$>=Q?;DfqT2=c9854?f6DE6619MBpGEU~VM!Z0txcz`k^}ngG$MxT-ly zorm4(7`;;+kFTcB1SRuQDGN7?N?T%Ru2Tnx3O{3)3g^by%m^<imG-?y_42o0a5fA~1&_^X@hCMBJ8y2^r{N2-7iBqxD(DB=uOaM|uB2FxkNP)M7}s#Iv+;+A z83&lcGyhlF;>}`*tT`>|W?9+xxhuz*8lGC4ug;Y#H05Q0x zLVP-koPmOj7e^uNW@`$4Np*8|@Qp?OI2<#IsfIOSsA>rNvCq z%~_kCAvI_3Vr{~8VBtAi3 zoeK1;ozur(X3Zw)I9Xs~#*`gg_G#%OrPq|6Roc1qa|qZ`!cEw67`gZKZVu5tb&6d8n7aS}(JI&6#|2+W3UjWyI+VAEH3a8CGrujj8f zN4fuZ?jB3Bgw9w%jDa^sBaX)+zGvcZG-y-M;!{=U?uDAGi{%=l`Oe35G9A%x7Ac%a zxXkO^y-4$Rvb^KK%V}l?N@a=cJDs~1NAk?k{mS&O&fObmp2~DN%zIqWaCNeq|V=+$YcFIzB% z4c`R4faAoA`f1vsxQ~0HI!2wOhN%;9X>2&oPXdLHBJ@{-)Id$`TxLq_gR@D{Is>K7 zL^>BG9STnFM^4dJUa0>cigGT}Ei+Sf=EEb#YpDqW&CGh$BrHIY<7{&F1Fc3Og6i~W}j;%oow?i38gwlXV0?I@UB;m6~4`ucF5_m zsiNc65RLvPyk=>9{iyK0u4zgwNDO&yQKJ2(MTwE47bI5KEJ$oPe?el_3yTshf!7YJ zO{9{wiJKu-iIRqXwHn{6cwfB_2*2xsT3q-IVB*BZiJ_0qPfSH-CDM?i*Qn*?KT|&g zOuqX@w3bp;HH#TU888_#p8%G>G(S<-e{o_TxK8G zmZi&J`Ne<~WQV>oKT(MsCd$9x_HK1Ipi|R8ej;9#7SpAH2|zD>0Z>oRPxQj^+G7?c ziemez@(BwPgN7|m{1h~{HtRF0ae*oTP^PMGe&X{B*68nmbOG$%kvY{ADf@}j@3(hzSDH8+6oBktpyKQ zRPB^q(>omSIrR2H;wV3VkZq?+79{=$z`C+e?ibQqfZkOJ2pOYU&h^qh8PRxr z>v2ZsKIls$pIDNZ4OofxE=OI?L_XWs)b~VnA|R}{i>+^?nLF1@KgZSI{`M}~w96mo zr`s1~r4ormI{^E?KF{-S^If(dqyLeu%3_vZzHm;W?zF{;s}M-Ed-=*W>MzA-sj~nX zc7uk5teCtYaVhj}zF|(H{j_YotPi0AG9#gTBz$u# zd}pXieF}I0^bx4b1<*Sj8PwaapoyYQ@BTFy??i@}52J?t&bbu&q8^h zoEzv78DjczC}DJMV)+S+6MsNq^fUFIU3R8A6A-TNrKg*6w$9nL_}~{fN{+|4gSr-| z9XqJ=D?ABE+!Rm+zdd>R;>7J%@Ajr^)Mv3RY72mR*;bt2L@)hJ*?b`Fo3eV>0n67B%DtJJ(CTeDFG8Ic!;rGXDfd(fd-X z-l{i%dO2o>>%02eo$F4P z@)5O(q2Ha8;Op&JF7=nj-ip5k*!KDjdWS-Pwts#}q7-<;NsANi+Q=>Wmw-C-`4sy9 zk2CBw^9}8#X|BCGxZT1+=UjiSguU+~aUVr{w;#Jk^(|Sb76NjWyE8w$3b+Gf(A+a> z6OX|#T`u}vap7;(Zvi>W-NC&_Znze32mCek!Uc(*w%mx;bk6Ug0px>Nt zib>`!O~zxT$Dp=iW-dr91>e0q0VH8x zZ?#M<13*+g0wDcK@DSgF#PYa)99OnNtpL1*yx#$s{{ZAmP`6)(_(qhysr1+f+Dhb; zZwqi0_|}H_NM}9zyuKunt_OHVAjzOgz5UBZsZoHDuPsTG0Vv0^h!t=Nkl`y=<$$fP zE=jOVW^X~P+yS0Da4hvWq4Y*|BY^pT1Q4gdvk{4#BH<&w2DFyguRRFhIm`MS={BAK zsCRHFUeXWf1HSP9zB8I-F@F`3*w?P~jQAM<(q+9>iMent`u0!Y{3NI~m))U8#qrKP z0J$U%%CT=rVn6s3(8BF|0f4dD2|)fq;G2&1<8?S53)uDu_P){io4an9sg&DN-Y( z6`PkNlCWp>*aeA)0L)LFyC6}AKJp73AArPoo>ls=dKkcb8bg0=MLcgnT7k43{F{-O zzZB*D4ZuBa`Jb`Z0*&Qxok>^=sCw3}+p!)KTNSb~V)?wKHEknbxf@{xNqlT6rpbh|}_Pt5T`r3-;M3(`$=SpHf)@#V( z#1*0P=CvHJIL@&=#z%M!O5a8S$4AoV-hlNd)<`#kk@j(2+o|Fg>K6c(r`rzu9VsJM zdAw#so+QSe@=fy-Kf*B;&>wHN{IU8mpws$bKf(Q<>MZg?~d*HfTT=ITfTcoU}J0OqsHGxVA9fckhBgV4q5i{MXlEL0Q6mq{6L=>U#PDk1p$4mKCU0!cy!O>_Py8C_em2| zzXJg*hq{)6J{QMv$*G^ocVjb|3f4~UzznuYjIHu^m4dO!hNy`W2Bh9$u%5mJz2f6g+ zlVM&ehrXT3?aUsLFZizU;obn!wn1O7!iDjw6t0uPzmI_?{#{&fk~#?>{_V1HQQB`( zp5R>d<(M9Z8nk2hJeORUC+awtoU5}2HkcJ=? zAgzZFW+8P!+O%X&q84cY(ssyqLOJVzC-WF-^CHM14M8eET93Ut_jX&3uT4B~R&C;c z5Lkh}0~P!0I^<18>V&lUxZ1=rq#;NJNb3jHCT1aZLD~fQ?ck{e9>C)>YZL2`CL?u1 z+KlTi%aFKcSvd>)pMkXr{u(>bcdj}YFbjEIkTxBQvXBNKZ9fKOAx%c=gtQs5%aGQC zZwPP!j|adOq%KICaLuF^X#mn;fVr4|IR`Ia=RvmL`^(+4^ZEIFy73o!febfo2I{3n40W?VK&w!uQm!c|x?^kHEv zgn&UZjuqwuv3aqPhJs&}EA?3E3+nxw6y8g3K(IZnu08a@K6^JFrjw<8qlo>ViSf@h z5TcuE0`Rb7kc z!6F5R+D+ChY`2GPy9rG&vIy1t9e1t%ppQBI=Kr(JB$;+wnZziCwj)TpnX~%%FYXoH zyV`CY)9uDMB&4eOSq0s0N8?lqE>c@!Y9BRE&J73KUntQW?6byU=|1~G;XJ%W1att~ ze&%(5SG9L4g>I`s@TsS^s{Ux(HkMGYz=@EFCbJ)$GjN~2O10~+aP`L=gIJFs?iCZx zLHiNTwRodBRR>z1A8#>Vc|wr3SYywhvG_xa%Nh89ZWa%-c&5eNgA?wx_yvnUv$(?U zu#T|!Op7nEc!kBkw)i!RcUW9$>(STZD%}df*aLD5p9y&*}2A$F+@Y)E$ z+MYx|(<#lsf(eE}OXDnLgS2vF?P(-0j}i>S%A`ICmmp7E7C*>faBS$Hdd2vh zoQ&4#6`Cw9?M(l7tk5=Ce{rZ(%b-)F z5U^RxgFcW7IIw`~q~4Cti#=|X>B;{}8xB9VG{HQ@V*Myft~bOBK}?z9&_UdotT)4~ zVmBO4wZj5$bQ4Axgiml8SYWaEd7V9f%HlUH{-?#|ww(PfKH6dvH!5k^OrWIWW?4TW zlRHgrnI^}>7Q4d|n;lg(uw6$>#bYgjU5{*WSFcA%0g`!soF z5@&!^HJ1Wua=_g-Os-4f43Mhk;y%qC*xf!%4hrcICYPrN-+jVlmBbk!Rn2=K5oI3~ zCTs2_C`n!{Omhb+56K{t6OgJt6#p~0DUqtK${;6k21r$R!~ZmQP|NONa$xsiVRFFD zM^@5>1a|idlLNbt2$NSPaRx|LABq3zLIUpIVRFFD86bk2%jF0%S9fW0P)IUN4pg%B z(%eZh0aDfd@jp!txCeyE0r$W#S#u{@$Z;8DkO-;jzpCI_`VJxmS^JR^&o1SNS^m>d)`GE5E%IXg@axX%fbX`o3p zVX`g+St>auOb!YeA5DG_BVM}l0rx+`WL-AIQ`IAGf9k?CH_3HKDtT9G{-tShP{=#C z&bo0BjOIuOb-~6SmnBq0St8Kr@dCg}@21C%} z(SJ<|D>E3_$xTW#_)A;)wt4>ImyMsV2f6bBXHo)ZJ;Jx-;+HXI4_--iCQwuU*Zsdy z$@|4m7H??Tw&>!55d}R9S{D4H!NvwBHM*i~MoC5dkcx&C6-}EpikG!4s8KOKL=@j) zO*+%!xW4~iq(1G)wL53~c}O*JJb!07i29dK{%Pnm$01ioy9P1!E*N9#J^kOv@Hz1q zo@L?NVQ0OEL7mMDfith$GLDh%EZ(3Ncxp8x-8-4lfDF&pF-k$$9Syx zmYVXgBn+gHY2X991kzGSg*Y<#t|Xq5)O7*UAd;k~kV^3kBagFn;=w6c6o5#QmO^Tb zcfXi?S7#w|nFRRkgg^=hd>F>$yOMlh-99jnBl9LreSm){Bt8Ld@&n2Kpk@13tj*_J zBkB6~9h6qG(bSAO`7R#Uw?>kFV-gUZJWnCa`KAtUK}$koYrM@4(cjXqcBc1XI>XLRxx750Z5+F)1bmyk61L3x(SjVC7Gl`KUrlYp!93+OcYt|T9MViIs;h(D1q`K}~?P{<_UO74velkZA0F2m1G z9VJBor;zqTGWo6~&eL!0!lC{(7qP%0I3Q1W1T((nyEvExTx-9B43qEbr*(6TALV2X%#D=-+nE}lw=gRvxAY8 zRuOJD`YMp&wu+IIR>>u4fBS{(Ao>R3Z1?JEB;9(7hiF3zDXN}E(ygc4KUtDnPb2Bp za~?PaQaIQTi9Ff$WMrA>(%EW_2^f8n!v8~%On%@Yj!nDgAtUK}Na{&?3Mp!xU?g1+ z(IWyW9Pn4ou7`}|?s&*Zx*l?)FSm!Je~N{!WH)5E{nO|yMh=s}-Ed8bnGUpvI3t;S zw^d4z!z2*y*(neYM>6@YWGQl(1YB#Ykzw*($(^ke`a{xPCzyJ=>jbww*^AwEf{}FB z32wym=WXsf!AQdTjCF!5IVzp+*3(@lxRMhf>8=xuPIsN)N=}2MyG}5YY;@c3I0|M# z9;cAzAensET6dk`M#3eKH0uag(p@LGl2<{}T_+f8ceYMg0!eqBU?e#znsopU0INc^ zPT`z80F&=p%RbK};KtDRkzw*($=1kW5^y8_r^qn*t|Whs#U!vQB$@(|`!bX7N>(73 zNx-%C7G#)wSCV^LCV}ueAq67$D<*Yz9lDNSA1(E#kWQ-7;p3W z)<}wPUCDgDHInoplRzgq08Sw_Ml$(0ve)~Jr1%yL8YB{Ul0xc$z5iR3%jJj(7W1v+O3=7%Nu zll9%Jr;*H6PijdaaTVp((@5s3Cj_)4*ClQ}jU?;9B=wZI1xZVCre}V3JtY!EQreTe zDWs?o%;=O}CX#o@SU3Cwq>!R|nUUlQlu0CAot!(FpKYzIQbp3$$=S$Vr5c^3$YIJQ z+0N!?>nuYK(=sH2Yc2PJ%+Ho=2pW?}y4F_O{A@{CrHW)YZXu-O)?KCYoeDwRPA3~c ztYy2TkfQphk(9Wd2`++2lAc0}>YqkZ;#PF(T}LPqqT<#_7NA@vk?etEffNp!ATdAe zAtNbqJ45H<3U{bylf<6wj$mhl9(c&CVS{?+^N^7g54n>0JY*!rL#`w(O(8{j$ViHZ za!E$@Y$GWi$|czndZRrgJv*0V1ti_IiP0%NTO^}e#qHVr{c6xEIMGmLalTeDlF}+x zAS-U8?p+y4X%&%NRcVe$Pa*L;emo9GpOKVS(V6&nHwfWB-sqIMOgLR@ISaaTnUR#aOeEbH;=YVL;Z~`^+3rQc04>ScoJnAw z99TRI*yOWS;IX|nb-1xZO^41Mwzj{g{oM9Pw=Zb_`*us)oz|{>yEhVdB&OnvT3@uS zYrCNBkhaa+zF6^-ig6VORcvc>UzE7h?#t%21-}v~(<&9rxw4%|NMh7(dpy9fP7dK2cENb|4*|lXO%JwRI ztMty&>7_kOx0gIxvasaDl9nYe7q2Wnw|M2E!UuG7zq?*ICwLS2y0&P+g<@^zvs@OD`tG5%h+ z?~xapU@c=`Wnzx&=RfUX;%H)KkCjRE_iCI1^s82q`mmnb5M}FC=HM`crEcFG9A;3=#nCOpjwmhNGdOel@gWRO-dP`tV!uj$#P}V~el*(Ku~ zWnUak<`kG=pyB3h96`Q4n!F~Oe0MbY*U{v6qRAgdlRt_kV`!q?deAxyEH*?qp+pQg z!TuIYK$uA=Z8yI;p^(Jg=>`o(3*B6^i!+<+vYgEoG*x{z7nfX2tOhUs zgqtg9s`_g#w;%tB?ErYS(BQW%e$kw&FD>4SF$m~w@tGE1Wbw@wKX36D7PpHVxd9fR zZ}CElxveJ1i^+G`^UgL7PPX`Ri*K>`QH%d#aha`0SBvE%Lf^ON>nx5Om-ba-@bR4q zNK^57ojfd4ae;aUhOkJM4!V>a@*VL4)QMU;Qnn*LP~ z2g3yTXEZJtPt4_|{VgLaG0SykGF_1lS&fkjGWSP2T?jQZcIMO>P?EDw-QX2d<;huI zi>%}RA%Q%ha&U-k3S2T3M&t;YL%@0g96QQZXA-Q<8G`$PnX@N@klu^5v7-*6xw)E& z*(QJ@r4LMJ&%_bcOpjKxpJtp2d-6Eqa5WpoPC^Z5!`w+a&RDxi2&PG(%!n@gKKCK|#ESguthC*-&JuU)CTDZ)d`A^=xeL24zd?MS;iz0r1#D!Z z158yI<-v{uaV|JlEn{i_5jwgOOz)L}5T9JyqQ)gGP0!>H{)p zhVP&Zn&CS*f>xD5GqSxhXevn^{ARCf3%@lK(2R~T5wx)pw22usqnF<*a?86of;KOL zwkm>ldjxGw1dVsEUA@0f(^!8~w|CMs+G}VZrfJEf(6*&%0pCZU?PD0QD8o0ac>z%Z zI(kGQM=(WHMywk+=KMPxdQ@_+&m27bDK-19z&f$g7%Md}XZ7))ol8=%Zb*+x$@;J< ztWz3MX!+L-X}fgjoSDgSm$^=#L&-E&31EE?S5 z;&yMfUexgA(%a%+HUDYxWySO3|6A0icuYJQ-z&a7c0_TDR{dH$Qe0#1|6i#)Fsdfk zEZbJ73V!W5>I>0hae-k9cu!F$t05YjZ$?6Ie* z^Yvc4s~U(io^#&~v*NVG!oW%%M4R=~uidPvxHK>TyM11&;Uy$(p1rWA4b11YyZ3;3 zCqk`Umlz8(c+3koGvU#b_0AyO$>LU{yHpp`Dy~ff|oiaR3tc9#jg0x z^&|w(O#Gh;&S8+64NhLOL&xK0OCVpx{`@Vh*fFT`By`j9=(0|=?f?B2Ry(sb|BXtUC+bZQpIAv8J$J16nk${z zIs^5DISu_!j&uw0imyPv7JBF#HP(!L6A(_*Fi>z98JjWNXw$jw5XfixufGMRpMpwo zJe-Z{Xye0+rF=p1+i!vK1JKR6-kO1Sn66uc^S`bJFT4wwY8+*kZ-UM8?I^5a2C8H5 zwx?6E6dSIETZh+vrVtSlY=rOM13r)`h|`n1iWzF7Y}ZyZ@|kI=Hn5m0_?tC**H$&H z!)wNT-u}%V@OI|V6J8{A%~*Hu+LD2h);hd~%xC`By(r79T6ipN9bPx)GjUI>$}`Q# z^l)Zg)L5!L8eT)@GdHU5w#n|h{cOh$&X7F93t^qLr6+mTbNn+ubwTY$R z8=Jvbr|JOY`w>8?#~)AKQk!@Zd>4Th*f&~@20&Ex04yK6C{aFOQKIVPMTrY7-;kr% zsBvX~QGWq+LEbvRMGdB@67Y;bnjPXBQMO*K2dw^MZQ?xu_W>*`g)}R~*S~D8nhV(a zhuXv;0AwkawegkO#LNu7ch$RqJ}B?k0P=15b8TWHc&CK;PAENDoeW?-3IOE013aH2 zO%Cx5DLqgf2|X7FuP8v*PbR|CF^ZEZxJ2f#ZbgRi}64**FW2PkQOsv^%eq|-9^ z=BxPtUZVdKfc)e+VBn&}@C?5F)&2nH&j2ipO>RV<8l+(vd_&bx07sre0N1YMNglH( zF*Jkk5%mawdY1u)o&ud;)Fzg*%#3)xS=|f(oB9kuT-gtP?!PF3CmXb%Yc9J(jfx+s zjs#3TYf)kvpg&;as@lX{=M)j6A&o*-C6dwqbMxvj)oj4zyG`6xt;~!$u&F+fsRSg4EJ|#_aYxW9k;;F+M*X(K zm+DJEpT?#?Q2zG#?P@RNmuxh@PJQ|ZOA>bh?l=MEoVX~#Uj_y8tyC*OSiTp2XIfx? z#}8Ju;`>VyNkI8YixO*ZUXHt7SJcfLCyj!qyei@+rDYOmd?2nPh zayQOgqkhw-r{a9Xayho@cny{76q9wzIgMp*d7?J)7vu)^?yL3%<2$j z{7(H2(5ZRQ52DKAeI*p11uFpMnCq(0N7!LmuCe#RIDJohWuZJ^sj-)HU=MV$xcwz{ zxX{V4m+`|kXPNAKe4ABZ?;Gk3K-k`>vS@D<+z&{?-sR}eoZAC?AC5l^puJMht>}OB zFCj_?>5Z(te*>^g_H~A2VDHiDXu$5;dp>}A(y$4A4{PB@Xj6rC5Z4B3BWO<|q5rE5 zz~dGt)YHId>qaYq36nu1ti|~{OXK+<$awG`@E-UEJ#cN)=bKbCd8Kie#)}&LzF~`o zBg;CLjVQgTWJ~d3#YYz%TR6So`UaoG2ga|9eWq&g1T{>H%dm8&wKJ~o^B1X4J9Yzw zV;1)^9QU|}5t!BTl3YWfumJPzAiD-J+)#_233AK#;=;>=_kj0+_kj0+_kj0+_kj0+ z_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_kj0+_rQOt2W|p9%=`Z_ zJgxnxJe9Pc^+rr}!O`T7*Wxvc=8iny>`{Zn=b{Cc{PAl2jK7>m;VOKiRlgNnKb>wl z_O`zwnf=uXv5$YMA1seSlX<&eR4KV=eAdW60g%f(p6)&1J>WgyJ>WgyJ>WgyJ>Wgy zJ>WgyJ>WgyJ>WgyJ>WgyJ>WgyJ>WgyJ>WgyJ>WgyJ>WgyJ@DV)ftOyY)A#>TSG*L3 z?-Pruo_KRB@f`hLmGuoyYj>DFSL%cYN_`KH3H$)(0#A;td{2&Z;c}FTx3D3_6yI^g zB*1sj2&8cEeI%2Qw;7d(C0iqhNq}!a5lGxS-(q0SQb1qrkbGCN z0=Y~AuC=!y!{ob?ZIQzy@D3bYqTix`_mzS8FX%M+t|VWV5`JaMJCG7dmbM*|CO?qm z+l2J%d9;SN$p)x0h)t_?7T|q2<|z+Xk{nDTDZV9l3W;*e*WZ4ytzvW{By^m(lBB1Q zO7S)!9%oAyfX3uXk~f6}8+CrRWFc~xa!K;zAk5E})Xe7-f3^qcXWk?kZ!0H=_m z;?_utZ$&^Nf#)eCe7!Quw`YPDcxWun2qG!Ay<<06jBK^@;F;kJmgA} zouDre2PUyr zd<&A6O&k_|y) z5=qzEN}Hc8$(Cjk$#C3)tmBsXVM)H5Hi+99IybO3U;i|c61TG*NzzkDQT@|MHb5?u z=;TMl!;ugbw?>jN$t03Ja4e9*K@%i5ZjGeG?JUb4<=6c6Q+jOy7&QaqGPlF!gadq{eAF3Ac=x@!}oQ+l>YMzxCD zv-w7@pjB|9K}N8Aacd-{RYX$yr?d)Z6&{Bp!AMH0h~%nDb3}RyiEr2Cakiwiiq6D8 zeiO2UO#w(Daik$nwxqO*&cwe}a-fnOQ#j@hz-<*{t+a{=NIiL;LgH-iw#q2bvVAL( z`Fv|6UEk^*z(!Lu>g4?C`qoHh`8El53n^gM)Ag;9Wa&nOVHaz8mO|qAZt{bbv5|Cr ztH+^GtFV{3zBQ7rZ;t|}Kne#OhoXHe5ii`UMoR1(3U^m-#2cM5mx-inEoVV@E;Euc zmx-hsL)@2INQBQI8IA)eq<7m{>k$c(yx$Ae$XnzK-)c?M$(Nwi3HM9NKrGA zk#wU^Bq5|FqsCh!$;e_7SYw(%pQiAi;bijNdb-i)>a2jI8+}Hn8-4S@DUiZJdn7md zjHDZVu4E@jy3uDO-RN^AyFk*7zEeTlz4kPcZhO9yq7Jj4$Dtl?-O>UC*7xEu+tkTcgvB+jn3=iJcv&m}9&fx2J=i?OTbyd^3`f z%;j6^OChnIZVVYo*SD*{X#kr-K$LHXf}U;dDu$NMkyhEUgO-P*&q%t~y7MPJ%yOJDl-H11mZp4RuOPkrg zZp0f&cg3i$M1)3@10d%S{{b2coRnx=wFU;Ko_v(j{l&c>`4qvR31KO3pM?%+F4P^`d1*2lDW#^cgcpLj1fq*sRrc)ar(S^ z9uU?X<+oXorQcEn9MdL#WQ{Zvr~4N1+Z!y0-|rxP5W-j{1Y2--9E+iT7*OwSbl{AZ`%zq%UT?%*HSnr>-wTa(F6 zx;Oc}@xzVhH$J{`dE*xvt!Ol+(E*J>PE-xBTR93XH@Vde;+SavQ&~`}M=51fB_({dM zii0Y)wYjg&rEP|`Y~6BmioZ%Q z)2vgo_siFoUs&F!JYN1})5_L=ZMC}9j8?r`ebsV9%f&6*w|gUTM`CKCM`C2*K85cV z+*L5E;K%}1@I-^!2E!UuGw&HV^qZ@w3=b9 z!%_WHbvW>)Wy@Ri(C4_jj&A*3q!OG9w0L3WS#q2U>o1a`O;D&w2nJ0^nI}5fS*)CzNnWNkTV zpLUNZk2Ke2p^+~3ktXH4G_i+z}c zP0FM!X>u-lNt5zLFDC>kOZZ50Wl3}GJ2FBxOcNcXx#f|@@`O&CNn?G5PFioAyY`VL za$+-Su6?AjJf<+8I}VZ09f$f@8PQE!NOSd)=ISNQ)f@IR%V2q=(H1FFXi{F7&mL=D z@^LXLwn^Pcld^=ydbxb0Me&K=u&i4T%DVm&--#~T*FHioY1GT|ZGALfsijfB$a2?6 z9-(nF=+=WYx4fzdKGMi1ywuS(f{!$p?~n*S(p^^9VlDT>HX&qL(z3o93ks(ijJ{L-<(Sm2onxgEZEcG?Cp0$6S|$Wl58|Nj*q&^~yRsEGumrrqM6BP?VvU zG%1hc59>j{2uNOSd)7Do!};JQ=R zbyA+JMZ@KhCVHhFq)8lz&7_H5v6(c{%h+Z;xaJaB(JO1Su-@(wd=T=1K4N*IgEX;O{7jn2iVn7~%SRpJ7x4jUO_8Xh4HErAS`$lS zJPA$8<9>&7v*P(A@M!iT*ep9yNr$Az+#K&AkD1@V^_)(KGMV%sV{vcHcQ<&u1W0LSOX>K zN31t(ISrWQ@jOhU-SD(ZXjz0cX_oPFNUBquMj0}&EPAV7d1 zgd~IzLckCKd7BUt2+BJN4{K#>sZT0cX?P3r{T57Qud$~p} zZP8MTO5y&#^WDESvwmx>bLQ-D`{(w*=X_?LwPxn~o0;GI<~P52thF=@`dM{`>R5!S zZc!b3c!1M%2t&T0rRi45wPH0L!Zc4!hp|BQv!+9sV#9P=2OWDb2UB{AMVO{jEW)&W ziaj+*r&xq3KNY*bgy|Ts=@6#83e#!6ng_;m%~!Fgm!{J&@L6pd#Uf18=~%W(!jzt- zJ3L6IVX#Xyo#ufutBs`e5T<noj+P_M6v}>c|UCTx*UC(ts z)%j@W1Dy}_-qrbN@2#Cr_1@UIt@Fd(x5!TTGu6kd&kt8e?(SMPaLT|JyUyr*tn2vB z3kPoRTG;u*$kW4j4c$I`&A?b^sq^-}XFHzkSUmhl$LBik?09#_s^MK7TRP4f-ZA`8 z|7jh|I~H^db-Y;lLFJ6zCn|64`$}b7?|qfN?iZ@dx@+AZuG~_&rgCBBl*)zOr*to? z+|ggF^i}Tdf1&-E_7}T<(EUXBSGw=({_wzk1CRGV(|^n83;lfqkGFqi;GyB#Xzj|`qP^0~p%(4B+N4qh|5aOmBGV?(iGjQO-a344`*Xb~wO9JS*tfKOPJ6Ze`L^-Cr`sND`(oRi z{=3_j_TS!iQvX}q&h6jPc18bLZT0?DZ4XuNt=>_sS8wdSwRdsbUA^ONmA2=~b4DH? zxqJAja^L7#eGd#hI`q`gb3>Kkg}ul3jt}qXd$jyO`H`N__1xL>?w(ye&v!lDbyxY; z@{Q$fbcdE zs!OYLs@3WjE%Fp(yYg zDgNaG&62?2wqk|+R7*1)_vF%94ERr{mAFDkTq>N{CI6L`>s%7ldBFntk)+NcK(84> zBEA6$L<2^({CZ*AcB#PilJ_NYwORgC5=aO|k0P|%@&96}#BRAlJCFbxGm5}kDaCf- z!zJ=C{BCJZHs&d=meG7zUD_dSag|iz3L%D4kO24*#mLnHy>K~*5w_unr+ z5K=f4O|M-*gT&f|#EnvtOBxJa?~+V`p_U&c0EX@pKS%~;k8Bs)up|)8P$-*AM9e)q zNdWAOlFu~_0+-5v$OnXrB*6SA64^dN0$oDjv!9h8a21bOf-SiAj#9BwioeT=6@{B{ z$WKbupmpbnS%wVOHKWLE5VeO<1dV&O(-_-? zFb5=Z1}1G3sr6Elizgr?aunA>r{@xa@O#0B5g#ddoY{s)xw5B%Di%nPANR< zyVZ?qc?*%<0W0=V79x5U_>yNQk`yfLsDW&4gSi;cF}&X-z>7*XdE}#3I;eD}_?qjw zwbBKp8(loa)TcOGQY@0cn#ApJ0$h{h-d9V}-XwR>qi8$|_jL}xP$+?M7s;o=4wBD+ zT`Xx~)~s)|5K^7xN^_ZLA1DmXVY{S58`eZDYw{mD3VF|3Dw{23Dfo2vD`TISGv$Se zHU*7cQYy&6F3I&0r%OQRhM>$SS6&VOGkI{faBG{CZkN=qNgmAbJUB|~47>9x8I&v! zmO9S$-65B(heRE3E5lL@v;_mr7kV=fee)pU;sp^?W6B0=4{{jxH^GMRNkR{G5&`9VM^F zYo=Ct5`Tv4^_*~^H|Mu)y58xwJp2_b%}JTkTq6>Qc1LgC+|V^>ch8%2X^s&2TPAWi zb^g54I$^4P2PF^d6>3>X_|*GLQ7;9D&`XPQYfh4jbE8%$%B`8U%9m1Tpu=6witBc` zXoOcb$EA%ti|Tij#5bpfia82dnW&CSCC68`6`5mkp3V2W;vn}EaMzUI#@9r!JX{`8*`4w z&lkLox{FF3OWTkK(#-W~{>bH#Ka#^WrUU!#4=P!Dn1@{@7OdKN3*FeYRqkPhULDvaEc--u z1uS7$x+)W)U9m#=0q%#|xEcL{(WNM#aCB7*d|{G$v(%Fd)OLhIsZhRyq}GraSkT^v z*W6<8ut8xR!1}HUC0N^-1;C<&9ZqXc`BJ23(_CuKEv zMFM@>O^pYaxFuuEowOuV;UM}9Blk5}=f<48S7MzL9SCW^L|#Su3`Ko3*&} z^C_M~Ok^=ovzJw81@p1noX$9m*+$Gmx=Xycl!)Y3XHZV#3P zziym>4h`mcdF9EDGvv)~(I!`kJQmO8FGzF}XZFw%+uXJZ=bqH3l%}9O!MJx$4u7t9 zQmE3rP{yI7nh7v;#P+8aBC3ztcGX?Nu7lx0pzouqnM4eYX4j()*=9_G%y zrT5t07kWP1^QNBpJ>TxWt^2g@j_$8icUBLs{?D!tcb(HU)b-8ITRYcvRy+T^*CR^C!Ms`8We-)(&;?}Vue!O<6rvvQ+i$WA1l!~=EPmWsO94|(jMrM zsZ*@(`#`LAY2BjmU@9hLr^g1N8Lg0SYpFD`(oLuWv5TrmAr7rD?hBt3K1iYf*#y0u~BWmTA1jURzcu!M;*N>YK?!T}@w8x&%Xbwr-W5Gv>)p!-dz%@s$m$0HO<)@wgFK z7FBd#X9A;{g*wAp(K-_jmNijlg2AxJcJ@}HuQOP-Y?=JXJBs9&N(c4vPPe7P;novC zKa0vA{fuM12cw@wfyp=y&mN8*7S&)IgzK<4A?L8EVP&V=U?2J$+X2S_njSPr0!IO& zNURmD2eTzTXpjgF0z~m-g%G$@II=6~0XPH@1wPJ+@tYm=NC8o9BAYU;ZwQa>LKwEU zN&PRDEkr$ML=sJF9>UX_N30Ro3!oDcr|MdlS0IT5qwhr4KHUomk3LPaQdDL*(h!br z)MO_n0d%CO;-@ni$6f-V*AX)1slu+h4=b(qNSdQocWksqR5ggqM z*1ACii^<{SfkdJQ5*+QpXoPhI>{-GFghC;i=w7i>_<#cySPJrR^n|FhQ>$f6#_Bru z>^TzPNrWkgah^UViD-dV5)f-u=_Jv#N+*0D#F_;5NvugCTCCS)gbF)LOWZ5+_}oyG zlFgFA^0Us(GFA%O8glO)2f0noR>IUmXGdF|jJ{b0plgD1MfaI(xsG&Xa8!Q^;^s|n z0wH8g*vN`Me=qQQds4G~T67 zZ}OZr&+f4d(bmICY58m!AOVq8!0AEGRecqr_2n9Ya+TOm^;v-_=t^w#VXn@uMR>H; zfcg{8E=4$O27fM3dQb7dizPrT0sGp+;3imPF?s9*a+x@teyO#NlZu|efTVK-hC~+d z)CzLPwRa@2)+u=$N#&Tuhfi1qoU~1KqM|C`Nde9ousZ8YAz1`GXq3V&=q1HqDb|S` z!h+r5rh=Hyaq)-c7>*?qmLnuEA_OAM5X>NMbe;Js8FqYCMukL_PFO7sd6f`AC3rHP zmB5MGC<5q{h7B*s&^SCWm9uH;72%F^iq@3lfJ(+I`?Z z;mEKF1`-VJH`REA?*soyU?2Fu1iW+oK2-s*K2Q4mU``;|7B!Ttla}8pf{XPW>;S3w zk_;FaMTSoc@%Sr`H$wtQ1m%q)lATME0N6;?E+b^}JYmY#VjqNEz->X~eyqTnVj+P} z^7ev+aABeWWsNWnObn+UB;k5LNYurH1OjmF9SgqF={`L2#Sw{cFfM9DS|fug4uXfP zDI@{bMF~)r_cXermn5=QDb_-DSr{*J;iJ`2M%L+4p{wM~DW>Lll3=s^US4`jW56dd z;T)f2!v!3etJf}|u_>@t$Z&eNS=tB>9ziNNkC4bSj@+c zt`MGJi{Fw#>7&SObX>t?ovW`rJz~j0cB06wX&hPygTZvqn`qfdo8#n4v^~AjnL#)} zMbRf5mULwC^@%0R0qBRQrrqGo56Hz$(kfWq_79M*D`!ERHfU zWjUUT+`jLAG0-9BiQV#f6UVn=TO4R{pv8d}2U;9xaiGP476)1!XmOy$ffff^9B6T% z#eo(FS{!I`pv8d}2U;9xaiGP476)1!XmOy$ffff^9Qd!yfxV?KmmbFce_4+9$n*bv z&p%JOl}jhN=l|c>KWhXhHLwd`6OU*Ad2&N8#65k(iqG+?_!sAYPIb|s5_Q_cKKD#` z^tq^&a-az>m(*ibgyXD9)Cm_H?*csi3^a*M;S>~~1k08q`Vg72?+?OpEFTcq0fObH}UrcqE@Bq8W$xKl5$-X#&ve@cb-Gfg_ethZ^xvAdyg{HGw4-=|msh7>54Ks#gM-rH;banx?kgK|h$@Ro z3f$o-d?8x>N@*Sf_=pxR;N(PWy3RXm!csK z=q%7aRN(|8yVO%XPL{xx#F4QpT}%0IL=m2dVils;_`npdy(1i-(}7{hPd->O5W%P( zcbp>^%Lg~~wWRD~{m;F&^~_e2FrKx(2)FMTn?_C)uA;pYi_3JmvlBY|LV6hH7h zhkp``;6!7n#&Z< z1TwZ#5dpkI%|ByAaK=U|0^=<{cm837J%V#wzh(w=1jF^3Au6umI;|o+0^`fjE6JkzW8T~QSPDGS9YrGl zMNAuAK~e1#D-n>#N-yyQqRP%f2Q%Oxw0i9V8cc-HYV#4AQ65O1m#1w$!jUpcY(v2z z6cQiBGRt+8P>RU<6|u<92`_G-!tq#?n(N)5kvIxV`l%p-_hBp~0d&!*_Qg!ZzG(8? zd;Z7uREkYn-y{H0i6XF8IxEaNOdkA`t|S7krCJ@V$;=2v4Q`T$HTiZ|OtA6XExxaT zVIG5-x)lEMu2XlU*Pj)+$uz; z(3y1UHT@bo503fb0umlYB3&Aafp!*>ik9)!nchYM(Gs1t zRJKSpN+l3*hBe;qT7A5rrIRlm^B_)0hrI>B9U$ zcL+&xeGA<^N`_mDmE}^ldCA0Rh2L7NbaL!|Xl=C?EAxlj)?%eB2J%Y)FbTQ(>4ufP zkRBQGRE?&s6-rfWv9g)P%Daay9@=l{yMw_ga3Qr-hnFzmJa-T|8YGpc0bs? zwR^bx;p)}Z1=YXodVklZuD-56?fm`ztNUyH-|Ty5-#a>2cK*EMOC9x&V>@1`{I|-= zzL$FcsQ0bCt9yUm^I*^0dj4kk&f$xO_aFY@(5}icl^5FoxV_%Kvi+xRf6#VS+hJ|b zl|Ng)w0uDM?@OO3ZIS(dX<^y_=RW@u`Dhf(kd1Et|G}OEW*qD8OQr2%LA@*^DUx?e z!^0i@qsO1%Rq-zbif~}hV68|&e%gA zfcc=?KzXJ_dLDa$V@Gs-{W1fA(Y0OaK7QffH%oYQeOJreN2i`#j3xopI?7gF;igY` z%^F&n;3>@B)hbq=lK}LNU#Sv#Lw&$Y@BC4BDtR*Ox6}4ue&FUlACx zQRP@6FBGDw@4@Niwh1c1*$P_W`XKM<$ynA%V*Rny7Fl@Ae)UTa1SjuJRH-jApz*Rl z>?83*KB)bLu92c8f3?`&S4$K6!#X4o-2;wu7B_{LP)LibIcR8?#kF@7pLDYk49Rcu z)nX*zrgfphC}Lgu9q$*p!bP)foiGfqDZ-v{_>wh}iDurK2J=8fJ26Q_s}QVSu_V~y z(2h(ZU}jVw%nC6HM5_`k_M#G4^uEL?HOL}~K%GRD0z~lQ$vh%ZCvGk{^&Y{u-=Jxu zRH{AuMtF3S`k{nCG^AU#ugL`*0&2KO9DBohnXc||dcc0Pg@n+Uu3O=vDi{#LwRhUB zbg2q$KrkB8m145*tw0}O&j5SeS37-30@00_6{XFtfYDvcGmt=VK3Ey4M6P5LoN#}Y zD+HOQ*9@AB`y>?Im9V6NRb=}`5RySVc-`1&MAXnbmIp6`#p_3PQF@2;4Kydopf#d) z6!JG=NCaKV$%KCS2j$RfmPZ9j-*fFtkc`a$sWj$QB>yWwECI&oD5=ETg?9&EBHH4L z*MvwBh;lX|QUpV!q7=zGv5VBG340{TL<`iKfQ+hll1MuBm=p;P_0nq>kQ~?uZSpNH zY9Bf@2|#?JWYF$vL5N5KLKHYi%G6#4 zspCqgxB{Og;sOx7E5QC|e`xR(;3CQF0~bjEMNf@RC}tiP*NDZ8eeLkT8cBcy_uL~t zM*!M*_dl+^V?(TMkl;LC-?2<0=w$~SAU~4S5dj$2-jT@q1`*Ea(Xx;*v@8itxq&YF z)1ZNl7djW*^ghW7oQ*1wUz77-a5ai0Ja)FL^`Qhb2up|tNeLD>uu8ml6s)sdzv1zSVu2!2 z^r@(4m)57a7)}gH2=lrqaXF_Uncx<9c%A&mqQ&MQ17B%KMU*Lib^uqg$H5NBAHQ+r ziDK?|$RYC6Q`#TpcD*R?IOyfBO|dS6Pcop4e%Twn1>8j!#`lkq5k4l*K18N~W>iLc zU2~1P->SlD4JC8UHv@?3e6P z-K0n>?2OC~8t+o6F?wg%QeF_m_>Rjmwub2}q0?#VQXIrejmvIhMhL)G|1|=VlinUj z4lRH$t>ud_%pDwpQc>{i!N;SbS_IFX6$wBw`H@)i7p2P2Aq~xnhdr`or=c@N1LX(P z?O&-hee9c~?;kyVv~zUx*sqS9GSW5jmEng+ZXP~i_+N)UH?&<&0sQsgZw_u692ori z!0iK@1_lQHvj469NA*9~cYog%eTVfu+qw~X#_fiWP*``ZZ zg0!f+_2^~)sMkgRAqJp9?HHwl?Sd5H7^YIwTl8x*k9Qom{1QHa7?PuaFm(NsWdtJw zzsMjQ0yU@T@!vV->aAp7V+^%XIcK*mm^+45zhK|U9gOf!a}S3nf-xjT<<9jHd{2^( zf%*zy*i21Ai*#w;Dl1EYK{AR&{wnKnuBOPgDbXRk3DF@iT69*5;DnFH6As~tYyq5| z$4UrH84mp<5iLR+1-@Gp8LSM9QaH?TiCn1-Npgump=i2slGlmS-{2t_0_CL9Nr4C+ z*n?~DD2?ETPDvn4$GZg4jkvaPpg^q|KI={*(M`FsVFYXa36E}29F;_arXSQNk?3Y! z-KdB^U_kX#Bv-PrkR4TnBLpT~SwQ&WeVF3WdxK;v27k{RVlTW zZOqa}PgOt)XH$wvMNdK2ONn-iosC&&TDh=H(UXgbzfDGBA`$!YZL*b4wjgLx4A0Y4 zB(cw$ie#cS)kdckiiMTr_DNrnM6|w2kLLtKJ4G?J^-VprJcQXhDm(1lV#lQlZetJXu zf_YGrSiDkT)^{1qTZWt3SbK$-HEi_a9h4=)|S$<)oV^mDn~afuO&++2wvNqmyp zSz;<1sHk3pyc%+N`9l#&D?!Ayep?)9aiGP476)1!XmOy$ffff^9B6T%#eo(FS{!I` z;J+>hItCu?zpej_{tpiH_CMUWvu|nNk9!~Jy|#D%-oNYlaLB9 zKm69A5;UR1{@-+$0xLsNYxDX#U4N)cw-a~Es=X(O1)bFE_^|qtcV=mWEG^-n`8K!Q ze}x?6@~`J(*|3lkMe6i~)D3cl&DQN1Vqj4eu`?55*oHv4boa%UZ(1zLO>VvFI=2Cf zH?isYVM`Fzjw<6uDHqS=OhgXvgp4A`$Dl5er|Ce>mTEkf3|{_vxjUCt#Icz|D)rJf zxzAmiJ3T`xd`&&YW0qi}4l!hjh3DZ&4816dSDP{=$;$30kwby}{ z{IeX_%L27mHuGaEa!$e*&txSTR*kPwg=&pbir8t`DrLhl5&tq>5{cd_SS@{ShY+y@ zqBpiyNlw6t@x++pjdQlU`5FX+U2s8Y>+@^i(Lrj9t&G7vUyof@%LeK zoh85)LKFKf&~+SI_o4ksWD4!i-Hh#`Jh_iS0@3ZiQdoGM2vHio51U5JA5su?zRSPJ zIy`JaB9MeABKQmk_H^*nRCr8@WTNFE{eowLAq!E>i5KBxM?ZW=G)dr~MHGqEt}XCx zY<+_|3BUr1lE;<81APY%6dmE%b8}C!O!gl4l_CdOIF3g|jczy;M6)byL$MS%8WBZi zjR-Q2Eqawt5;zhOrCPjDh5DI9a2z74H6}M&Nf5h(Q5BoWXeB8a)KR1+Hd;w6+L(?p zT1hh6sGi(tCBbOJdNQMxV64|VsnH61-d8gWTNrM)^HR!thsf0};+e*2MFWS*S{iVs-l$ul5F?^2sTVfRm0T|=K^?i` ze92Ajcb8C)F9lwqf~Q@!Cv}{qd5-x!es zvx#X0V#pn(tDKjnLAhW7b^3B$nOiQ{9iR)IfEx?t@$g#d5b?{zAMDx*@A#%=gcX;I zBX#Bka9=}EGP6p^h%((7KQxMv0<;d?Y7$>E3ng=Y`Zqa2W>Z%w!c&HuTWdLK8gAS zZPkn{EeqQo^m={UH$xALsQ6ol`obD*l3z|1fe-jK6@Dl9fInZ#k>#CkP7>+{XkXRj zS-pzB2~C8v)6gQ2c*rL;FXVoq;PDg%v_-%gtS76yPkZ&s%n_wY`s(yobJ_Fzs`S!7#L`EpURj2J8TT!D=6>T~ z&)|atR}IV^c)b5t`j_|rxbKsFo8%q;pYOf2cUte`J-^m-a!*&!quuZ7KB>E_`zzI7 zs=l`Ri>@zs?e1FM_3xcu=-l18yz>_wU+&o5v0uk`D<7?#UFocRseMQL?DlW8{Yu;M zZU0ohv%J3iV(IgxEy?r$J!MRvmpD7MES5ATc`N7K-;PI4B}&Y=Qt4jttHi5&-PbqVH@X zqoW@TYkgBqCOQ9!-&9LFS$pu{5|**0_pX#V7FX9~Og&WQuCk4T*Lz8~tCaM`+e!c- z_@)c)ftL?}taNiZym(0F_r!0NsT&?k?gAn+{&egQB;qvEtaJ@=n zX?dyevt4+AU7OH#22>j~aBu+SQR%qiiYt`PG7$jq23wx#O>>5jvY~@x2;lJn2OMDO z@L{^Jof(p%qx`|TF4nJHd*L&&Z1WwWlOVL%22GcVAt_pTJ2lq4xT5Lg7Oku_cor-y zPk1^kX)ms+VZ9pfH^Q6KdirJln=TLfQ@T71alx(+NgrJ6)<1aA40J^HK?m(RrGBv1 zt^VR|G+4XdR@(bT*C#?cQGEhi3vU(N) zD-8@cD9xJtlJY36j*L8qy`({FO`|lINMGH>eh$9uY2Q<-$^Xubt_wpFSx&D&2~O*! zbhw}yZ5;N^P(L^L>uDT`;X~U$6C5~ihr zLjvh?Fr!&+o9Pe?)kyd=j2IrG@mc)Ls^rGY* zFaNMeZ0>dy8yey<4u@i-B~(O@{bSek`9iL@jKC?tu3vne&EZ5 z{YjYM89GsYfo0;mauZ4~zii7C)h9>`mIz+*iBfHYtXf)8eIqOvc!lX%4y~v@qUE|q zY`}!pG*>Rj(aq(X#k$7oTiEB3Tj*+X^P`u`rISQRVIt8iLES(@ZJV~h8V=FCuE{^p zI3uCKEpC{}`r*Aaz4nZ45mHrpCkeCtX0?_{ZHh|jiG>i4Yfl4bez!FSJ*A;`c1Pn0 z28-ss(m2s=#c~Sf`K#sVEb+AH#57KFO^t0bp6Me$v>aU}9K$JcHHiR!SGk79;R#!h zYRN4<6%bJTiNa4k_CWa!+qm031yVpF;pgjwLf-L((sf!U1pYJY}f?&4uRT?NBFsh zj>QKeX-da1#0BTkI5JCvB@OjdSoWN9h{XpP!8oVoSm-hgX)vU)9AfcV8dw`m*M%X4 zG>&Fnnzl`ZFvy+9r43eYe(6>HL3hn{;IA z)}(E+*w(Fi+a%k5P1`0v`*fy$uMXRUb%brBc16}UnRx9GSk;$N>m;kiX47?vpK(qU z(g;@yDaSeMul$xNzosLJ(B>hHaHWtmFf&k>%&VwD@hQu1ed}AGftV@r!LA+2I-#W# z#S=e2!|cedhlOQnV(lm?hqg`B+7VtpN3LY>QR_u3lX2-`<%8zmnXwJS71f+JX}`yn z0VlqdMwD!>ck?D)SLWkw9h8xfR=BE7$!H5k%tm?EiE*g&CsJ}{f^|71IpJD+g4Oy& z$;JvXE+7@+z*FR{woX)ES>tB7m_%U4JYs278Z&Rur>iv9gK^j3!|9Fr4Aziw5>nT< zSFT*C^!BvvDcvQL(~iuVU>MS%$9{8#TmQ$(YomQoH|0%dW`5I|?Zazb`|w@Pm{c_A zY!2u|$qf1*pHc#+-CAi#BT80S7S6Rn^oi8uF1+!4_ zHpEBiHN4w9eA-FKTRP!NFLTe`525Vyk*5resQ!#S13z7Ke1(PL=fN)ba50j_albYB zg*}{}2TN^cKRfHbSy#+jIP002cg{R_=Ge@~$L|;)>VK^7*1nVa7EF73?9Q=s$HvAU zAANVuLL}d;#G5rQZ(r|F4mnVgJ8c#{bv4 z{r~6s?;Kv?!ukIH8L|WKI=zI!O|SmmL=!HT2K)bR*m$hXz6_aUAe>Q8 zWMz*LkO20!q6pa6o)V4){V4c3ZVntC+QyO)KW~HuBB(yk9jxz1J?pVv^b1asW7W%V z<$FRfDpHUA$i3M=6+5NIVBir9r&dHjBD=* zUY86kc=E;A1do zZd3xRx%w$0j0>I|I!CHZ;BsD>E|Tp{tOTN|A&7XT14I(va49M)x=s}F4Z>#Z#qwcy zG(9aqUruxvM@kzX<#aNJ|ITUq>B8=2sWum|JsEVCC^GoU8lUjsr_L@G>jQ6t#W>Fw z?4#;fyZ6M=d7_AK$|asHEe541{+%by0rdhc;om}ykGJ6*0Ie>*Nrgg$0gxpXHYQ!k zu~cH5BR6rf3jEw5RfUSC278T55#7OyzE4In$Tdp8POc|N5M4b*5T!-O^^TR}W2jif z!&`qLeP~~NPDA?$2?86{3~O`y0*Q1e5iCFH$2r5LD1CJ>p9A(^b5lDPaz;{60jXE> z%YA{yhXU}V((ivKF(`m2ViyR1LSj2z=fXQ(z`s1w=>Ad4^1PrwU}Aom>sr`8LStkZ z0A-MBVTfX03!j-oma|~e&hxTzkhJy}|V3P;^Kt z>C0HF(Qb%q??~!wHyy)aBmEd9)B~gwDgw#^9g;*l1nep|IZ=qTJ{d&=11m@%45KV0 z+Nngh$%U2_*WPKR^`%egCh+Bpwt&xe${rG@oMRa;l}huxlqZVb?JBJn6`DBDqB>m! z8&!iLf*};&)x)kL%@A@h8Qv%3;3gqN;U&L{nk4DZlM&>0K9quf*u_^d>ARCv@oWLB z2@6u;B!Hu@CyJh%QeJ4!JmtmLmhjbH=*6fu$SefFnLbgoq+K)G0l0a)UYAr`uC~Q z%&LEI?Vai$-75^u0GgWzxWo|oSKzY_B!=p_7fDF&&VfgI%@CGrjT=5WXHj_}2~;iB z%z))}!804`3MV|Ze}@~>U^+?SNK6#TjX5Nf#kSJ?mTPgK#eo(FS{!I`pv8d}2U;9x zaiGP476)1!_%FzT4-TF+I6C;Xfp-m@IM6=uaR0oaCkJon-@pI6a*AMO-;a7f(R*s| zzx8~k=gOWr^8WuzyZgJpT)nv3S^ZMiRb7j^p6q;A=PG&b|C1e?I-alGU)fsesC=RQ z+V*Ab|J3%mw#{v)5C44V4~O0~G}iX#<+qg&D*vE#Piaf?{Qt2sVa5J`uPnEe<;4q& zg)T+%Di9JLJbb5$*o7NOIY5x=eumQC(~2q9jRRMZm3qU~NEGK+@|3 zB!L%wa;F$eyMD{f^CEhMYNM=6VdWohGQ@T`RyncrnC1-DsiG=}tpmKU9q-P+NyuP3 z0q+IC*MND2tzql~;3+q4x#;y`yp|Niu%wH{T~FQjeAcjR25K5m^ z@WilA97POY0@HcJCp$_7hxAu3DRPah6 zk2O;4s-rjVmjC*k9#1PF-V=v-MlH&pBO-|}gWU-kMRp#>w$Y%8jd5sN@ zsPb-V5XMFj4k?27c_qzkZWM9%%nZSzGP>n#H<$=5l}L9lg{Pxn^p(?8O*( zLQ%(K2T@{^CWtK(_8Y&mz!KuwgD8S%-JK#N*GZ3onBz%A?1SMKJBz+?@CbtI?Y9T5 zi)-)Lx@QY~w}5dT1w*6XcFyWT?D<8N^K21iv@{56S(y!Y@xs21qp?v$&&eUWO-c=& zlOtus{ob+7*SeNcfG-+Lu0LI6tO63jRB!OWgiUbaPUF*~)IDx0U zxpn95IueXF6S1dGg3x)?c)n|q7{+1OwJ?0E;>;h))1^YglSH&3xIXDV=uD7vXgW_Q zdemK;5DLYRrNQVL#cod|6h0D(9!v2adTOt{&P!q#Kch-?foQL5q@}0>pa|LYu)?vA z%Y*;4qDVS=B!wxFPa1|0Hi$#A7)_%}%s0gIunI&LBYrs0q{*TOr^rH*Ggg(neCYJj z`BGWF=>}&h{Xt)lNIWFx@edxknEgCu4x-=YNih%K;pi9!FYIf3BEUpV8z!EEutca< zl;+7-UnCOEur*@DbACpNNmvASp@!XGJZK3y7j>L`qv#F1vWv!pvdSwWl5`AbhNj_xJ ziBHWwbP7$lHpO#Y86Xif+$$mnB!^atBFFC+&~QZGLzBTqg#yNbPB0=}QZ!nMwA|;e z3ltq6W(m>byQH0WxYFed6p3Q!bZ1O-odSH&YZ4~W^{J+SbmFWu zB$I?NfJTYSIStA5#y8AbOtgG=^<+_$sCnDj0bIo%Gh=_i&lAP)dWcw7@`&61D7Vwb z7%shIr7w4F3UfoBDbO=-9LCW0ehn)eg2@!njLHa)n5cO^wJb0&r?NmD^6GLykcH0l zF~Q)eJ+R4JuPi+V<|u)~`!I@1A1{g+uv6Ux13;cA;&l`;*@fqq!j|%afC+O{ma#QV zX9;CXlY|V#ggPoaJki3ll`3brhmFRup5#PEuht&S=$)}F@1EIX##QN+W35l0%6?kLj5<-SCQ-`!3(*-nSacNFoW zau<`v1U!;-C@=gN1`LH_ZetoAMf$uzQep^WLLNork9Q^hd_h zb+GyowmD2>&LiI3co2?SM%EjqUWch

aogkL=wjQZp6u^M!nrd9}J>>GJ)O06sNg{fdkU!NRk<8pcDxGVYYz)fb-(_LTl$j3{ z89JLp@-U@YAmTCjYW8AKWJXBs0}d8X#P&Tp|1}vAN+3o)?nfFb3EjT4?x-@UM$jNKvUfox#-`%d)MgL(&KCqy&v{X7pl0-dOc&+pz zyc7_V{M{n2Sk>la1*=z_N$R!^q~>Y~LmF)V?UYRBw_J+@Ee^Ce(BeRg11%1;IMCui zivukVv^db>K#Kz{4zxJX;y{Z7Ee^Ce(BeRg11%1;IMCuiivukVv^db>K#K$a|Kh-w z#`FKB(i+(~FPDy%uRGxXVm>ZB?f9Wp?!HvINcR69moowj zU3|BE?E=?XWJSW@EfQgM@%?gu7}r@OPMW|UNWyX!D(&zP1>&=G`9x2q%_zoZ1-DKdt)M52)Jio|2Ec(4qvE*|w{MSOd%l5l?i z1nCs1c}kE&;_Nx;Sfuh+k)M^KS8>KyTwOfQM_b;mlCZMl8+fNknvtP15+@XSc-z;LZ`?qiXmk^~lJj%!mtl3e&g&~g zqAlUoX+05E7vCo`&v=`swx>lR9LOQ5pKVX(iME1Qr+MPOE*_j?yve6- z+mm^st=L}qNF2_z?MbAzCvozmnqJ8Ny7-!S+nz*fdrAW5v{i6Z7r#J!etSZq;njhj zy1HD*qiv0N%OO0b5I(A4OS>$Iw@5to0I$v>anE>*#6u16>TErs&lzu#a_{7PV4(?5xz@k*ZTlyYll9Mq zg0%gUNZUVcX_pF;{ntu@?VnbLz-#tjkEAx4Ovk@0j*@1PlgZFaFTeCMEh3AYOosmB z<^OoO-D!D?oJ@vZd|748A}5ofUkI`}9shGdHmBo%CP*toaXS75L0TCi(#nw4@&7JJ zD?>zD8M6KJr-ICvp~-aozX`HA9sj%_o73_CDoBw5aaIy0)A2tMWOF+H$AWB5$3G`X zs(oMDl~VS}b$nj`B(joy#7g~?Vnc17xzy*9SE-u)>`QP700hOQepzy;1d&t zIzkf#wPT`C9TX-CdwyY}4k-sbTw$WHKj$RcAlP*6E_d`0n$(Vo!rEz~pmt0Y)~+y7 zSi8bRVeJYNg|*8`gb7BvcBlkgP;e#+Ygd>ktQ{%=m!TBaPMar_D6AcgmK;i9?FzFC z)ox*Sp@vmTB`@P-LATTf9!?WgeQ#l+P;Y9Y9xp0P6e_yHM17JCJe(Fh5IRy4rIbuQ z3loJlh-Me)0#XX6l!Xlp1*i&A6J=@_4giITLXBORC{)f`@Jx2lysCW*DTUg%kW#39 z3n_)#R}*EJ8ERimRJBqNYF|y1sa>dj3lm{c4IZvA5oVw8aGEGna6Ehq52uMTW!g_7 z;o&q~cLn+kbnkYjl)Z>~cLn+kbg^5BvervXYS@2MgYobhceS(IE(?mhrVZkje zPnWo)sqv19!nV7#C{fsUN(rA%Z&+fa6t-PqqOk3@H?j)~4%Vd$u2z50EKC#@yf9H% z@WMo4!3z_G1usk#3SD8MQ0O#Kz=AhsSkPdTFec$R6NN0$L;;_eC}e>qs#!`Q3p7!N zQpf^Llqq<~0!X< zeqq+PX8qo*_srThYvrt2v;J-7<1>GE<~wIzJoEUOGiLr|{OjZQj{nN|8^@0w9~=Ld z8DE>RXGVR-1v8GGF+Ahh>3=@`lhc2B`nl7OoIWu9htnRJ_K9h4nRfQHrPF$+eShq$ zV|R|-F!uVfC1cgG|26vX=to9(jcy!0c(h~m>5&IVeskp7k<&&F8fhE(?(i3fKRA5V z@cQ8e!!HkgXXw8T-9Gf@p_7N^54||}H-o=F_-lhZ2Gi zch?zRhjevzeXsMO&eyk(xBq?H-ED7bTiW*1@pkc8?AP;5_h-7V>3&D~l=49N ziPA?)Tax{M7?;@p|AhNrcPqemmAA}gbCycmMP3KRFF+GE+>P%mW0pFh<1RiLKHGV8 zm2;v!6C!PoQY6Cb;;S+zz;(FdNTls%ibQx_Ja$8IokiNdr$~g?#bY-V*IA_Pkcvcj zUHq7=2;n-5M492$DH36I@#C^+!g#-OgZr{u%SQKAce7r||GIeCx{S9-+n+U00XXCW z`HwW&(uSr3;w^HagmH@K^TfE(oFouwB_Z$3ft3UzizERhheI8$BoJAV7omLXqhwZMCmUg0EMx^DfA`y-} z^LiPPMZ85gka@j~Nbn6_o#u(Ky7;_aMx^DfB0&jA%z`a%5$2_ja^mH7A`TI$9J0uX zI7Fm!NRbPqBZD5T8W~uidh25pr=OK8plGyXmn>H_Yc zv(Ykgd$J(yela-&xrC>j$UDPKJx^`KXG@Eb8@>p6RwF)(L~FnoAu%Cli`jZ&EQBxO z?T$u#Hc#{-_@X?oYs6=fx_n%e=UWBI%{^OMT~q!(hq?@J-zi9>$>s^&39rZnNEEo+ zBw7_-kt>j>;p+1LF7b%ZB6Uf+h(q@Zh8u>qp1Mx0qGM&~_XUYG**s@U7<>`( zp+yn}po^3r%@g-^@z8q|X)g)Pvm!C@>OL#Q z49_b=(=gs5bre)&D7OfMrm>?S^F(WCiy);%A{FCpo;nHw1!voHzJ%FPka>c4@aimw z7D)u-ZJs&`D)Rn-OkDz(h_|C4^MvfE{K#b~MB@G^@r<{5>L`d*a7+2m{nq6d9J8Y! z^F&K?l#>f_7I}h%G2Z4W_sQlYkd{L$lX!~^M?fHLtE`bQI|{P2Itl^>XY<@3VRjV6 zIMZA&BeJNMA-pa=Zx%_U?PYmZjqPPb+FoYsi59WFj7ZzdEE4_G_A(-EFSAHLw)*zO zs94NfiF6!7NukX`Jw#*?Z&ml@+3`eL-fC&JRr;ismbXMs#@jp%M&x9?1&1teG5R;h zAtIaM5RuJrh{z%ifnr_!kmxU@3EPv%<~cN(^o>hyR>w0>tK+Q(gAHMIJdsw%TO@1< ztK*5ZI$otu0FFbjA*_xk(&~7N++UDZ#}jFFyhR=;NUP(Cv^qXd4_O^gq}B0xvn!;@ zN`lq#)?z$ZFjmJiPpjiCa+x5ljwcd57hc^0y=eT$SjKp-!HCqEjsh%iUndbrldUIo zC%iga+Sf}2<87Wg(okhMy zA{cLxI@2ja-Xalpro&blml$|;HqZA<1mkUMZgRiD0~~Co~kiI?JJNNCe|8 z60;n5bvDnxmk7pNWKCk=)mgjm2NF?pkrp{$LgCff(mp2-YokylHr7DnDPxnzfayjxu= z|C9HOF7vb_@16v-$~9y98QmnZb@7UF;Fa3{|Eu8-55H0N`+qd_xuNTajvvAf`uk-M zJ#Tk?vVHZVyI+)j{C8JhR~@TZg1LrU3}j2|3s>8u}FjiIV_eOu0yRvr0Nz$epWKWY7xTg;-SxQokglu z|EDficF&}(!gVH$-qxz$U&4H=ET$QqtPxD4@ri5`JpADeWS*Uj_^`A@YOB~hk+v=# zvk0WgB84F(ctxrVA#GiJ-b|l)YOB20)Kif%5@uS3NNp9()9y_AHGe;v5~;1CNR?a7 z6ZUF;tAGRWinR5F1&H`8hcHUPKUz@F@kV?W2>`t2xk9eh)#U;<6^Yt<>Rf9(Cse5w zM<5r7w{tCWNatFI7L<0eAnjahk%W1satl2Je@H=|^BeKmdZMM_RfcRmU(<-sB6W?x%B=ug zd!kNujezwWk{Ecc=blw^6F6AAh!68bpY{C{;|QEe!bIZ=k=j2MsrA(UnK#-Ksr^%t zVK1vo8S>spLnQhhydpJE3343jZp3Hnsr|DEiMF==lX*e_;ERxX;|h`5KNV>;HF}vH zSBTX9$r7dahU$WX9b)_E5()F|DL2k3hfs#P_`I1Rk=mXPCO_I&v_13mEs@%u7K!`1 zc=T$kZ;3=(!mHCfabFkTC!X>BBEYm#iPZL#1kUXhe(0IKx`gD-3=fv@<~T&8DkI=d9dHTVzHg zB30rWz>I~FC-Fq8#49r7EyDgoIAkTBNc4Glbry*?UNGLv5Rp9sfmgRD>EjH+8!s5| zk%vfBb23C^GcrV^m7%bnbtzSz3=wH%$Rfd8D?>zD8OoDBD?>z1CPR=uqzU^9kyeJn z(jqSq!!s$QKYs?-uOvmQLBJMb@7lqqzQRTWV?jHtJ6I79({%JUJnszTV<~- zZt5rqbl$0BB0D4&Ufte>Qo_bt0TBjm!g!mfZIu(0MB_i~Oxv@Wr)?FB92cbR*=)~= zdUjnBZENV}LqqKReSw!0QR7pTMka??FMB4ULB*KBr zTg@WUwx=Qy4rJbH7Lm3+w@T{JLHcZa5?PgG@ap#HMai$uGu}%dCBbUyP!H9GO5WRH z7D#w=J)1}?3E_x@JW)@i341n?RucBUlz#VS-k42fMX156Q@O=`T|BtMc+a5)5>|G- z7Ok!>)CqM7gpOytMHWc{C;UL`VC_C4dxb8%I*WuJV!Y?=fs(j6=_9fk=_4{DeUEw_UzbwlNgt6FiG^3U zS4^jHbjY(9iG*aOq|YE>Cs^qtvQv=o>h^9+=Ltz*yydNxKGk5LR2L8Vv3iJkW~49Z zp8|3+WTlVDjP#j$LWZpL5t)%bgMk`;D##>~E#K5Zy zCB80!u;Ur;kxL}3xv`8$JCZ;jDD7w`A)V^09&@ALb;`ShOsp`+M`zkT-4 zbNBtfmYfUFU3{KRz`lL{nShVZ-7*)u`#4kZ(%ADO=~E1PE+9M$P`v+tlH>o;rB&|# zkduk0XO}8#+&xd$t(I$!c5)%^Z@z!3G~mRJE32=SM80)-dd-g&6U~5$)Yes`%A&Sz z-i(Pz$Tqx1qSSTq7-6jZ6A9UdSERGZq!w^>@p&^~B31qssijpUm}cdl$WDoYSESo% z4)V;~5g<}66-C-S^LFfrR7*vXwzneOj^IS<2wsGoCrCSjA17g666D4?wHhXp1R_-u z6sh%`ND_!tNw7$S*Tv_}orzRQut)v*4BD7O>YCNJLo5XwI5=F$O@4WyUQcY+|%v zO}ywL4wY)$Ai^d_1#9AE1FOyVU%5quO$?US#0Qimi8w^q#Avdb_#iRHNNQV~7*($! z(sKi9ft}PQM)#{B(kI4F3Hzl@3>&wG$kK{xX$JV!IP{AMn;2$oO?;4ezPm+)O$=M1 z=3{NGM223+4$D6RRM#dCC|$xW-~Bt01-e#Cbi1 zlp!y4lsYLH`ibo+OzZ_IDKp2>v>-9D7o>!Bv}n_U#Kc~Z5)tKLdPLX?dO=ExArnS% zh_H#hASH?O1c}A)f|Qh*XWi3+#Kc~ZlEkxIG17v>#5sb*Q`d;_WjbSZf+*dX>LBjk#25Ua%CY? z6JPe@U|vsQ;vClHX;CIt)&wI~zkur5!FGO=eJOlr|^<;L?#Y1T2Z zXI&!Cqpr+(tn)o388m0O#OaO>FZi6|3$5ly5{bf>sHZg>$*1SwBMNjXPEsdCdIx?1vz<}(vV@|lU1 z&yz?U6Dyx5kvb;!d`^Z5n#5_TTVpDi@HwwrF|k%KBO8eDLmLxo1q0athpnz-VpNb0 z3#CpYak`WiBqsJ1Ov+3XB3;3ggkac$3pntgtCn3#LBGZ$%{Cbg{dW>3=G^IhV!*+a_SBu-Sp zYh2>ANzBAlKZs5eFL8+xVT*xzM$N@0#W>2{BElw?`$pnK>W+1Z5n&TUE^96}nWwCG zw}`NbA&oT`nxUE;gy)>)b6OY+~AFh)zZ;Y{l{L zmruM_Lc%_nP|oXvOssuy5+%dLIen1bD%}T}xPtOIm-G~ND@52bcQld)^2~092%9+U zgAMh?Zj~ObSPb6>6RD$OOdC||B%hFVi6G^%j)^_%5L~J2+}z&ae7Q4WegoP7n>yB>~0ZZDf=-cNqm`0oE}q1S-_U^)h;n2EM-5Y zB&@r^B~Fhir0mC(q)~p!B~FhiOzg*$B=N7f#OX1GiF3x3_qoLBF@=fI?`tl0k8Whp zphASLAi4z;CoOoJ!y>{a#%c`{C*1giON(f5pAIC|J<+vs19+&l71Bd;5oKl1$WpAUa@_{!l`!=uCBAG&|emxgW~ z+B|f`P{+`dgTFiYw!uw<3kLsv;A;aPAGl^<&A{}5AND`gf17+E;Hds;|KIifUfym$v^|d))s2i6SX@{vQKKxwOUYmesmz(@%2u{`vo#1Bp8S-!Ax0 zaGQI{{r^K973tGL+dEZx2&;>Sna6k;IT~kCh=fG}uMXC%p7^RuAe1KKEwWu=;nnTg zF~(aY3=ep9dsgWckx*)kw@BzNcy)UP|M-bqDr z2$l!DI(KpaBcHgscvvBfw|OE4UfmwOkQ38&xyGE9@fO)FvGD4&J#k+b4>N@E7Ks>m zb>W!b>ZE39xg&YDBO>1Rnsf0DhAtEh@w6w}0o}t2>FD;RlLt+1v ztF3}?AR+O%4%?GR%iFCkmH&a(w9*WB&MqH zMacP$_^c$Lz2FsTOS`BMpGBg*;ERw;8u20WND1>2FE`F9k0+9NBHJWAygDr{!s_Dl zbOMno@fJCeP9PG}4zJGj6{o)#g1*9dFMUL+#4A$kiTk>EaL?)lB30rgfpc0<+|; zNKAl{CM$g^@h(z+Y@RqBgES$MXDc9|@G~1CsK|-rmPnObi&VMIJ8Mm(%B>US5F2X0er9B2{kR(LmlTDb>~GVxD*_x5r4B*P4%- zJSUPqA_0K6NQBkJ=Sd%tDt#8IS~Kq}RYXFv;4M;uT%M32#D~&Hq)J~A5;A0^k4Tk1 zMOx__7o?RwB31f|kQjNb^bx7jcTS^KY@X0VR{Eefe0$1`b1~Y4NNrC=hB~1xfq8R# zBDFmgX-kWeB2CyTL~47wNcpiy^b^~jL~45~(vC>zC$>F_)b>=Q?JLk=wmpf|_EeP*(85QbGA##LIkRMP~I7C841T-E7&e4>3=xhxXQ? zCHX*sT*?~bOE0%OO=R=5ddSL9-WntGw0g+43VOcPL)7uwv#*yFaF(|i?S0R7Nm@TG z4zxJX;y{Z7Ee^Ce(BeRg0|^K6-_9Sti{E}>;QQ15Z+>IIzk6V6&;P$cYJ~lNI@+$= z<}IDK)`gc!H_HFV#cam>>#J^BQ!d?n&(bwaU;NAcf2=r^%CNfq%*ubq4qN@)n6;ysalz-{I9+-3240;--YF4`x5#mcfmdgdcS{80EfRckylOx#^1dYABC*a3ug)SLkO;MZgRiD0}%;z1gCbr$)UL@?eWu{*}+$BDJbCz5!JoF_5x z>MZgpiD0}%)+7dAokcz)5j7X-k&f4sj-Ocl;tH5W7LA_>uZ!=NKfks$$JqhQvuON8 zIFQ5gXVqS8usF3&#sk2K+kL}XEEU1IrxKCq)bkrj!7S7%!VsTl8h zOQap`^TupD+7oF<`@NC}S97VKVJFzpo=6O|!C+g88SRO*qkSF{Y07~OMx-6>^N>i> zmOlygFDE>gsZFlz7J5_LTbxNBd)wc#E{7eQ2B1 z1+`kd9qn0KJK9_120_}arJLRejVo*p6+nu2;pF2pHP^Td9!*P3CT&=k}& z4w$U5BdjhSk3(6l$vjai>KVBZr+MPKE*^FXY)=PrMkLYoG0GuAtI&T6Y8OhlX%M^tA}hoFBhcML(J3aA&b0LkX8>7Y4wmr-Xut? zhlqrZfme5eUdaEt__vE^yshVCdgwiZw0eknPB!cKfFSLxgGg8q@ak+mKOzx~x1~kT zg;!^hzbz4rw@5qdupIgwLE2ddOFP-DFvkoFBn{|9ikapHV&_YXkzX&T?qJAQ^9w2MPpUoy~KRAQ^9w z7+K-fS>)k@WV}T#6bQUJi#%44jJL=|0)ba&k*fvCc#Aw(An@ueht>;{@fLZAK;YHc zJU0oF@fNvQAn@ue@;pH@-XfO>1YVs*UMxt)TjZevfmdgdmkW~d7I~OJ;MG|UT`Ne& zTjWxKz^k))-XuuITjb#afmdgdZx!rq7oTUx6A2p~UY)hZ^XzycVWY#Vvq)$X##`QYNesL?TUy8u<1G?4I=niIJXRtY zZ;{;+1Fy~^S4#xrEfO|5ygG|qFAMU}TL@?eWVWY#VvvPZ$L@?eW<$lU` z{5)h+hK&xd&X)FaiD10V6E-@$I*YtkA{cLxLlOh8&LVG;2*z9Fu*ATtvmAQ6L@?eW zVWY#Vvw6NpA{cLxu+ibwS>y*Kg7Fp!8y#MqMSesg7;lly*zxm_O}QC6p2%kGcp{sz z*vtG#my7;e(XT0T5Gj=@lY{rgvWhl>=(!i@zO^y4y_-Dm4-j|k0SfI2* z)ikCZq$3e z>!=!fMBJBun*Pfw4IKo?`9l`TTi!|Zt zJWJapq44T#o{)9M+dMHkbA%>#g_4l}b@8w_7;ll?5(BT!B3~mBjQ7ZeNSu)bZBLa1 zJeh2FvWT>ju%MAS!s{R{e|AmQ%}FwODpK>zlRhGCp2}Oz6INh;o>uy_o+va*3%Rw@ z$2=<%3$JeP8PW=kZyePnFi-l3w9>a%QWLq#DOu<C<|m40ZA2;*loYcO%kD zpUo4`LRje|5|Tyfa)dL_FJf(m@m_|Aw9;oaeoc^8`iSh27vFpGr?YP9itFy?HC4%v`uVBP+ z7FGkgKuO5|y7*JYGu|T)k+AIOph(r!dAo!}T1~BTtC||)iq+IaT1{>13CXjXdU4aG zCDN8w>j|=T@yHWt!uBL`veH6>+0vr_WO=LgRNm%|f<#VMT4-roS|TSaE#xP^v=xbg zSEr@LeO)|82gZ9DVxD#sw8)wu?I=j39R=;T^YTt*5NSt2o96<_(~g2fPBscI6r>#m ziL|4j%@gusM?oTcBnDocMPh7YyyY!MICymyxlAG$Z;^cx1Fy~^anE>*l>5{uXpzS! z@g8{?vYFKG%hM)AT8Y;@5ndOMvrkr=IEx^Yry>R9kdRsQxUgpvY4Z#%sk)@ko9Pf~ zdzrPyAwRa45sA{kt6QKK^1m*ANIc^`Zx5HS=6Fk_t*4fDBHj{d>#66h5MCEQQ~vDP ziX$aFTiTluDsCd(N2D!n*ealq*D6HX((YM>^mKLk2Rq)j3X$MAxz5x(_|N^;MZgsiD0}%+Ig8p zUMNUAFJoz;!{OCgMZgWiD0}%PLmjTbryN6L@?eW?Yzt)?+~P&m$9C9US^SZ3ewKYh#Z#~cy$(e zw?r`Bme$V8Eb=}<+IboCoNQhH0YUQoj?L4q>)SjZ5~Mw!!#w9m47@svd_*D`Z}Y^u zCA>O|d`u!3Z;|^+47@svd_p1^Z;|sP240;-J|z*1x5%2rz^k*!XC$KLA}w;hgu<({ zn)+FZV7x`{FEQ}ytnN$id~hZIXe4fG%qFs#F`LL{#%v-hQe=2_A#V`|`C+{05RuJ{ z*+e!oW)q3=m}4@^R*E{?Ph>M=Hj&MY*+e!oW)s=Wm`!A#a0OnSmD{{An@DNjDUaDi zHZx`u+02+tWHVznkEB!cl4+02;DdNwm=6WPp|O=L4;Hj&MY*+fF0a!e+7EpH!5;w^8R8MBW> zCS|K{_k_l-B*0ka=Scg$i+{>~1N%KO_oH*S%sp`KvvYob&W&?Um{Xbawb{4Ne#7iJ zv;Se%y|b>GwQSbUXMSboJ7=CYb7ba|UY9@_8G!S@fIH8^YV>48rV zTrqIOzzh8k_utZgYX4CGx8(%D*1m;(|J?gP?^}9T^>+3?CSL|Pw`aeeXSzSreNFe# z-7i-Er26ja>*NH$ce?KCy0mL?*H1dX*!i~3lRA4kAMa@P`Tvu_MA`ozFXR8sZua|B z`M|mBT)6ZF8GgHE@Wvj4y2swN{>yq@^gpy3nz5@WQS*d6ygDmUd3F_%HG#mZv&d&8 zqUIv4EW&1jR~KVfG0$e~s$-DNq;^%_S|yQ1b``?w;?qxfvQ>yIva1jdWZn~=$4dC* zrOjKpA+o5nAX^uY(H&{R6%8VbO6wBK55@_k$s#Kf2CvRaLY@`KJgpU&xBg;RZivii zCC$7s*UsBZAhH=NkVtCK8$_tBcP&8BQch z1++TN6ZduTuvZ!H<(5dRheAmJ64sN|Lqu9VWRV96(pyIy9f-7g$d>kSK_X4qowSGkVUQ+4ANwglj)&Ng0Xst^|X2@w2UQambdu ziX?f`ZMP?43^tW)gg!z9rrVMu#i2hXNjna)wIiL4eu5qhBUT@Z@{^NN1y8B^mn)G9%PN z6l^Nl2z`SHOt-Ba>1_1dBnh5;Ywfd98=)VNjC}=}t!*a?HkE8^e@FzT+t!YBHu^6l zXLK$5AdemFzMx zs59M`>>?3tD%p~yB*}DJ@+1<$rjjjLLy}ClCA&!kn@YB13rRBFmOPn6u&HDtG>#;h zZcFx%2sV}MGRKo7(``wNtk_htC8v@k({0IK62YdDEjf!MnQlvtClPEa*^+ZelIgbO z1QNlfl8w+}l4QCqIgv!LsbrV=L6T&;Ejfuqu&HEAUQCiqwjbX#%? ziC|O7mb{E4nQlv-N+Q@)vJtw1B$;kY;`#wLmFzOFB1xv(l2b_pn@YCiM@W+Cwq!qv zU{lGK{8N%-x-E&TYU0Y86tyKkL6S_jB?m|Xn@To9pCU=7XC+SuvrmMA^Z2lH2bRQq z9h*wFwWUO0x?Lvb>)2GXC2NSlbXyX0bZjb_ZJVJ?jDSqfN}dVk5$hRtzQU4rJ?(is z=9zXqS<-h?Cn(q_f8irlZA>zrerz#WeoB@OUXO8wml<)a=JwJ?G zO32U9R!;xyC-3G`etwxs5@p^%TNt)1X_skVPYA=7C2ed?@6S+~Y1(XTS<=SVmc-oF z#+D^ZOIa%U{lGK#5|Mfwq%MZ*i^EyMPFgM zEs36sO(k0r^Dm~`k~q)9rjl*#I3h6Jmc)4;HkIr$Pa*=-ZAthDHkG!j1KMY3JB2o; z+miG<=bDt=p1qo$m7GO+o{zH_Y%1CH+(iVY+miJ}!KRW~Pvl)e8`HCrJinbz6l^M~ zUZ#G3mbx3$ZOK7m!KRWe`2~_>x-E&T)!09!;g7AVU? z&9Mww-ylh*+mg7ZC9Z2pNxRH%lO)q^$q$eOHkEA2ACM%|ZAr9^XdfwROa71~nQlvB z6crmXj1e;3s-Jp|+!1QdHENPEruYgm$(>XL2 z+HjBB9?MwL9?R_ZoJ`X8SjLhgjb%7*u*Wi%w8t_N+YCt|zT0CNOH#da#xlE}cpDTv z=DhF!TaP#I|KHMfsA+Cfs_A=;w>7S6>}>p5L*X_3vv>Oo-|1gaTTyGT{r{h}^8cGn zk2Dp3_y6g(MShk4oOg$}mZsVX0z;j4ajSUVdf^i>`vR?6aQAr~ftt$A`_*}?0yR7P*Zp@? z1**E64j!%u_FZ->)hH%+HZle)V_% z9H>dyt~=}gJy7$i#$P{rAOL7c3%5=GWzfjS-i!N>wgi|mBW=65x;1F#V{dPKSy#{^ zf4q9^-DLq^6ZO2md~4mc0bl0yyno$)v@~d!Y@ZlDIxE0r80lNxG==ZrWAB^y+;%t+ z@r5$>ZN2ripi@%*`slA02jk?AkDdSM(x6NJI5xfWSa6d3QTA%pZ2@T%Y0Gc!tPBw1 zkcO{p^@1Kg_V)g^?eyRj`D4?;ODlq2`Qygv>;5_zFMquGn^kuQ@Fb*t|32r`U?LxT z_dRsyKL?ZKk7EZv^Vwjs{ITcNbN(Sv*K5YE`{0s5U4pstqLw=XHCO)42VehffPjYd zH#P6R5~yn*Kiye+LokgA-p6{*FAoOfkHwoOogVO1)${H+@4@wfnw@_1mOtMRs0rt> zzJnEkin?$09eh1d)572X+trf-HPie3zkPmEpeAp_hdxymsQK8QL!WvhP*bd354HVU zphlcs2ao<$aHcfpr+Xj$t6)g}_}||+dr2@y{`gT_d`&P{{#aK1cP|7Y*iy#&;dk!} z=1a=KC$9Ow10H5+f_d);ei^8d^{t1Syf{t>$ByL&-pX^f~E4uop)Bx2$snouMc*3!E*WI#&>U-9GoM6Y`OAqWpJ+i@zNE| zX9ORVKmPTqiz-;EFcTpqfeL%<>65O4@M1RMem0f&G?z#-rea0oaA90Cpjhk!%CA>a^j2si{B z0uBL(z<*x^RwY*@mnDai(~>>OmSjcp{lu}vzb1|*zLR)7@#Vz5iBBeOOk9)Lo!F4L zAh9?xJ8^2FE76chC4LuwBmOV(=i>hu|62Tu@w?-H8UJ|vs`&Q!n)r(NS@D_iiSdqj zO*|3*P3*PUKgXVl{eA3_*cW1V#r`68U2I=$YwVKP^4Of%Ka^j2si{B0uBL(fJ49`;1F;KI0PI54grUNL%<>65O4@M z1RMem0f&G?z#-rea0oaA{%8;wN9l2IEiE#Vz_MEMrn`F6eYaS%>PYh3R=f!eA}D9m z!Hot2`yQx$-1r%K*hi9hnI1YWq&Iw%-itmhgS6Y*<8AWx(zeIjPk+INBACrrY#Y2? z-gf%8js(CAHoSme1RGw>FMjM?#9w)>$0exZ>D0YBuTQCkq$fExdPw^xaK1 z(~hyJeeKIC0ZD?U!5RjaO{H9#j@)IQ3YmBTZh zR_%<|Fg`?wSpuZd^S0P#jq_G}m(jLCGHkUOW>KkNfrY1$MIREsHyFQJ^LATsjL@R4$ot?MLOd+ajmpNpwauqLqNXkwO~RNNk_FDeI?xLMd3p(QI% zGlQ%pV`-7HtwLJKCQb4wv?|y-DtnW+k}TOF;~k2?`aQZnCllKyiWgv6N7YukN=&A4 zwA$Bp8u_75F{E-C77O_;Mlq!(!x#&RGLtyYTSm%vl57?StP!M*9Oo_1t1Q+H%3)YZ z@&^n9D@}$|NW%pJEE}{clWnZGg0z@8V5+2xnd+SHN^UNsA*PnvlwwS6uqm^NwhceF&qS?hV!SnCKHo`XXqr~BuMoGrX%9W~=sB$gG) z2?djLO1Y3wM00KxEd%{IAz`8jO$z4oL@hWtfHfyLOb%tmu%7m25;OhxmZ|}%MUHRt zB|*=)w)nj?E5baZkLD~>#U$ZF^nCImnVZeKggAJ8DxLc={K`2RZQAc1@G=EWJ{c!W#2=`=#_WSynI2-dNvsOEcH2m!@k| zj1oB)5*XW2;+b@u_5gFvG~z58!TBF1X#G^FX|!KSN7Jat=|tndQv?@JH=qQry;u#( zXORe|Y12p?2=U*QblgYc*}qf7F@C4Lv+M?6=o(z0&+ZZ3;Gh7)@fyaQ20fjc4s*I$ zq7??^-`oa;xN3u(hCH1bZI5oo;CyqlINw}AJ@{(E;Tp<`q7MA0Q4todA$LRMT}^gG zS@2(L-)dna920ZioLNPoi9*hdB5I%oeHXj&io(%oCn#C`0c;NbrwjaTAIYChpjDRHt?~`mDt~aR zVETIr_3Ftq?BG~UhjXXdJRL5^0}$YFjZMv4@OzbCYtTGHN`W zheoANB0$G%adv6T#&fvnPoN|`eE-Hysb|RFD0R~I z5|uwBt`P85F_vFX8qXy}liu+VdB`Gl(#9CLdbmE+T)!#e~aA z+dhpi^eEfLc+W>Eq5MwTpl5;B!}c)7(DPyc!(NKMUDDybNWY>|ClR1$zSgs!JjSlm zSnuai3MgOcSfz2|OH}Y*yOwOl;du(lJ-!f-7}dZ10QRCwf*; zRR2IM!UbjcHCu%Gbdf%VtZ&E^axk<*vFb>z3DjqwL7jPOVB!OVy`-Q}SHNmrHIe*;KN$WLimUiC^+^@b|&t;NoB?I4MX3KTST7 z{9nnf$%)C=6F*2in)poOI$CL(MkYEXa#_^^8UX>M?`19(?#c86uBCHREovFK^;dMP8V@iPNl0q_v}1%9JR+h z>Q_WWr2m!a4l85Nd#~L|OXthIQb5r5g;#Z1fxR8pd9uku;NnTBT|VnKX1xfk{#DKWKI`O1PF6ol0sq^Y#D z2CMjG@eMnV#LcGNAXRJt4#oKfRN#giPpzgBtZc>h6KPbA+_)oh8QB9kUy*8FDZVne zO@pw@6G7~u=mS#G2NLo-!t`5r_i$k6i1C+ih)tylJ6GtmgqW55BB4Wrm_$|5-1Ut;dW|C1s7;t9-WV z98z`#HTfC|eD=m1&9Es>!=_ho0AHfr2*58Sbyv}bXs3e2NhAd|Cl&9Kb8;N=@1%mi z!~Gegk?lB}6mXa_?-Al=JloQT^9Gd^GHS2#8KH$j749NtTdiBF=`KFnTuf7&?5#wc z1mxdJoa)^t72j9<@N%|nIhMKFD7t-`cDNwBk1rwx#2`R6wNCjtW3zQ<908bTP z4u&lg%e<~4RpIV%?!dQ;hMw#x@>DM)?R)c3)}_4nB{FJHJR)%g&!NHCKI?@`z{Zad zA8dTnoaI#fo&i^TR;KX69obDZlAy;8Q|QC<2vg~6Od*P9NkwX(tLSX0XbUO9vywO) zcgZ2(5O4@M1RMem0f&G?z#-rea0oaA90Cpjhk!%CA>a^j2si}(|BApf$+g~`cva$} zV5|SKcXP?SlD{ZjQ2LwHXS{*rKgN&wa^j2si{B0uBL(fJ49`;1F;KI0PI54grUNL%<>65O4@M z1RMem0f&G?z#-rea0oaA90LCn5D@GC<9>cj-PA9q^#E|ce^|Wz_hNNx$1)=0{{L>; zI_V*Rf1Q#`|{pFke?VYCfo@ly6Ss{0;A*SK^F-8<+nFHS4vv0|}A z1nUKCAXNF25t6Qbqr+%hUAp$SPDw@m){%`;TDN$Qq+9LIIAJwri7ng5ZxTx#Sjt&i z$W*HgjeRH84C|v{1zoHtBjt6QcT@eYBp$qlKTMv3C37W@_TUbpVLc^q>Q>NR(WNPP zkyP{mt^wY2mNkIi=>Ef0EcGm?T||S=q2x8DyzZGD#DTSgq<0~om-dzjU{xDl5u0bQ0%DLKiIy7d6R_&P~wPtyZd^=gaDYr!J`=K?`Z30QP z>XWpUYO2~BJ%#%r>O9D=Bo95zE<^_rd6){sWE<`#+YpyfGxAcV>o)8m3rspz9N3|_z$>)C zPP~P@i~eaH8aWGdE6x~*q zMZn4^S9&GqYNWczirm$P2AM;bm*YK5(m>~$ zN($r|{eIC4HxLR~83OH$&+A}i58ba>!oXZ(#uTHL7#A+1cEn$_j4Vypq?g({mqW%5 z)}$?-NnD!(>s@e)Q_XGmmZ4s8>>8~x6Roy=j>M@JQ= z7@mZ+04%Du+OiCb_3MW{eOj3(FJ?1`VY}*;dR$=+Z9DKZ`YltnbwEwGJ-z^7l%Cgy zOxK!?He`y{YPBI#waqy##k43q@VNoc!*>Npx9@e6SHbHprwEF#`e3n?LFUmdk!Lm2 z^-KZtE%XImm?B3r8c36HmqI|VVhr~h8mpVx=#sCW^JsZhJZ0$K*11g8hvOI^WdMxVJex+t56bqS0 zk3`ur^r*rdXmwfp>}ZEJRSSmX)E?_@3U27jUGGqqh$oN*N2lh<(a@>rs1s|z3WZWy zkKrA1+`N+F+Ezu?zS%CQyE&e5JrHGOJ$PP2JFqLdLmLt-~`Xn%q)ZlQlNelS(Hk11W-Ouu3FVpo{k`sHGrsL&^@s;`YSREN(nNN>G1>!4n z>T$BD_{uWI+(SjpY)qE%l{xjCW|EHHA@P-Yb=)!HD^qmLu_6+BEw9=odLzdjd@5>d zHbOIxjynT1Ze2v*h+0W26XW_7&Nt2{?oG6!HGh0*r8mejx^J};AL_Z2cqL7@d6%T^ zAr8zU=qeCP>)Lb(4tOb9S+KeU0Q z+ZeERqt)`R7&C`P$ry8)qT92J##~-E{Yv36+IHPu%>o;pZ+KG943hO~yo~EKh|tD$ zKzInB+iVdf64uP2+eBS)#_HqxiZk;VrNfKVY+P!vabg*xcjV#39AP*yMYkZX)~KtW zvNT;+jS$OdIZu50U&7~`2Sk3&3AYu^ttObo2TT)9v=; zT#XR!3ZQ1V!i4k4L8faz>JrzJa_*!sM~q4r{nqFgOfir{OfZmTx~?ZAA82iT(%tkBeiNT08PtH5G|>7^2n_t9#eHKI;btyQ$6LiZKm4o!MVDA ztyD7}j|Q1yv;{{>j?v(C*Q)3<)bK98xV^)nhV@%hW#F(GAf3N*Z z?YFlNw_ngcv%RZ5)&64Jx7r?TyR~gk+sd}tZ5?fiwwGIsTGv-sU-x$H(b`9AZ?D~2yP&qKHc|Uh%{OZf*KDhqThmY3Gv>K|1-RCQg|=Bg!C6RN7JUaEY!@^IzB%GH&# zD_bjHuXwuRa}_sKY_3>P(O&UJ`IF^$m0wqWY55uDt>y2Py;%0mvir+!DBE7PylfJ! z@&9`1_eviwy|r|A>59_9()QBhsh3mVO5K!NnVOU;OTAh0c*#8_*O#m>Sy0klQdRP1 z@OklxRloUZw=l}zL0z*c{q6>d1-QfvOAedzLxl2;=#nti35oX5`&56#M|+s z@kio^<#~@|26+^KjW|RXZs!gar!RDBi`-a zwcc8f-~UJRBW2(JhhyXY|K+rYtL>%j20Bx;_tcQ z@5SQped6yM;x9j;kRV%N7r+0HK;e=@z#-rea0oaA90Cpjhk!%CA>a^j2si{B0uBL( zfJ49`;1F;KI0PI54grUNL%<>65O4@M1penCFpiS>{y*PUFZa^ozIsNy|Nmrle+S=- z&))xEXF&D-=jY%Vo`Oj}Us6U);;F1odLrjadY%Ozwcm@UAo=MO{p^x{-j4J26F}B8 zIZV~h))-HpO%&$nr(N*$8J={(lRmrX`J+Lm>t}29iUXXlpP!i`o|D>1Pu<|@p<(*R zpQYXuYuMm=y;wL z&z{n=eaxXzo5F^5Jc`-GA#QR8Afx5qM3wVa$=OKB<)@ejrwE%g4z1MkXg_*~nkgFhF3R6YRO2~o=FqJs>%+O) zRy?7%m;SL|NUhpqrigmt+0WhdL?PC%FyD5R+!`CB4Y(BDzIftJu7AN4jRc;xmv1yP zMfWueBc^JMddQ}&WHp}ggWvOWp@XLiymamGw!{|FFItIdS_4*yKyQ*yyfHPbE=