@memberjunction/ng-dashboards 6.2.0-edge.2 → 6.2.0-edge.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.d.ts +4 -3
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.d.ts.map +1 -1
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.js +8 -5
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.js.map +1 -1
- package/dist/AI/components/duplicates/compare-value.component.d.ts +67 -0
- package/dist/AI/components/duplicates/compare-value.component.d.ts.map +1 -0
- package/dist/AI/components/duplicates/compare-value.component.js +168 -0
- package/dist/AI/components/duplicates/compare-value.component.js.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +49 -3
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +287 -169
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts +77 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.js +116 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.js.map +1 -0
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +1 -0
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +16 -4
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +2 -0
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.js +12 -6
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-index-auto.d.ts +29 -0
- package/dist/AI/components/vectors/vector-index-auto.d.ts.map +1 -0
- package/dist/AI/components/vectors/vector-index-auto.js +59 -0
- package/dist/AI/components/vectors/vector-index-auto.js.map +1 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +9 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +65 -20
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +7 -3
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +3 -2
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -0
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +0 -3
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +5 -14
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -0
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +1 -0
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/form-override-dialog.component.d.ts +12 -1
- package/dist/ComponentStudio/components/form-override-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/form-override-dialog.component.js +128 -81
- package/dist/ComponentStudio/components/form-override-dialog.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts +2 -0
- package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +12 -10
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-agent-context.d.ts +14 -43
- package/dist/DashboardBrowser/dashboard-browser-agent-context.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-agent-context.js +6 -29
- package/dist/DashboardBrowser/dashboard-browser-agent-context.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +174 -321
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +522 -1195
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-library-filter.d.ts +116 -0
- package/dist/DashboardBrowser/dashboard-library-filter.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboard-library-filter.js +277 -0
- package/dist/DashboardBrowser/dashboard-library-filter.js.map +1 -0
- package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboards-agent-tools.d.ts +26 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.js +32 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.js.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.d.ts +58 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.js +391 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.js.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.d.ts +37 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.js +68 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.js.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.component.d.ts +295 -0
- package/dist/DashboardEditor/dashboard-editor.component.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.component.js +1022 -0
- package/dist/DashboardEditor/dashboard-editor.component.js.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.types.d.ts +23 -0
- package/dist/DashboardEditor/dashboard-editor.types.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.types.js +3 -0
- package/dist/DashboardEditor/dashboard-editor.types.js.map +1 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.d.ts +11 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.js +17 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.js.map +1 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +30 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +349 -232
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.d.ts +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +2 -5
- package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
- package/dist/FormBuilder/form-builder-resource.component.d.ts +0 -14
- package/dist/FormBuilder/form-builder-resource.component.d.ts.map +1 -1
- package/dist/FormBuilder/form-builder-resource.component.js +7 -29
- package/dist/FormBuilder/form-builder-resource.component.js.map +1 -1
- package/dist/Home/home-agent-context.d.ts +29 -10
- package/dist/Home/home-agent-context.d.ts.map +1 -1
- package/dist/Home/home-agent-context.js +50 -24
- package/dist/Home/home-agent-context.js.map +1 -1
- package/dist/Home/home-dashboard-switcher.component.d.ts +95 -0
- package/dist/Home/home-dashboard-switcher.component.d.ts.map +1 -0
- package/dist/Home/home-dashboard-switcher.component.js +442 -0
- package/dist/Home/home-dashboard-switcher.component.js.map +1 -0
- package/dist/Home/home-dashboard.component.d.ts +330 -17
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +1702 -1014
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Home/home-menus.d.ts +38 -0
- package/dist/Home/home-menus.d.ts.map +1 -0
- package/dist/Home/home-menus.js +53 -0
- package/dist/Home/home-menus.js.map +1 -0
- package/dist/Home/home-pinned-dashboards.d.ts +33 -0
- package/dist/Home/home-pinned-dashboards.d.ts.map +1 -0
- package/dist/Home/home-pinned-dashboards.js +76 -0
- package/dist/Home/home-pinned-dashboards.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-production.component.d.ts +5 -1
- package/dist/PredictiveStudio/components/ps-production.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-production.component.js +64 -41
- package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +3 -2
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/RealtimeRecordings/realtime-recordings-dashboard.component.js +2 -2
- package/dist/RealtimeRecordings/realtime-recordings-dashboard.component.js.map +1 -1
- package/dist/TelephonyOperations/telephony-operations-agent-context.d.ts +107 -0
- package/dist/TelephonyOperations/telephony-operations-agent-context.d.ts.map +1 -0
- package/dist/TelephonyOperations/telephony-operations-agent-context.js +216 -0
- package/dist/TelephonyOperations/telephony-operations-agent-context.js.map +1 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts +58 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts.map +1 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.js +812 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.js.map +1 -0
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +7 -7
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/WorkQueue/components/work-queue-bindings.component.d.ts +37 -0
- package/dist/WorkQueue/components/work-queue-bindings.component.d.ts.map +1 -0
- package/dist/WorkQueue/components/work-queue-bindings.component.js +210 -0
- package/dist/WorkQueue/components/work-queue-bindings.component.js.map +1 -0
- package/dist/WorkQueue/components/work-queue-dead-letters.component.d.ts +70 -0
- package/dist/WorkQueue/components/work-queue-dead-letters.component.d.ts.map +1 -0
- package/dist/WorkQueue/components/work-queue-dead-letters.component.js +496 -0
- package/dist/WorkQueue/components/work-queue-dead-letters.component.js.map +1 -0
- package/dist/WorkQueue/components/work-queue-discard-dialog.component.d.ts +22 -0
- package/dist/WorkQueue/components/work-queue-discard-dialog.component.d.ts.map +1 -0
- package/dist/WorkQueue/components/work-queue-discard-dialog.component.js +99 -0
- package/dist/WorkQueue/components/work-queue-discard-dialog.component.js.map +1 -0
- package/dist/WorkQueue/components/work-queue-overview.component.d.ts +29 -0
- package/dist/WorkQueue/components/work-queue-overview.component.d.ts.map +1 -0
- package/dist/WorkQueue/components/work-queue-overview.component.js +278 -0
- package/dist/WorkQueue/components/work-queue-overview.component.js.map +1 -0
- package/dist/WorkQueue/components/work-queue-partitions.component.d.ts +59 -0
- package/dist/WorkQueue/components/work-queue-partitions.component.d.ts.map +1 -0
- package/dist/WorkQueue/components/work-queue-partitions.component.js +359 -0
- package/dist/WorkQueue/components/work-queue-partitions.component.js.map +1 -0
- package/dist/WorkQueue/services/work-queue-operator.service.d.ts +22 -0
- package/dist/WorkQueue/services/work-queue-operator.service.d.ts.map +1 -0
- package/dist/WorkQueue/services/work-queue-operator.service.js +44 -0
- package/dist/WorkQueue/services/work-queue-operator.service.js.map +1 -0
- package/dist/WorkQueue/work-queue-agent-context.d.ts +67 -0
- package/dist/WorkQueue/work-queue-agent-context.d.ts.map +1 -0
- package/dist/WorkQueue/work-queue-agent-context.js +119 -0
- package/dist/WorkQueue/work-queue-agent-context.js.map +1 -0
- package/dist/WorkQueue/work-queue-dashboard.component.d.ts +94 -0
- package/dist/WorkQueue/work-queue-dashboard.component.d.ts.map +1 -0
- package/dist/WorkQueue/work-queue-dashboard.component.js +545 -0
- package/dist/WorkQueue/work-queue-dashboard.component.js.map +1 -0
- package/dist/WorkQueue/work-queue-types.d.ts +40 -0
- package/dist/WorkQueue/work-queue-types.d.ts.map +1 -0
- package/dist/WorkQueue/work-queue-types.js +2 -0
- package/dist/WorkQueue/work-queue-types.js.map +1 -0
- package/dist/ai-dashboards.module.d.ts +21 -20
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +4 -1
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/core-dashboards.module.d.ts +69 -61
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +29 -2
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +1 -1
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +3 -1
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/module.d.ts +14 -13
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +7 -0
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +6 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +9 -0
- package/dist/public-api.js.map +1 -1
- package/dist/shared/dashboard-library-changes.d.ts +23 -0
- package/dist/shared/dashboard-library-changes.d.ts.map +1 -0
- package/dist/shared/dashboard-library-changes.js +26 -0
- package/dist/shared/dashboard-library-changes.js.map +1 -0
- package/dist/shared/dashboard-owner-names.d.ts +17 -0
- package/dist/shared/dashboard-owner-names.d.ts.map +1 -0
- package/dist/shared/dashboard-owner-names.js +65 -0
- package/dist/shared/dashboard-owner-names.js.map +1 -0
- package/dist/shared/dashboard-recents.d.ts +34 -0
- package/dist/shared/dashboard-recents.d.ts.map +1 -0
- package/dist/shared/dashboard-recents.js +87 -0
- package/dist/shared/dashboard-recents.js.map +1 -0
- package/dist/shared/dashboards-app-install.d.ts +59 -0
- package/dist/shared/dashboards-app-install.d.ts.map +1 -0
- package/dist/shared/dashboards-app-install.js +97 -0
- package/dist/shared/dashboards-app-install.js.map +1 -0
- package/dist/shared/dashboards-app.helpers.d.ts +42 -0
- package/dist/shared/dashboards-app.helpers.d.ts.map +1 -0
- package/dist/shared/dashboards-app.helpers.js +143 -0
- package/dist/shared/dashboards-app.helpers.js.map +1 -0
- package/dist/work-queue-dashboards.module.d.ts +23 -0
- package/dist/work-queue-dashboards.module.d.ts.map +1 -0
- package/dist/work-queue-dashboards.module.js +92 -0
- package/dist/work-queue-dashboards.module.js.map +1 -0
- package/package.json +73 -66
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing-explorer.component.js","sourceRoot":"","sources":["../../../src/Testing/components/testing-explorer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAIT,uBAAuB,EAEvB,KAAK,EACN,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAA4E,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACzI,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAErE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;;;;;;;;;;;IAkF/D,wBAAyD;;;IAAzD,yGAA0C;;;;IAA3B,6CAAyB;;;IAyDtC,wBAAyD;;;;IA9CvD,AARF,AADF,sCAAgB,wBAI4B,aAK9B;IACR,mCAIgB;IAClB,iBAAM;IAEJ,AADF,8BAAa,gBAC2D;IAAvB,4LAAS,mBAAY,KAAC;IACnE,uBAAuC;IAAC,+BAA+B;IAAA,yBAAS;IAClF,AADkF,iBAAO,EAChF;IACT,iCAAmE;IAAtB,4LAAS,kBAAW,KAAC;IAChE,yBAAgC;IAAC,gCAA+B;IAAA,yBAAQ;IAE5E,AADE,AAD0E,iBAAO,EACxE,EACL;IAOJ,AANF,gCAAa,0BASkC;IAA3C,uNAAe,iCAA0B,KAAC;IAC5C,iBAAiB;IACjB,8CAK0C;IAAxC,gOAAqB,wBAAiB,KAAC;IACvC,4CAI8B;IAA5B,AADA,0NAAgB,mCAA4B,KAAC,yLACpC,wBAAiB,KAAC;IAE/B,AADE,iBAAkB,EACA;IACpB,2CAG0C;IAAxC,mNAAa,0BAAyB,KAAC;IAG7C,AADE,AADE,iBAAiB,EACb,EACS;IACjB,2GAA0C;IAC5C,iBAAiB;;;;IA7CT,eAA6B;IAC7B,AADA,kDAA6B,gCACL;IAoBxB,gBAAoB;IAApB,yCAAoB;IAMpB,cAAsC;IACtC,AADA,2DAAsC,mDACK;IAGzC,cAAuB;IACvB,AADA,4CAAuB,+BACA;IAMzB,cAA6B;IAC7B,AADA,kDAA6B,8BACP;IAKb,cAAyB;IAAzB,6CAAyB;;;IAUxC,+BAA8B;IAC5B,iCAAyD;IAC3D,iBAAM;;;IAqCgB,2BAA6B;IAC7B,YACF;;;;IADE,cACF;IADE,yFACF;;;IAGA,wBAA6F;;;;;IAAjE,4GAA4D;;;IA2BpF,+BAA8B;IAC5B,2BAAiF;IACjF,gCAAgC;IAAA,YAAgB;IAAA,iBAAO;IACvD,gCAAiE;IAAA,YAAqC;IAAA,iBAAO;IAC7G,gCAA0B;IACxB,2BAAuH;IACzH,iBAAO;IACP,gCAA6E;IAAA,YAAkB;IACjG,AADiG,iBAAO,EAClG;;;;IAPsB,cAA+C;;IACzC,eAAgB;IAAhB,mCAAgB;IACpB,cAAoC;IAApC,mDAAoC;IAAC,cAAqC;IAArC,iEAAqC;IAEjC,eAA4C;IAA5C,2DAA4C;IAAhF,kDAAmC;IAEvC,cAA+C;;IAAC,cAAkB;IAAlB,qCAAkB;;;IARnG,gLAAa;;;IAAb,6CAUC;;;IAGD,+BAA0B;IAAA,YAA6C;IAAA,iBAAM;;;IAAnD,cAA6C;IAA7C,yEAA6C;;;IAf3E,+BAAgC;IAC9B,0KAYC;IACD,wKAAmC;IAGrC,iBAAM;;;IAhBJ,cAYC;IAZD,6BAYC;IACD,eAEC;IAFD,yDAEC;;;;IArDH,AADF,AADF,+BAAwB,cACG,cACK;IAE1B,AADA,wBAA4D,eACyB;;IACrF,gCAA2E;IAAA,YAAkB;IAC/F,AAD+F,iBAAO,EAChG;IACN,+BAA2B;IACzB,YACA;IAAA,gJAAyB;IAI3B,iBAAM;IACN,yJAAyB;IAG3B,iBAAM;IAIF,AADF,AADF,gCAAwB,eACJ,gBACS;IAAA,0BAAS;IAAA,iBAAO;IACzC,iCAAuE;IAAA,aAAmC;IAC5G,AAD4G,iBAAO,EAC7G;IAEJ,AADF,gCAAkB,gBACS;IAAA,sBAAK;IAAA,iBAAO;IACrC,iCAAyB;IAAA,aAAqB;IAChD,AADgD,iBAAO,EACjD;IAEJ,AADF,gCAAkB,gBACS;IAAA,0BAAS;IAAA,iBAAO;IACzC,iCAAiE;IAAA,aAAwC;IAC3G,AAD2G,iBAAO,EAC5G;IAEJ,AADF,gCAAkB,gBACS;IAAA,6BAAY;IAAA,iBAAO;IAC5C,iCAAyB;IAAA,aAAuC;IAEpE,AADE,AADkE,iBAAO,EACnE,EACF;IAEN,2JAA8B;IAsB5B,AADF,gCAA0B,kBAC4C;IAA7B,yQAAS,4BAAkB,KAAC;IACjE,yBAAgC;IAAC,4BACnC;IAAA,iBAAS;IACT,mCAA8E;IAArC,yQAAS,oCAA0B,KAAC;IAC3E,yBAAqC;IAAC,0BACxC;IAAA,iBAAS;IACT,mCAAyF;IAAhD,yQAAS,gBAAS,iBAAiB,cAAW,KAAC;IACtF,yBAA+B;IAAC,uBAClC;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;;IAlEwB,eAAqD;IAArD,sGAAqD;IAClD,eAA+C;;IAAC,cAAkB;IAAlB,qCAAkB;IAG7F,eACA;IADA,yDACA;IAAA,cAGC;IAHD,gDAGC;IAEH,cAEC;IAFD,gDAEC;IAM0B,eAA6C;IAA7C,4DAA6C;IAAC,cAAmC;IAAnC,6DAAmC;IAIjF,eAAqB;IAArB,wCAAqB;IAIrB,eAAuC;IAAvC,sDAAuC;IAAC,cAAwC;IAAxC,oEAAwC;IAIhF,eAAuC;IAAvC,iEAAuC;IAIpE,cAmBC;IAnBD,qDAmBC;;;IAhEP,AADF,+BAA6B,aACD;IACxB,wBAAkC;IAClC,6BACA;IAAA,gCAA4B;IAAA,YAA2B;IACzD,AADyD,iBAAO,EAC3D;IACL,+BAAuB;IACrB,sJAwEC;IAEL,AADE,iBAAM,EACF;;;IA7E0B,eAA2B;IAA3B,kDAA2B;IAGvD,eAwEC;IAxED,oCAwEC;;;IAhFP,qIAAiC;;;IAAjC,2DAmFC;;;IAwBe,2BAA6B;IAC7B,YACF;;;IADE,cACF;IADE,mDACF;;;IAGA,wBAA4F;;;;;IAAhE,4GAA2D;;;IAIrF,gCAAwB;IAAA,wBAAiC;IAAC,YAAmB;IAAA,iBAAO;;;IAA1B,eAAmB;IAAnB,6CAAmB;;;IAG7E,gCAAwB;IAAA,wBAAiC;IAAC,YAA8C;IAAA,iBAAO;;;;IAArD,eAA8C;IAA9C,+EAA8C;;;IAGxG,gCAAwB;IAAA,wBAAuC;IAAC,YAA8B;IAAA,iBAAO;;;;IAArC,eAA8B;IAA9B,+DAA8B;;;IAQ1F,gCAAkB;IAAA,YAAS;IAAA,iBAAO;;;IAAhB,cAAS;IAAT,6BAAS;;;IAD7B,+KAAa;;;IAAb,8CAEC;;;IAGD,gCAA2B;IAAA,YAA2B;IAAA,iBAAO;;;IAAlC,cAA2B;IAA3B,oDAA2B;;;IAP1D,+BAAuB;IACrB,4LAIC;IACD,yKAA4B;IAG9B,iBAAM;;;IARJ,cAIC;IAJD,4BAIC;IACD,eAEC;IAFD,mDAEC;;;;IApCL,AADF,AADF,+BAAuB,cACI,cACK;IAE1B,AADA,wBAAoD,eACgC;;IACpF,gCAA0E;IAAA,YAAiB;IAC7F,AAD6F,iBAAO,EAC9F;IACN,+BAA2B;IACzB,YACA;IAAA,gJAAsB;IAIxB,iBAAM;IACN,yJAAwB;IAGxB,gCAA2B;IACzB,4JAAqB;IAGrB,4JAA4B;IAG5B,4JAAwB;IAGxB,iCAAwB;IAAA,yBAAoC;IAAC,aAAwC;IACvG,AADuG,iBAAO,EACxG;IACN,2JAA4B;IAY9B,iBAAM;IAIF,AADF,AADF,gCAAwB,eACJ,gBACS;IAAA,4BAAW;IAAA,iBAAO;IAC3C,iCAA2F;IAAA,aAAiC;IAC9H,AAD8H,iBAAO,EAC/H;IAEJ,AADF,gCAAkB,gBACS;IAAA,sBAAK;IAAA,iBAAO;IACrC,iCAAiE;IAAA,aAA0E;IAC7I,AAD6I,iBAAO,EAC9I;IAEJ,AADF,gCAAkB,gBACS;IAAA,2BAAU;IAAA,iBAAO;IAC1C,iCAAyB;IAAA,aAAoB;IAC/C,AAD+C,iBAAO,EAChD;IAEJ,AADF,gCAAkB,gBACS;IAAA,0BAAS;IAAA,iBAAO;IACzC,iCAAsE;IAAA,aAA+D;IAEzI,AADE,AADuI,iBAAO,EACxI,EACF;IAGJ,AADF,gCAA0B,kBAC0C;IAA3B,0QAAS,2BAAgB,KAAC;IAC/D,yBAAgC;IAAC,sBACnC;IAAA,iBAAS;IACT,mCAA4E;IAAnC,0QAAS,mCAAwB,KAAC;IACzE,yBAAmC;IAAC,0BACtC;IAAA,iBAAS;IACT,mCAAkF;IAAzC,0QAAS,gBAAS,WAAW,cAAU,KAAC;IAC/E,yBAA+B;IAAC,uBAClC;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;;IArEwB,eAAoD;IAApD,sGAAoD;IACjD,eAA8C;;IAAC,cAAiB;IAAjB,qCAAiB;IAG3F,eACA;IADA,kDACA;IAAA,cAGC;IAHD,8CAGC;IAEH,cAEC;IAFD,gDAEC;IAEC,eAEC;IAFD,6CAEC;IACD,cAEC;IAFD,oDAEC;IACD,cAEC;IAFD,gDAEC;IAC4D,eAAwC;IAAxC,yEAAwC;IAEvG,cAWC;IAXD,oDAWC;IAMsC,eAAqD;;IAAC,cAAiC;IAAjC,qDAAiC;IAInG,eAAuC;IAAvC,uDAAuC;IAAC,cAA0E;IAA1E,kGAA0E;IAIlH,eAAoB;IAApB,wCAAoB;IAIpB,eAA4C;IAA5C,4DAA4C;IAAC,cAA+D;IAA/D,8FAA+D;;;IAjE/I,AADF,+BAA6B,aACD;IACxB,wBAAgC;IAChC,uBACA;IAAA,gCAA4B;IAAA,YAA0B;IACxD,AADwD,iBAAO,EAC1D;IACL,+BAAuB;IACrB,sJA2EC;IAEL,AADE,iBAAM,EACF;;;IAhF0B,eAA0B;IAA1B,iDAA0B;IAGtD,eA2EC;IA3ED,mCA2EC;;;IAnFP,qIAAgC;;;IAAhC,0DAsFC;;;IAKD,qCAEoD;;;;IArM1D,uCAS2C;IAAzC,AADA,AADA,0OAAmB,oCAA6B,KAAC,qNAClC,+BAAwB,KAAC,qNACzB,+BAAwB,KAAC;IAC1C,iBAAc;IAGZ,AADF,2CAAqB,4BACI;IAErB,4GAAyD;IAwFzD,4GAAwD;IA2FxD,kIAAiE;IAMrE,AADE,iBAAwB,EACJ;;;IAlMpB,AADA,AADA,AADA,AADA,6CAAwB,gCACA,sCACM,qBACV,mCACO;IASzB,eAqFC;IArFD,0FAqFC;IAGD,cAwFC;IAxFD,yFAwFC;IAGD,cAIC;IAJD,kGAIC;;;;IAOP,+BAAyD;IAA1B,yMAAS,sBAAe,KAAC;IAAC,iBAAM;;;IA0CzD,+BAA4B;IAC1B,yBAA8C;IAC9C,4BAAM;IAAA,YAAsB;IAC9B,AAD8B,iBAAO,EAC/B;;;IADE,eAAsB;IAAtB,6CAAsB;;;IAoClB,kCAAwB;IAAA,YAAa;IAAA,iBAAS;;;IAAtC,iCAAe;IAAC,cAAa;IAAb,iCAAa;;;;IAJzC,AADF,+BAAwB,gBACI;IAAA,0BAAU;IAAA,gCAA4B;IAAA,iBAAC;IAAO,AAAP,iBAAO,EAAQ;IAChF,kCAAoD;IAAzB,oVAAwB;IACjD,mCAA0B;IAAA,8BAAc;IAAA,iBAAS;IACjD,0IAEC;IAEL,AADE,iBAAS,EACL;;;IANuB,eAAwB;IAAxB,iDAAwB;IAEjD,eAEC;IAFD,kCAEC;;;IAUC,kCAAuB;IAAA,YAAY;IAAA,iBAAS;;;IAApC,gCAAc;IAAC,cAAY;IAAZ,gCAAY;;;;IAJvC,AADF,+BAAwB,gBACI;IAAA,4BAAY;IAAA,iBAAQ;IAC9C,kCAA2D;IAAhC,kWAA+B;IACxD,mCAAiB;IAAA,gCAAgB;IAAA,iBAAS;IAC1C,0IAEC;IAEL,AADE,iBAAS,EACL;;;IANuB,eAA+B;IAA/B,wDAA+B;IAExD,eAEC;IAFD,+BAEC;;;IAQD,kCAAyB;IAAA,YAAY;IAAA,iBAAS;;;IAAtC,kCAAgB;IAAC,cAAY;IAAZ,gCAAY;;;;IAS3C,AADF,+BAA0B,cACQ;IAAA,yBAAS;IAAA,iBAAM;IAG3C,AADF,AADF,+BAAsB,cACI,gBACI;IAAA,kCAAkB;IAAA,iBAAQ;IACpD,kCAME;IAHA,6VAA6B;IAIjC,AAPE,iBAME,EACE;IAEJ,AADF,+BAAwB,gBACI;IAAA,2BAAU;IAAA,iBAAQ;IAC5C,mCAOE;IAJA,sVAAyB;IAOjC,AADE,AADE,AARE,iBAOE,EACE,EACF,EACF;;;IAjBE,eAA6B;IAA7B,sDAA6B;IAU7B,eAAyB;IAAzB,kDAAyB;;;IA6B/B,wBAA2C;;;IAE3C,yBAAiC;;;;IAlJrC,AADF,AAFF,+BAAgC,cAED,cACK;IAC9B,wBAA2D;IAC3D,gCAAkC;IAChC,YACF;IACF,AADE,iBAAO,EACH;IACN,kCAA6D;IAA1B,4MAAS,sBAAe,KAAC;IAC1D,wBAAiC;IAErC,AADE,iBAAS,EACL;IAIJ,AADF,+BAAkC,iBAK/B;IADC,4MAAS,6BAAsB,MAAM,CAAC,KAAC;IAEvC,yBAAgC;IAAC,uBACnC;IAAA,iBAAS;IACT,mCAIC;IADC,6MAAS,6BAAsB,OAAO,CAAC,KAAC;IAExC,yBAAkC;IAAC,wBACrC;IACF,AADE,iBAAS,EACL;IAGN,yHAAwB;IAUpB,AADF,AADF,gCAA2B,eACC,eACQ;IAAA,wBAAO;IAAA,iBAAM;IAG3C,AADF,gCAAwB,iBACI;IAAA,sBAAK;IAAA,iCAA4B;IAAA,kBAAC;IAAO,AAAP,iBAAO,EAAQ;IAC3E,kCAKE;IAFA,iUAAsB;IAG1B,AANE,iBAKE,EACE;IAGJ,AADF,gCAAwB,iBACI;IAAA,4BAAW;IAAA,iBAAQ;IAC7C,qCAKC;IAHC,kVAA6B;IAIjC,AADG,iBAAW,EACR;IAEN,gCAAsB;IACpB,0HAAqC;IAWrC,yHAAsC;IAYpC,AADF,gCAAwB,iBACI;IAAA,uBAAM;IAAA,iBAAQ;IACxC,mCAAoD;IAAzB,sUAAwB;IACjD,+IAEC;IAIT,AADE,AADE,AADE,iBAAS,EACL,EACF,EACF;IAEN,0HAAqC;IA8BnC,AADF,gCAA0B,eACQ;IAAA,qBAAI;IAAA,iBAAM;IAExC,AADF,gCAAwB,iBAMpB;IAFA,iUAAsB;IAHxB,iBAKE;IACF,iCAAwB;IAAA,mDAAkC;IAGhE,AADE,AADE,AAD4D,iBAAO,EAC7D,EACF,EACF;IAIJ,AADF,gCAA6B,kBACiC;IAA1B,6MAAS,sBAAe,KAAC;IAAC,uBAAM;IAAA,iBAAS;IAC3E,mCAA2F;IAA3D,6MAAS,iBAAU,KAAC;IAGhD,AAFF,uHAAgB,kGAEP;IAGT,aACF;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;IApJE,eACF;IADE,oGACF;IAWA,eAA8C;IAA9C,8DAA8C;IAO9C,eAA+C;IAA/C,+DAA+C;IAQnD,eAKC;IALD,mDAKC;IAYO,gBAAsB;IAAtB,+CAAsB;IACtB,wIAAmH;IAQnH,eAA6B;IAA7B,sDAA6B;IAE7B,sIAAiH;IAKnH,eAUC;IAVD,gEAUC;IACD,cAUC;IAVD,iEAUC;IAG4B,eAAwB;IAAxB,iDAAwB;IACjD,cAEC;IAFD,uCAEC;IAMT,eA2BC;IA3BD,gEA2BC;IAQK,eAAsB;IAAtB,+CAAsB;IAWyB,eAAqC;IAArC,iEAAqC;IACxF,cAIC;IAJD,2CAIC;IACD,eACF;IADE,+FACF;;;;IAQN,2CAI6B;IAA3B,sNAAU,sBAAe,KAAC;IAC1B,gDAKiC;IAA/B,mOAAc,sBAAe,KAAC;IAElC,AADE,iBAAsB,EACP;;;IATf,gCAAkB;IAGhB,cAAkB;IAGlB,AADA,AADA,AADA,gCAAkB,uIACkD,yIACE,gIACT;;;;IApYjE,wCAA8D;IAK5D,AAJF,yGAAiB,wEAIR;IA6MX,yGAAoB;IAMlB,AADF,+BAAyF,cACf;IAApC,uMAAa,4BAAqB,KAAC;IAAC,iBAAM;IAE9E,2GAAoB;IA6JtB,iBAAM;IAGN,oHAAwC;IAetC,iBAAe;;;IAzYa,AAAd,2BAAa,kBAAkB;IAC7C,cA8MC;IA9MD,0CA8MC;IAGH,eAEC;IAFD,8CAEC;IAGuD,cAAgC;IAAhC,mDAAgC;IAA5D,2CAA2B;IAGrD,eA4JC;IA5JD,8CA4JC;IAIH,cAcC;IAdD,kEAcC;;AAssBL,MAAM,OAAO,wBAAyB,SAAQ,oBAAoB;IA8GtD;IACA;IACD;IACA;IA/GO,iBAAiB,GAAuB;QACtD,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,WAAW,EAAE;QAC7D,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,WAAW,EAAE;KAC9D,CAAC;IAEc,kBAAkB,GAAuB;QACvD,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;QAC5B,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;QAClC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;KACjC,CAAC;IAEF,yFAAyF;IAClF,kBAAkB,CAAC,KAAa;QACrC,MAAM,SAAS,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAsB,CAAC;QAC5D,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,0FAA0F;IACjF,WAAW,GAAG,KAAK,CAAC;IAErB,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAEvC,kBAAkB;IACV,QAAQ,GAAmB,EAAE,CAAC;IACtC,SAAS,GAAwB,EAAE,CAAC;IAC5B,aAAa,GAA4B,EAAE,CAAC;IACpD,YAAY,GAAuB,EAAE,CAAC;IAC9B,YAAY,GAAqB,EAAE,CAAC;IAE5C,qBAAqB;IACb,UAAU,GAAoB,EAAE,CAAC;IACjC,SAAS,GAAmB,EAAE,CAAC;IAEvC,iBAAiB;IACT,YAAY,GAAG,IAAI,eAAe,CAAS,EAAE,CAAC,CAAC;IAC/C,eAAe,GAAG,IAAI,eAAe,CAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAC9D,UAAU,GAAG,IAAI,eAAe,CAAW,MAAM,CAAC,CAAC;IACnD,aAAa,GAAG,IAAI,eAAe,CAAc,KAAK,CAAC,CAAC;IACxD,iBAAiB,GAAG,IAAI,eAAe,CAAmB,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACrF,WAAW,GAAG,IAAI,eAAe,CAAY,MAAM,CAAC,CAAC;IACrD,eAAe,GAAG,IAAI,eAAe,CAAgB,KAAK,CAAC,CAAC;IAEpE,uBAAuB;IACvB,SAAS,GAAG,IAAI,CAAC;IACjB,UAAU,GAAG,EAAE,CAAC;IAChB,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,QAAQ,GAAa,MAAM,CAAC;IAC5B,WAAW,GAAgB,KAAK,CAAC;IACjC,eAAe,GAAqB,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAC9D,SAAS,GAAc,MAAM,CAAC;IAC9B,aAAa,GAAkB,KAAK,CAAC;IAErC,mBAAmB;IACnB,cAAc,GAAoB,EAAE,CAAC;IACrC,aAAa,GAAmB,EAAE,CAAC;IACnC,iBAAiB,GAAoB,EAAE,CAAC;IACxC,iBAAiB,GAAuB,EAAE,CAAC;IAE3C,SAAS;IACT,cAAc,GAAG,CAAC,CAAC;IACnB,mBAAmB,GAAG,CAAC,CAAC;IACxB,mBAAmB,GAAG,CAAC,CAAC;IAEf,aAAa,GAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC5D,iBAAiB,GAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAEzE,gBAAgB;IACR,MAAM,CAAU,eAAe,GAAG,4BAA4B,CAAC;IAC/D,MAAM,CAAU,gBAAgB,GAAG,6BAA6B,CAAC;IACjE,MAAM,CAAU,kBAAkB,GAAG,+BAA+B,CAAC;IAE7E;;;;OAIG;IACH,aAAa,GAAG,KAAK,CAAC;IACd,sBAAsB,GAAG,IAAI,OAAO,EAAQ,CAAC;IAC7C,cAAc,GAAG,KAAK,CAAC;IAE/B,iBAAiB;IACjB,YAAY,GAAG,KAAK,CAAC;IACrB,kBAAkB,GAAqB,MAAM,CAAC;IAC9C,aAAa,GAAG,GAAG,CAAC;IACpB,QAAQ,GAAG,KAAK,CAAC;IACjB,gBAAgB,GAAG,EAAE,CAAC;IAEtB,eAAe;IACP,YAAY,GAAG,CAAC,CAAC;IACjB,gBAAgB,GAAG,CAAC,CAAC;IAE7B,cAAc;IACd,QAAQ,GAAG,EAAE,CAAC;IACd,eAAe,GAAG,EAAE,CAAC;IACrB,UAAU,GAAG,EAAE,CAAC;IAChB,UAAU,GAAsC,QAAQ,CAAC;IACzD,iBAAiB,GAAG,EAAE,CAAC;IACvB,eAAe,GAAG,CAAC,CAAC;IACpB,WAAW,GAAG,CAAC,CAAC;IAChB,QAAQ,GAAG,EAAE,CAAC;IAEd,IAAI,WAAW;QACb,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,IAAI,CAAC,kBAAkB,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QACzE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YACU,GAAsB,EACtB,gBAAkC,EACnC,oBAA0C,EAC1C,sBAAqD;QAC1D,KAAK,EAAE,CAAC;QAJF,QAAG,GAAH,GAAG,CAAmB;QACtB,qBAAgB,GAAhB,gBAAgB,CAAkB;QACnC,yBAAoB,GAApB,oBAAoB,CAAsB;QAC1C,2BAAsB,GAAtB,sBAAsB,CAA+B;IACjD,CAAC;IAEd,oDAAoD;IACpD,IAAW,oBAAoB;QAC7B,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IACD,oDAAoD;IACpD,IAAW,oBAAoB,CAAC,KAA2B;QACzD,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC;IACpC,CAAC;IAED,sDAAsD;IACtD,IAAW,sBAAsB;QAC/B,OAAO,IAAI,CAAC,sBAAsB,CAAC;IACrC,CAAC;IACD,sDAAsD;IACtD,IAAW,sBAAsB,CAAC,KAAoC;QACpE,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAC;IACtC,CAAC;IAED,8EAA8E;IAC9E,YAAY;IACZ,8EAA8E;IAE9E,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAExB,IAAI,CAAC;YACH,MAAM,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5C,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAE/B,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,IAAI,CAC/C,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB,CAAC,SAAS,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,WAAW;QACT,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACzB,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7D,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1D,cAAc,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;IACjD,CAAC;IAED,8EAA8E;IAC9E,iBAAiB;IACjB,8EAA8E;IAE9E,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9B,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,iBAAiB,CAAC,EAAU;QAC1B,OAAO,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,iBAAiB,CAAC,SAA2B;QAC3C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,cAAc,CAAC,MAAc;QAC3B,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,cAAc,CAAC,IAAiB;QAC9B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,WAAW,CAAC,IAAc;QACxB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,aAAa,CAAC,KAAY;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,MAA0B,CAAC;QAC/C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,WAAW;QACT,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,iBAAiB,CAAC,IAAmB;QACnC,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,8EAA8E;IAC9E,yBAAyB;IACzB,EAAE;IACF,4EAA4E;IAC5E,+EAA+E;IAC/E,kEAAkE;IAClE,uBAAuB;IACvB,8EAA8E;IAE9E,mDAAmD;IACnD,IAAI,WAAW;QACb,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YACpD,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,IAAI,EAAmB,CAAC;YACvF,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QAEtE,OAAO;YACL;gBACE,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE;oBACL,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE;oBAC9F,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE;iBAC3G;aACF;YACD,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE;YAC3C;gBACE,KAAK,EAAE,YAAY;gBACnB,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;oBACvC,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE;oBACvB,KAAK,EAAE,EAAE,CAAC,IAAI;oBACd,IAAI,EAAE,iBAAiB;oBACvB,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,CAAC;iBACvC,CAAC,CAAC;aACJ;SACF,CAAC;IACJ,CAAC;IAED;;kDAE8C;IACtC,kBAAkB,CAAC,IAAmB;QAC5C,OAAO;YACL,EAAE,EAAE,SAAS,IAAI,CAAC,EAAE,EAAE;YACtB,KAAK,EAAE,IAAI,CAAC,IAAI;YAChB,IAAI,EAAE,oBAAoB;YAC1B,KAAK,EAAE,IAAI,CAAC,SAAS;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;SACrE,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,IAAI,WAAW;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC;QACjC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACpD,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QACvC,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,iFAAiF;IACjF,IAAI,cAAc;QAChB,MAAM,GAAG,GAAa,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,KAAsB,EAAQ,EAAE;YAC5C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC,CAAC,QAAQ;oBAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC1C,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACnB,CAAC;QACH,CAAC,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,8EAA8E;IAC9E,gBAAgB,CAAC,IAAmB;QAClC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACnB,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;YACjB,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;aAAM,IAAI,EAAE,KAAK,YAAY,EAAE,CAAC;YAC/B,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/E,CAAC;aAAM,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,gBAAgB,CAAC,IAAmB;QAClC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;QACjE,IAAI,IAAI;YAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAEO,aAAa,CAAC,IAAqB,EAAE,EAAU;QACrD,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC;gBAAE,OAAO,IAAI,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACpD,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8EAA8E;IAC9E,6BAA6B;IAC7B,EAAE;IACF,8EAA8E;IAC9E,sEAAsE;IACtE,uEAAuE;IACvE,yDAAyD;IACzD,8EAA8E;IAE9D,gBAAgB,GAAG;QACjC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;QAC/B,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;QACrC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;KACpC,CAAC;IAEF,gDAAgD;IAChD,IAAW,gBAAgB;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAEe,oBAAoB,GAAG;QACrC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE;QACnC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE;KACtC,CAAC;IAEF,oDAAoD;IACpD,IAAW,oBAAoB;QAC7B,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,IAAW,YAAY;QACrB,OAAO;YACL,EAAE,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE;oBAC/D,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;oBAC7B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;oBACnC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;iBAClC,EAAE;YACH,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE;oBACzE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;oBACnC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;oBACrC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;iBACxC,EAAE;YACH,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS;gBACpD,IAAI,EAAE,mCAAmC,EAAE,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE;YAC7E,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;gBAC1D,IAAI,EAAE,iCAAiC,EAAE,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE;SAChF,CAAC;IACJ,CAAC;IAED,4CAA4C;IAC5C,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,IAAW,YAAY;QACrB,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;YACtC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,aAAa,EAAE,IAAI,CAAC,aAAa;SAClC,CAAC;IACJ,CAAC;IAED,4CAA4C;IAC5C,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAEM,oBAAoB,CAAC,MAA+B;QACzD,IAAI,aAAa,IAAI,MAAM,EAAE,CAAC;YAC5B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAgB,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,QAAQ,CAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YAClF,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,WAAW,IAAI,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAc,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,eAAe,IAAI,MAAM,EAAE,CAAC;YAC9B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAkB,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,oDAAoD;IAC7C,oBAAoB,CAAC,MAA+B;QACzD,OAAO,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAEM,gBAAgB;QACrB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,gDAAgD;IACzC,gBAAgB;QACrB,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;IAED,mEAAmE;IAC5D,eAAe;QACpB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,GAAG,EAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED,+CAA+C;IACxC,eAAe;QACpB,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;IAChC,CAAC;IAED,mFAAmF;IACnF,IAAW,qBAAqB;QAC9B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM;YAAE,KAAK,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,aAAa,KAAK,KAAK;YAAE,KAAK,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oFAAoF;IACpF,IAAW,sBAAsB;QAC/B,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAClF,CAAC;IAGD,OAAO,CAAC,MAAc;QACpB,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,QAAQ,CAAC,OAAe;QACtB,IAAI,CAAC,oBAAoB,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,aAAa;QACX,IAAI,CAAC,oBAAoB,CAAC,UAAU,EAAE,CAAC;QACvC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,QAAQ,CAAC,UAAkB,EAAE,EAAU;QACrC,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,UAAU,EAAE,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACpI,CAAC;IAED,eAAe,CAAC,MAAc;QAC5B,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,gBAAgB,CAAC,OAAe;QAC9B,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED,SAAS;QACP,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,UAAU;QACR,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,YAAY,CAAC,IAAsB;QACjC,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,aAAa;QACX,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,qBAAqB,CAAC,IAAsB;QAC1C,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAE/C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAExB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,kBAAkB,KAAK,MAAM,EAAE,CAAC;gBACvC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,MAAM,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC;YACvF,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,aAAa,CAAC,KAAiB;QAC7B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,aAAa,CAAC;QAC3C,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1D,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACvD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;IAC1C,CAAC;IAEO,YAAY,GAAG,CAAC,KAAiB,EAAQ,EAAE;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,CAAC,CAAC;QACjF,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC,CAAC;IAEM,WAAW,GAAG,GAAS,EAAE;QAC/B,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7D,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1D,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;QACpC,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CACzC,wBAAwB,CAAC,eAAe,EACxC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAC3B,CAAC;IACJ,CAAC,CAAC;IAEF,mBAAmB,CAAC,MAAc;QAChC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;IACvE,CAAC;IAED,8EAA8E;IAC9E,qBAAqB;IACrB,8EAA8E;IAE9E,cAAc,CAAC,EAAU;QACvB,IAAI,EAAE,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,EAAE,GAAG,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;QAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC;QAClC,IAAI,OAAO,GAAG,CAAC;YAAE,OAAO,GAAG,OAAO,KAAK,OAAO,GAAG,CAAC;QAClD,OAAO,GAAG,OAAO,GAAG,CAAC;IACvB,CAAC;IAED,qBAAqB,CAAC,OAAe;QACnC,IAAI,OAAO,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,OAAO,GAAG,EAAE,CAAC;QAC1B,IAAI,OAAO,GAAG,CAAC;YAAE,OAAO,GAAG,OAAO,KAAK,IAAI,GAAG,CAAC;QAC/C,OAAO,GAAG,IAAI,GAAG,CAAC;IACpB,CAAC;IAED,kBAAkB,CAAC,IAAiB;QAClC,IAAI,CAAC,IAAI;YAAE,OAAO,OAAO,CAAC;QAC1B,MAAM,CAAC,GAAG,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;QAE/C,IAAI,WAAW,GAAG,CAAC;YAAE,OAAO,UAAU,CAAC;QACvC,IAAI,WAAW,GAAG,EAAE;YAAE,OAAO,GAAG,WAAW,OAAO,CAAC;QACnD,IAAI,SAAS,GAAG,EAAE;YAAE,OAAO,GAAG,SAAS,OAAO,CAAC;QAC/C,IAAI,QAAQ,GAAG,EAAE;YAAE,OAAO,GAAG,QAAQ,OAAO,CAAC;QAC7C,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,aAAa,CAAC,KAAa;QACzB,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;IACjC,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,IAAI,IAAI,GAAG,IAAI;YAAE,OAAO,OAAO,CAAC;QAChC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/B,CAAC;IAED,aAAa,CAAC,KAAa;QACzB,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,MAAM,CAAC;QAChC,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,MAAM,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,cAAc,CAAC,MAAc;QAC3B,QAAQ,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7B,KAAK,QAAQ,CAAC,CAAC,OAAO,eAAe,CAAC;YACtC,KAAK,QAAQ,CAAC,CAAC,OAAO,eAAe,CAAC;YACtC,KAAK,OAAO,CAAC,CAAC,OAAO,cAAc,CAAC;YACpC,KAAK,SAAS,CAAC,CAAC,OAAO,gBAAgB,CAAC;YACxC,OAAO,CAAC,CAAC,OAAO,gBAAgB,CAAC;QACnC,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,wBAAwB;IACxB,8EAA8E;IAEtE,kBAAkB;QACxB,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC;QAC3C,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAiB;YAC9C,UAAU,EAAE,eAAe;YAC3B,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,CAAC;YAClF,OAAO,EAAE,gBAAgB;YACzB,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,CAAC;IAED,8EAA8E;IAC9E,2BAA2B;IAC3B,8EAA8E;IAEtE,eAAe;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;IAClF,CAAC;IAEO,oBAAoB,CAAC,KAAwB;QACnD,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACzF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAE1E,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/F,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC;YACtC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM;YAC5E,CAAC,CAAC,CAAC,CAAC;QACN,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QACvD,MAAM,YAAY,GAAG,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;QAEjE,OAAO;YACL,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;YACpC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,SAAS,EAAE,OAAO,CAAC,IAAI;YACvB,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,WAAW;YACxB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;YAChC,KAAK,EAAE,YAAY;YACnB,iBAAiB,EAAE,OAAO,CAAC,IAAI;SAChC,CAAC;IACJ,CAAC;IAEO,sBAAsB,CAAC,cAAuC;QACpE,OAAO,cAAc;aAClB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;aACvC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,EAAE,CAAC,EAAE;YACR,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;YAClE,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YACnD,OAAO;gBACL,MAAM,EAAE,EAAE,CAAC,MAAM;gBACjB,QAAQ,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,SAAS;gBAC5C,UAAU,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;gBACjC,SAAS,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;aAC/B,CAAC;QACJ,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,CAAC;IAEO,mBAAmB,CAAC,IAAkB;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACjF,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,sBAAsB;QACtF,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;QAClE,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7F,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;QACxF,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAErD,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,QAAQ;YAClB,SAAS,EAAE,SAAS;YACpB,aAAa,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;YACpC,SAAS,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;YAC9B,SAAS,EAAE,WAAW,CAAC,MAAM;YAC7B,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,IAAI,CAAC,wBAAwB,IAAI,CAAC;YAC/C,OAAO,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC;YACnC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;YAC5D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;YAC/B,SAAS,EAAE,IAAI,CAAC,cAAc;SAC/B,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,4BAA4B;IAC5B,8EAA8E;IAEtE,cAAc;QACpB,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;QAEtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;QAEjD,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE;gBACpB,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM;gBACnF,QAAQ,EAAE,EAAE;gBACZ,QAAQ,EAAE,KAAK;aAChB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,KAAK,GAAoB,EAAE,CAAC;QAClC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACrB,IAAI,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAChD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,YAAY,CAAC;IAC7C,CAAC;IAED,8EAA8E;IAC9E,+BAA+B;IAC/B,8EAA8E;IAEtE,uBAAuB;QAC7B,aAAa,CAAC;YACZ,IAAI,CAAC,YAAY;YACjB,IAAI,CAAC,eAAe;YACpB,IAAI,CAAC,aAAa;YAClB,IAAI,CAAC,iBAAiB;YACtB,IAAI,CAAC,WAAW;YAChB,IAAI,CAAC,eAAe;YACpB,IAAI,CAAC,UAAU;SAChB,CAAC,CAAC,IAAI,CACL,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,EAAE;YAC5G,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC7B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;YACnC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;YAC/B,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;YACvC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;YAC3B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;YACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACzB,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,YAAY;QAClB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5C,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;IACpF,CAAC;IAEO,gBAAgB;QACtB,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,MAAM,GAAG,IAAI,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACrC,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,eAAe;QACrB,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,0BAA0B,CAAC,MAAuB;QACxD,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC;QACjC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,OAAO;gBACV,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACtD,KAAK,YAAY;gBACf,OAAO,EAAE,CAAC,CAAC,0BAA0B;YACvC,KAAK,UAAU;gBACb,OAAO,EAAE,CAAC,CAAC,iCAAiC;YAC9C;gBACE,OAAO,MAAM,CAAC;QAClB,CAAC;IACH,CAAC;IAEO,yBAAyB,CAAC,KAAqB;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC;QACjC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CACrF,CAAC;gBACF,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9C,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;gBACzE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACvD,CAAC;YACD,KAAK,UAAU;gBACb,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;oBACtB,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACrE,OAAO,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChD,CAAC,CAAC,CAAC;YACL;gBACE,OAAO,KAAK,CAAC;QACjB,CAAC;IACH,CAAC;IAEO,yBAAyB,CAAC,MAAuB;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAClD,IAAI,CAAC,IAAI;YAAE,OAAO,MAAM,CAAC;QACzB,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACvB,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YACnC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAC3C,CAAC;IACJ,CAAC;IAEO,wBAAwB,CAAC,KAAqB;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAClD,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACtB,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YACnC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAC3C,CAAC;IACJ,CAAC;IAEO,yBAAyB,CAAC,MAAuB;QACvD,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;QACjD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC;IAEO,wBAAwB,CAAC,KAAqB;QACpD,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAChD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,CAAC;IAEO,cAAc,CAAC,MAAuB;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/H,CAAC;IAEO,aAAa,CAAC,KAAqB;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1H,CAAC;IAEO,kBAAkB,CACxB,KAAa,EAAE,OAAe,EAAE,KAAkB,EAClD,KAAa,EAAE,OAAe,EAAE,KAAkB,EAClD,GAAW;QAEX,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;YACvB,KAAK,MAAM;gBACT,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;YAC1C,KAAK,QAAQ;gBACX,OAAO,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC;YAC9C,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC;YAC/B,CAAC;YACD;gBACE,OAAO,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,mBAAmB;IACnB,8EAA8E;IAEtE,aAAa;QACnB,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QACxF,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;IACrE,CAAC;IAEO,kBAAkB,CAAC,IAAsB;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC;QACjF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAErC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;YACjD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAY,CAAC,CAAC,OAAO,EAAE,CAAC;YAClD,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;QAC7B,CAAC,EAAE,CAAC,CAAC,CAAC;QAEN,OAAO,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC;IACpC,CAAC;IAEO,eAAe,CAAC,IAAsB;QAC5C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACnC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAEO,kBAAkB,CAAC,MAAc;QACvC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC;IAC3E,CAAC;IAEO,oBAAoB,CAAC,MAAc;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5E,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;IAC9C,CAAC;IAEO,SAAS,CAAC,QAAuB;QACvC,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACpC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,KAA2B;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,OAAO,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IACzD,CAAC;IAED,8EAA8E;IAC9E,yBAAyB;IACzB,8EAA8E;IAEtE,gBAAgB;QACtB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC;YAC9F,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACrC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;oBAClD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;gBAC7B,CAAC;YACH,CAAC;YACD,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;YAC/F,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAA2B,CAAC;gBAC7D,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;oBACrB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;oBACnC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,KAAK,MAAM,CAAC;QAClH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,iDAAiD,EAAE,KAAK,CAAC,CAAC;QACzE,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAEO,wBAAwB;QAC9B,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAC9B,YAAY,CAAC,GAAG,CAAC,EACjB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB,CAAC,SAAS,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,0FAA0F;IAC1F,qBAAqB,CAAC,SAAkB;QACtC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO;QACjC,IAAI,CAAC;YACH,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CACzC,wBAAwB,CAAC,kBAAkB,EAC3C,MAAM,CAAC,SAAS,CAAC,CAClB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,2DAA2D,EAAE,KAAK,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO;QACjC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;YAC9C,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CACzC,wBAAwB,CAAC,gBAAgB,EACzC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CACtB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,mDAAmD,EAAE,KAAK,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,2BAA2B;IAC3B,8EAA8E;IAEtE,SAAS;QACf,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,WAAW;QACvB,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,eAAe,CAAe,WAAW,CAAC,CAAC;QACjE,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;QACvD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;QAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC;YAAE,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,eAAe,CAAC;QACnF,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC;YAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC;QACnE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnF,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC7F,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,eAAe,CAAoB,iBAAiB,CAAC,CAAC;QAC7E,KAAK,CAAC,SAAS,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAClC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;QACxD,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;QAC/B,IAAI,IAAI,CAAC,iBAAiB;YAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACpE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnF,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACnG,CAAC;kHA5kCU,wBAAwB;6DAAxB,wBAAwB;YA9oC/B,AAFF,gGAAmB,8EAEV;YA4DT,2HAAsB;;YA9DtB,yCA4DC;;;iFAolCQ,wBAAwB;cArpCpC,SAAS;6BACI,KAAK,YACP,sBAAsB,mBACf,uBAAuB,CAAC,MAAM,YACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8cT;;kBAutBA,KAAK;;kFApBK,wBAAwB","sourcesContent":["import {\n Component,\n OnInit,\n OnDestroy,\n ChangeDetectorRef,\n ChangeDetectionStrategy,\n ViewContainerRef,\n Input\n} from '@angular/core';\nimport { ViewToggleOption, MJLeftNavItem, MJLeftNavSection, FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport { Subject, BehaviorSubject, combineLatest } from 'rxjs';\nimport { takeUntil, debounceTime } from 'rxjs/operators';\nimport { RunView, CompositeKey } from '@memberjunction/core';\nimport { MJTestEntity, MJTestSuiteEntity, MJTestSuiteTestEntity, MJTestTypeEntity, UserInfoEngine } from '@memberjunction/core-entities';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { TestingDialogService } from '@memberjunction/ng-testing';\nimport { TestEngineBase } from '@memberjunction/testing-engine-base';\nimport { TestingInstrumentationService } from '../services/testing-instrumentation.service';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\n// ---------------------------------------------------------------------------\n// Interfaces\n// ---------------------------------------------------------------------------\n\ninterface SuiteCardData {\n ID: string;\n Name: string;\n Description: string;\n Status: string;\n TestCount: number;\n PassRate: number;\n AvgScore: number;\n AvgDuration: number; // ms\n LastRunDate: Date | null;\n Tags: string[];\n Tests: SuiteTestItem[]; // first 4-5 for preview\n TotalTestsInSuite: number;\n}\n\ninterface SuiteTestItem {\n TestID: string;\n TestName: string;\n LastStatus: string;\n LastScore: number;\n}\n\ninterface TestCardData {\n ID: string;\n Name: string;\n Description: string;\n Status: string;\n TypeName: string;\n SuiteName: string;\n LastRunStatus: string;\n LastScore: number;\n TotalRuns: number;\n PassRate: number;\n EstDuration: number; // seconds\n EstCost: number;\n LastRunDate: Date | null;\n Tags: string[];\n UpdatedAt: Date;\n}\n\ninterface SidebarSelection {\n Type: 'all' | 'standalone' | 'suite' | 'testType';\n ID: string | null;\n}\n\ninterface SuiteTreeNode {\n ID: string;\n Name: string;\n ParentID: string | null;\n TestCount: number;\n Children: SuiteTreeNode[];\n Expanded: boolean;\n}\n\ntype DisplayMode = 'all' | 'suites' | 'tests';\ntype ViewMode = 'card' | 'list';\ntype SortField = 'name' | 'updated' | 'status';\ntype SortDirection = 'asc' | 'desc';\n\n/** Simple result type for test run stats queries */\ninterface TestRunStatRow {\n ID: string;\n TestID: string;\n Status: string;\n Score: number;\n CostUSD: number;\n StartedAt: string | Date;\n CompletedAt: string | Date | null;\n}\n\n@Component({\n standalone: false,\n selector: 'app-testing-explorer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (HideToolbar) {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n } @else {\n <mj-page-layout>\n <mj-page-header\n Title=\"Test Explorer\"\n Icon=\"fa-solid fa-compass\"\n Subtitle=\"Browse tests and test suites\">\n <!-- X-of-Y filtered count earns its meta spot per chrome conventions §2.\n TotalItemCount and FilteredResultCount are both kept in sync by\n the component as the rail selection / status chips / search input\n narrow the data. -->\n <div meta>\n <mj-stat-badge\n [Count]=\"FilteredResultCount\"\n [Total]=\"TotalItemCount\"\n Label=\"results\">\n </mj-stat-badge>\n </div>\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"OnNewSuite()\">\n <i class=\"fa-solid fa-folder-plus\"></i> <span class=\"action-btn-label\">New Suite</span>\n </button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewTest()\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"action-btn-label\">New Test</span>\n </button>\n </div>\n <div toolbar>\n <!-- Concise-chrome control bar: search · Filter · view, together.\n Search is persistent wayfinding (never a filter field); all\n filters live behind the one Filter button (docks as a bottom\n sheet on mobile); applied filters render as removable chips\n below the bar (see <mj-applied-filters>). -->\n <mj-page-search\n Placeholder=\"Search tests and suites...\"\n [Value]=\"SearchTerm\"\n (ValueChange)=\"OnSearchInputValue($event)\">\n </mj-page-search>\n <mj-filter-popover\n Label=\"Filters\"\n Icon=\"fa-solid fa-filter\"\n [ActiveCount]=\"TotalActiveFilterCount\"\n [ShowClearAll]=\"TotalActiveFilterCount > 0\"\n (ClearAllRequested)=\"resetAllFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterValuesChange($event)\"\n (Reset)=\"resetAllFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n <mj-view-toggle\n [Options]=\"HeaderViewOptions\"\n [ActiveKey]=\"ViewMode\"\n (KeyChange)=\"SetViewMode($any($event))\">\n </mj-view-toggle>\n </div>\n </mj-page-header>\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </mj-page-layout>\n }\n\n <ng-template #content>\n <!-- Shared chrome primitives instead of bespoke wrappers: mj-page-body\n (row) is the rail+content layout, mj-page-body-interior is the\n scroller. Both reflow / scroll correctly on mobile. -->\n <mj-page-body [Flex]=\"true\" [Padding]=\"false\" Direction=\"row\">\n @if (IsLoading) {\n <div class=\"explorer-loading\">\n <mj-loading text=\"Loading test explorer...\"></mj-loading>\n </div>\n } @else {\n <mj-left-nav\n MobileTitle=\"Browse Tests\"\n [Sections]=\"NavSections\"\n [ActiveId]=\"ActiveNavId\"\n [ExpandedIds]=\"ExpandedNavIds\"\n [Collapsible]=\"true\"\n [Collapsed]=\"RailCollapsed\"\n (CollapsedChange)=\"OnRailCollapsedChange($event)\"\n (ItemClicked)=\"OnNavItemClicked($event)\"\n (ItemToggled)=\"OnNavItemToggled($event)\">\n </mj-left-nav>\n\n <mj-left-nav-content>\n <mj-page-body-interior>\n <!-- Suites Section -->\n @if (DisplayMode === 'all' || DisplayMode === 'suites') {\n @if (FilteredSuites.length > 0) {\n <div class=\"content-section\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-folder\"></i>\n Test Suites\n <span class=\"section-count\">{{ FilteredSuites.length }}</span>\n </h3>\n <div class=\"card-grid\">\n @for (suite of FilteredSuites; track suite.ID) {\n <div class=\"suite-card\">\n <div class=\"card-header\">\n <div class=\"card-title-row\">\n <i class=\"fa-solid fa-folder-open card-icon suite-icon\"></i>\n <span class=\"card-name\" [innerHTML]=\"suite.Name | highlightSearch:SearchTerm\"></span>\n <span class=\"status-badge\" [attr.data-status]=\"suite.Status.toLowerCase()\">{{ suite.Status }}</span>\n </div>\n <div class=\"card-subtitle\">\n {{ suite.TestCount }} tests\n @if (suite.LastRunDate) {\n <span class=\"dot-sep\"></span>\n Last run {{ FormatRelativeTime(suite.LastRunDate) }}\n }\n </div>\n @if (suite.Description) {\n <p class=\"card-description\" [innerHTML]=\"suite.Description | highlightSearch:SearchTerm\"></p>\n }\n </div>\n\n <div class=\"card-stats\">\n <div class=\"stat\">\n <span class=\"stat-label\">Pass Rate</span>\n <span class=\"stat-value\" [class]=\"GetScoreClass(suite.PassRate / 100)\">{{ FormatPercent(suite.PassRate) }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Tests</span>\n <span class=\"stat-value\">{{ suite.TestCount }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Avg Score</span>\n <span class=\"stat-value\" [class]=\"GetScoreClass(suite.AvgScore)\">{{ (suite.AvgScore * 100).toFixed(0) }}%</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Avg Duration</span>\n <span class=\"stat-value\">{{ FormatDuration(suite.AvgDuration) }}</span>\n </div>\n </div>\n\n @if (suite.Tests.length > 0) {\n <div class=\"card-tests-preview\">\n @for (t of suite.Tests; track t.TestID; let i = $index) {\n @if (i < 4) {\n <div class=\"preview-test-row\">\n <span class=\"preview-dot\" [attr.data-status]=\"t.LastStatus.toLowerCase()\"></span>\n <span class=\"preview-test-name\">{{ t.TestName }}</span>\n <span class=\"preview-score\" [class]=\"GetScoreClass(t.LastScore)\">{{ (t.LastScore * 100).toFixed(0) }}%</span>\n <span class=\"preview-bar\">\n <span class=\"preview-bar-fill\" [style.width.%]=\"t.LastScore * 100\" [class]=\"GetScoreClass(t.LastScore) + '-bg'\"></span>\n </span>\n <span class=\"preview-status\" [attr.data-status]=\"t.LastStatus.toLowerCase()\">{{ t.LastStatus }}</span>\n </div>\n }\n }\n @if (suite.TotalTestsInSuite > 4) {\n <div class=\"preview-more\">+{{ suite.TotalTestsInSuite - 4 }} more tests</div>\n }\n </div>\n }\n\n <div class=\"card-actions\">\n <button class=\"btn btn-sm btn-primary\" (click)=\"RunSuite(suite.ID)\">\n <i class=\"fa-solid fa-play\"></i> Run Suite\n </button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"ViewSuiteResults(suite.ID)\">\n <i class=\"fa-solid fa-chart-bar\"></i> Results\n </button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"EditItem('MJ: Test Suites', suite.ID)\">\n <i class=\"fa-solid fa-pen\"></i> Edit\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n }\n }\n\n <!-- Tests Section -->\n @if (DisplayMode === 'all' || DisplayMode === 'tests') {\n @if (FilteredTests.length > 0) {\n <div class=\"content-section\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-vial\"></i>\n Tests\n <span class=\"section-count\">{{ FilteredTests.length }}</span>\n </h3>\n <div class=\"card-grid\">\n @for (test of FilteredTests; track test.ID) {\n <div class=\"test-card\">\n <div class=\"card-header\">\n <div class=\"card-title-row\">\n <i class=\"fa-solid fa-vial card-icon test-icon\"></i>\n <span class=\"card-name\" [innerHTML]=\"test.Name | highlightSearch:SearchTerm\"></span>\n <span class=\"status-badge\" [attr.data-status]=\"test.Status.toLowerCase()\">{{ test.Status }}</span>\n </div>\n <div class=\"card-subtitle\">\n {{ test.TypeName }}\n @if (test.SuiteName) {\n <span class=\"dot-sep\"></span>\n {{ test.SuiteName }}\n }\n </div>\n @if (test.Description) {\n <p class=\"card-description\" [innerHTML]=\"test.Description | highlightSearch:SearchTerm\"></p>\n }\n <div class=\"card-meta-row\">\n @if (test.TypeName) {\n <span class=\"meta-item\"><i class=\"fa-solid fa-robot\"></i> {{ test.TypeName }}</span>\n }\n @if (test.EstDuration > 0) {\n <span class=\"meta-item\"><i class=\"fa-solid fa-clock\"></i> ~{{ FormatDurationSeconds(test.EstDuration) }}</span>\n }\n @if (test.EstCost > 0) {\n <span class=\"meta-item\"><i class=\"fa-solid fa-dollar-sign\"></i> {{ FormatCost(test.EstCost) }}</span>\n }\n <span class=\"meta-item\"><i class=\"fa-solid fa-calendar\"></i> {{ FormatRelativeTime(test.UpdatedAt) }}</span>\n </div>\n @if (test.Tags.length > 0) {\n <div class=\"card-tags\">\n @for (tag of test.Tags; track tag; let i = $index) {\n @if (i < 4) {\n <span class=\"tag\">{{ tag }}</span>\n }\n }\n @if (test.Tags.length > 4) {\n <span class=\"tag tag-more\">+{{ test.Tags.length - 4 }}</span>\n }\n </div>\n }\n </div>\n\n <div class=\"card-stats\">\n <div class=\"stat\">\n <span class=\"stat-label\">Last Status</span>\n <span class=\"stat-value status-text\" [attr.data-status]=\"test.LastRunStatus.toLowerCase()\">{{ test.LastRunStatus || 'N/A' }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Score</span>\n <span class=\"stat-value\" [class]=\"GetScoreClass(test.LastScore)\">{{ test.LastScore > 0 ? (test.LastScore * 100).toFixed(0) + '%' : 'N/A' }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Total Runs</span>\n <span class=\"stat-value\">{{ test.TotalRuns }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Pass Rate</span>\n <span class=\"stat-value\" [class]=\"GetScoreClass(test.PassRate / 100)\">{{ test.TotalRuns > 0 ? FormatPercent(test.PassRate) : 'N/A' }}</span>\n </div>\n </div>\n\n <div class=\"card-actions\">\n <button class=\"btn btn-sm btn-primary\" (click)=\"RunTest(test.ID)\">\n <i class=\"fa-solid fa-play\"></i> Run\n </button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"ViewTestHistory(test.ID)\">\n <i class=\"fa-solid fa-history\"></i> History\n </button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"EditItem('MJ: Tests', test.ID)\">\n <i class=\"fa-solid fa-pen\"></i> Edit\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n }\n }\n\n <!-- Empty State -->\n @if (FilteredSuites.length === 0 && FilteredTests.length === 0) {\n <mj-empty-state Variant=\"no-results\" Icon=\"fa-solid fa-inbox\"\n Title=\"No tests or suites found\"\n Message=\"Try adjusting your search or filters.\" />\n }\n </mj-page-body-interior>\n </mj-left-nav-content>\n }\n\n <!-- Slideout Backdrop -->\n @if (SlideoutOpen) {\n <div class=\"slideout-backdrop\" (click)=\"CloseSlideout()\"></div>\n }\n\n <!-- Slideout Panel -->\n <div class=\"slideout-panel\" [class.open]=\"SlideoutOpen\" [style.width.px]=\"SlideoutWidth\">\n <div class=\"slideout-resize-handle\" (mousedown)=\"OnResizeStart($event)\"></div>\n\n @if (SlideoutOpen) {\n <div class=\"slideout-container\">\n <!-- Slideout Header -->\n <div class=\"slideout-header\">\n <div class=\"slideout-title-row\">\n <i class=\"fa-solid fa-plus-circle slideout-title-icon\"></i>\n <span class=\"slideout-title-text\">\n Create {{ SlideoutCreateType === 'test' ? 'Test' : 'Test Suite' }}\n </span>\n </div>\n <button class=\"slideout-close-btn\" (click)=\"CloseSlideout()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <!-- Type Toggle -->\n <div class=\"slideout-type-toggle\">\n <button\n class=\"type-toggle-btn\"\n [class.active]=\"SlideoutCreateType === 'test'\"\n (click)=\"SetSlideoutCreateType('test')\"\n >\n <i class=\"fa-solid fa-vial\"></i> Test\n </button>\n <button\n class=\"type-toggle-btn\"\n [class.active]=\"SlideoutCreateType === 'suite'\"\n (click)=\"SetSlideoutCreateType('suite')\"\n >\n <i class=\"fa-solid fa-folder\"></i> Suite\n </button>\n </div>\n\n <!-- Error Banner -->\n @if (FormErrorMessage) {\n <div class=\"slideout-error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n <span>{{ FormErrorMessage }}</span>\n </div>\n }\n\n <!-- Slideout Body -->\n <div class=\"slideout-body\">\n <div class=\"form-section\">\n <div class=\"form-section-title\">General</div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Name <span class=\"form-required\">*</span></label>\n <input\n class=\"form-input\"\n type=\"text\"\n [(ngModel)]=\"FormName\"\n [placeholder]=\"SlideoutCreateType === 'test' ? 'e.g., Agent Response Quality Test' : 'e.g., Core Agent Test Suite'\"\n />\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Description</label>\n <textarea\n class=\"form-textarea\"\n [(ngModel)]=\"FormDescription\"\n rows=\"3\"\n [placeholder]=\"SlideoutCreateType === 'test' ? 'What does this test evaluate?' : 'What does this suite contain?'\"\n ></textarea>\n </div>\n\n <div class=\"form-row\">\n @if (SlideoutCreateType === 'test') {\n <div class=\"form-group\">\n <label class=\"form-label\">Test Type <span class=\"form-required\">*</span></label>\n <select class=\"form-input\" [(ngModel)]=\"FormTypeID\">\n <option value=\"\" disabled>Select type...</option>\n @for (tt of AllTestTypes; track tt.ID) {\n <option [value]=\"tt.ID\">{{ tt.Name }}</option>\n }\n </select>\n </div>\n }\n @if (SlideoutCreateType === 'suite') {\n <div class=\"form-group\">\n <label class=\"form-label\">Parent Suite</label>\n <select class=\"form-input\" [(ngModel)]=\"FormParentSuiteID\">\n <option value=\"\">None (top-level)</option>\n @for (s of AllSuites; track s.ID) {\n <option [value]=\"s.ID\">{{ s.Name }}</option>\n }\n </select>\n </div>\n }\n <div class=\"form-group\">\n <label class=\"form-label\">Status</label>\n <select class=\"form-input\" [(ngModel)]=\"FormStatus\">\n @for (status of FormStatusOptions; track status) {\n <option [value]=\"status\">{{ status }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n\n @if (SlideoutCreateType === 'test') {\n <div class=\"form-section\">\n <div class=\"form-section-title\">Estimates</div>\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label class=\"form-label\">Duration (seconds)</label>\n <input\n class=\"form-input\"\n type=\"number\"\n [(ngModel)]=\"FormEstDuration\"\n min=\"0\"\n placeholder=\"0\"\n />\n </div>\n <div class=\"form-group\">\n <label class=\"form-label\">Cost (USD)</label>\n <input\n class=\"form-input\"\n type=\"number\"\n [(ngModel)]=\"FormEstCost\"\n min=\"0\"\n step=\"0.01\"\n placeholder=\"0.00\"\n />\n </div>\n </div>\n </div>\n }\n\n <div class=\"form-section\">\n <div class=\"form-section-title\">Tags</div>\n <div class=\"form-group\">\n <input\n class=\"form-input\"\n type=\"text\"\n [(ngModel)]=\"FormTags\"\n placeholder=\"Comma-separated tags, e.g., agent, quality, v2\"\n />\n <span class=\"form-hint\">Separate multiple tags with commas</span>\n </div>\n </div>\n </div>\n\n <!-- Slideout Footer -->\n <div class=\"slideout-footer\">\n <button class=\"btn btn-secondary\" (click)=\"CloseSlideout()\">Cancel</button>\n <button class=\"btn btn-primary\" (click)=\"SaveForm()\" [disabled]=\"!IsFormValid || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-check\"></i>\n }\n Create {{ SlideoutCreateType === 'test' ? 'Test' : 'Suite' }}\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Slide Panel for Test Execution -->\n @if (testingDialogService.IsPanelOpen) {\n <mj-slide-panel\n Mode=\"slide\"\n Title=\"Run Test\"\n [Resizable]=\"true\"\n (Closed)=\"OnPanelClosed()\">\n <app-test-run-dialog\n [PanelMode]=\"true\"\n [selectedTestId]=\"testingDialogService.PanelOptions?.testId ?? null\"\n [selectedSuiteId]=\"testingDialogService.PanelOptions?.suiteId ?? null\"\n [runMode]=\"testingDialogService.PanelOptions?.mode ?? 'test'\"\n (PanelClose)=\"OnPanelClosed()\">\n </app-test-run-dialog>\n </mj-slide-panel>\n }\n </mj-page-body>\n </ng-template>\n `,\n styles: [`\n /* ==========================================\n Testing Explorer Component\n ========================================== */\n\n :host {\n display: block;\n height: 100%;\n width: 100%;\n }\n\n /* Loading */\n .explorer-loading {\n flex: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface-sunken);\n }\n\n /* The rail + content layout is the shared <mj-page-body Direction=\"row\">\n (it reflows to a column on mobile) and the scroller is the shared\n <mj-page-body-interior> — no bespoke .explorer-layout / .content-area. */\n\n /* Mobile search-grow + icon-only action buttons are handled by the shared\n <mj-page-header> rules (action-btn-label + toolbar search-grow). */\n\n /* ==========================================\n Main Content\n — left rail + content pane handled by <mj-left-nav> + <mj-left-nav-content>\n ========================================== */\n\n /* Buttons */\n .btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 9px 16px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n }\n\n .btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n }\n\n .btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n }\n\n .btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n border: 1px solid var(--mj-border-default);\n }\n\n .btn-secondary:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .btn-sm {\n padding: 6px 12px;\n font-size: 12px;\n }\n\n .content-section {\n margin-bottom: 32px;\n }\n\n .section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .section-title i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n }\n\n .section-count {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 10px;\n }\n\n /* Card Grid */\n .card-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));\n gap: 16px;\n }\n\n /* Suite Card */\n .suite-card,\n .test-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n transition: all 0.2s ease;\n }\n\n .suite-card:hover,\n .test-card:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-md);\n }\n\n .card-header {\n padding: 16px 16px 12px;\n }\n\n .card-title-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n }\n\n .card-icon {\n font-size: 14px;\n flex-shrink: 0;\n }\n\n .suite-icon {\n color: var(--mj-brand-primary);\n }\n\n .test-icon {\n color: var(--mj-brand-primary);\n }\n\n .card-name {\n flex: 1;\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .status-badge {\n font-size: 10px;\n font-weight: 700;\n padding: 3px 8px;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n flex-shrink: 0;\n }\n\n .status-badge[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n\n .status-badge[data-status=\"pending\"] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n\n .status-badge[data-status=\"disabled\"] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n .card-subtitle {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n }\n\n .dot-sep {\n display: inline-block;\n width: 3px;\n height: 3px;\n background: var(--mj-text-disabled);\n border-radius: 50%;\n vertical-align: middle;\n margin: 0 6px;\n }\n\n .card-description {\n margin: 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .card-meta-row {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n margin-top: 8px;\n }\n\n .meta-item {\n font-size: 11px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .meta-item i {\n font-size: 10px;\n color: var(--mj-text-disabled);\n }\n\n .card-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-top: 8px;\n }\n\n .tag {\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n border-radius: 4px;\n }\n\n .tag-more {\n background: var(--mj-border-default);\n color: var(--mj-text-disabled);\n }\n\n /* Card Stats */\n .card-stats {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 1px;\n background: var(--mj-border-default);\n border-top: 1px solid var(--mj-border-default);\n }\n\n .stat {\n background: var(--mj-bg-surface-card);\n padding: 10px 12px;\n text-align: center;\n }\n\n .stat-label {\n display: block;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 2px;\n }\n\n .stat-value {\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .stat-value.good { color: var(--mj-status-success); }\n .stat-value.warn { color: var(--mj-status-warning); }\n .stat-value.bad { color: var(--mj-status-error); }\n\n .status-text[data-status=\"passed\"] { color: var(--mj-status-success); }\n .status-text[data-status=\"failed\"] { color: var(--mj-status-error); }\n .status-text[data-status=\"error\"] { color: var(--mj-status-warning); }\n .status-text[data-status=\"running\"] { color: var(--mj-brand-primary); }\n .status-text[data-status=\"pending\"] { color: var(--mj-status-warning); }\n .status-text[data-status=\"skipped\"] { color: var(--mj-text-muted); }\n\n /* Suite Tests Preview */\n .card-tests-preview {\n padding: 10px 16px;\n border-top: 1px solid var(--mj-border-default);\n }\n\n .preview-test-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n font-size: 12px;\n }\n\n .preview-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .preview-dot[data-status=\"passed\"] { background: var(--mj-status-success); }\n .preview-dot[data-status=\"failed\"] { background: var(--mj-status-error); }\n .preview-dot[data-status=\"error\"] { background: var(--mj-status-warning); }\n .preview-dot[data-status=\"running\"] { background: var(--mj-brand-primary); }\n .preview-dot[data-status=\"\"] { background: var(--mj-text-disabled); }\n\n .preview-test-name {\n flex: 1;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .preview-score {\n font-weight: 600;\n font-size: 11px;\n min-width: 32px;\n text-align: right;\n }\n\n .preview-score.good { color: var(--mj-status-success); }\n .preview-score.warn { color: var(--mj-status-warning); }\n .preview-score.bad { color: var(--mj-status-error); }\n\n .preview-bar {\n width: 48px;\n height: 4px;\n background: var(--mj-border-default);\n border-radius: 2px;\n overflow: hidden;\n flex-shrink: 0;\n }\n\n .preview-bar-fill {\n height: 100%;\n border-radius: 2px;\n transition: width 0.3s ease;\n }\n\n .good-bg { background: var(--mj-status-success); }\n .warn-bg { background: var(--mj-status-warning); }\n .bad-bg { background: var(--mj-status-error); }\n\n .preview-status {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n min-width: 44px;\n text-align: right;\n }\n\n .preview-status[data-status=\"passed\"] { color: var(--mj-status-success); }\n .preview-status[data-status=\"failed\"] { color: var(--mj-status-error); }\n .preview-status[data-status=\"error\"] { color: var(--mj-status-warning); }\n .preview-status[data-status=\"\"] { color: var(--mj-text-disabled); }\n\n .preview-more {\n padding: 4px 0 0;\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-style: italic;\n }\n\n /* Card Actions */\n .card-actions {\n display: flex;\n gap: 8px;\n padding: 12px 16px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n }\n\n /* ==========================================\n Slideout Panel\n ========================================== */\n .slideout-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n animation: fadeInBackdrop 0.2s ease;\n }\n\n @keyframes fadeInBackdrop {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n .slideout-panel {\n position: fixed;\n top: 0;\n right: -100%;\n height: 100vh;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .slideout-panel.open {\n right: 0;\n }\n\n .slideout-resize-handle {\n position: absolute;\n top: 0;\n left: 0;\n width: 5px;\n height: 100%;\n cursor: col-resize;\n background: transparent;\n z-index: 10;\n transition: background 0.2s;\n }\n\n .slideout-resize-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n\n .slideout-resize-handle:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n }\n\n .slideout-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n }\n\n .slideout-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n .slideout-title-row {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .slideout-title-icon {\n font-size: 18px;\n color: var(--mj-brand-primary);\n }\n\n .slideout-title-text {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .slideout-close-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 14px;\n transition: all 0.15s ease;\n }\n\n .slideout-close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n }\n\n /* Type Toggle */\n .slideout-type-toggle {\n display: flex;\n gap: 0;\n padding: 16px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n .type-toggle-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .type-toggle-btn:first-child {\n border-radius: 8px 0 0 8px;\n border-right: none;\n }\n\n .type-toggle-btn:last-child {\n border-radius: 0 8px 8px 0;\n }\n\n .type-toggle-btn.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n }\n\n .type-toggle-btn:hover:not(.active) {\n background: var(--mj-border-default);\n }\n\n /* Error Banner */\n .slideout-error {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 16px 24px 0;\n padding: 12px 16px;\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface));\n border-radius: 8px;\n color: var(--mj-status-error);\n font-size: 13px;\n flex-shrink: 0;\n }\n\n .slideout-error i {\n font-size: 14px;\n flex-shrink: 0;\n }\n\n /* Slideout Body */\n .slideout-body {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n }\n\n .form-section {\n margin-bottom: 24px;\n }\n\n .form-section-title {\n font-size: 12px;\n font-weight: 700;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.8px;\n margin-bottom: 14px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .form-group {\n margin-bottom: 16px;\n }\n\n .form-label {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 6px;\n }\n\n .form-required {\n color: var(--mj-status-error);\n }\n\n .form-input,\n .form-textarea {\n width: 100%;\n padding: 10px 14px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-text-primary);\n transition: border-color 0.2s ease;\n outline: none;\n box-sizing: border-box;\n font-family: inherit;\n }\n\n .form-input:focus,\n .form-textarea:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n .form-input::placeholder,\n .form-textarea::placeholder {\n color: var(--mj-text-disabled);\n }\n\n .form-textarea {\n resize: vertical;\n min-height: 80px;\n }\n\n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n }\n\n .form-hint {\n display: block;\n font-size: 11px;\n color: var(--mj-text-disabled);\n margin-top: 4px;\n }\n\n /* Slideout Footer */\n .slideout-footer {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding: 16px 24px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n }\n\n .slideout-footer .btn {\n min-width: 100px;\n justify-content: center;\n }\n\n .slideout-footer .btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n box-shadow: none;\n }\n\n /* Search Highlight */\n ::ng-deep mark.search-highlight {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n color: inherit;\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: 700;\n }\n\n /* ==========================================\n Responsive\n ========================================== */\n @media (max-width: 1200px) {\n .card-grid {\n grid-template-columns: 1fr;\n }\n }\n\n @media (max-width: 600px) {\n .card-stats {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .slideout-panel {\n width: 100% !important;\n }\n\n .slideout-resize-handle {\n display: none;\n }\n\n .form-row {\n grid-template-columns: 1fr;\n }\n }\n `]\n})\nexport class TestingExplorerComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n\n public readonly HeaderViewOptions: ViewToggleOption[] = [\n { key: 'card', icon: 'fa-solid fa-grip', title: 'Card view' },\n { key: 'list', icon: 'fa-solid fa-list', title: 'List view' }\n ];\n\n public readonly DisplayModeOptions: ViewToggleOption[] = [\n { key: 'all', label: 'All' },\n { key: 'suites', label: 'Suites' },\n { key: 'tests', label: 'Tests' }\n ];\n\n /** mj-page-search emits a string; bridge it to the inner's Event-based OnSearchInput. */\n public OnSearchInputValue(value: string): void {\n const fakeEvent = { target: { value } } as unknown as Event;\n this.OnSearchInput(fakeEvent);\n }\n\n /** When true, the inner bespoke .toolbar is hidden — the parent shell owns the chrome. */\n @Input() HideToolbar = false;\n\n private destroy$ = new Subject<void>();\n\n // Raw cached data\n private allTests: MJTestEntity[] = [];\n AllSuites: MJTestSuiteEntity[] = [];\n private allSuiteTests: MJTestSuiteTestEntity[] = [];\n AllTestTypes: MJTestTypeEntity[] = [];\n private testRunStats: TestRunStatRow[] = [];\n\n // Computed card data\n private suiteCards: SuiteCardData[] = [];\n private testCards: TestCardData[] = [];\n\n // State subjects\n private _searchTerm$ = new BehaviorSubject<string>('');\n private _statusFilters$ = new BehaviorSubject<Set<string>>(new Set());\n private _viewMode$ = new BehaviorSubject<ViewMode>('card');\n private _displayMode$ = new BehaviorSubject<DisplayMode>('all');\n private _selectedSidebar$ = new BehaviorSubject<SidebarSelection>({ Type: 'all', ID: null });\n private _sortField$ = new BehaviorSubject<SortField>('name');\n private _sortDirection$ = new BehaviorSubject<SortDirection>('asc');\n\n // Template-bound state\n IsLoading = true;\n SearchTerm = '';\n StatusFilters = new Set<string>();\n ViewMode: ViewMode = 'card';\n DisplayMode: DisplayMode = 'all';\n SelectedSidebar: SidebarSelection = { Type: 'all', ID: null };\n SortField: SortField = 'name';\n SortDirection: SortDirection = 'asc';\n\n // Filtered results\n FilteredSuites: SuiteCardData[] = [];\n FilteredTests: TestCardData[] = [];\n FilteredSuiteTree: SuiteTreeNode[] = [];\n FilteredTestTypes: MJTestTypeEntity[] = [];\n\n // Counts\n TotalItemCount = 0;\n StandaloneTestCount = 0;\n FilteredResultCount = 0;\n\n readonly StatusOptions: string[] = ['Active', 'Pending', 'Disabled'];\n readonly FormStatusOptions: string[] = ['Active', 'Pending', 'Disabled'];\n\n // Settings keys\n private static readonly PANEL_WIDTH_KEY = 'Testing.ExplorerPanelWidth';\n private static readonly SEARCH_STATE_KEY = 'Testing.ExplorerSearchState';\n private static readonly RAIL_COLLAPSED_KEY = 'Testing.ExplorerRailCollapsed';\n\n /**\n * Whether the browse rail is collapsed to icons. `<mj-left-nav>` owns the presentation; we own\n * the state, same split as `ExpandedIds` — so it survives a reload and follows the user across\n * devices via `UserInfoEngine` rather than dying in one browser's localStorage.\n */\n RailCollapsed = false;\n private settingsPersistSubject = new Subject<void>();\n private settingsLoaded = false;\n\n // Slideout state\n SlideoutOpen = false;\n SlideoutCreateType: 'test' | 'suite' = 'test';\n SlideoutWidth = 560;\n IsSaving = false;\n FormErrorMessage = '';\n\n // Resize state\n private resizeStartX = 0;\n private resizeStartWidth = 0;\n\n // Form fields\n FormName = '';\n FormDescription = '';\n FormTypeID = '';\n FormStatus: 'Active' | 'Pending' | 'Disabled' = 'Active';\n FormParentSuiteID = '';\n FormEstDuration = 0;\n FormEstCost = 0;\n FormTags = '';\n\n get IsFormValid(): boolean {\n if (!this.FormName.trim()) return false;\n if (this.SlideoutCreateType === 'test' && !this.FormTypeID) return false;\n return true;\n }\n\n constructor(\n private cdr: ChangeDetectorRef,\n private viewContainerRef: ViewContainerRef,\n public TestingDialogService: TestingDialogService,\n public InstrumentationService: TestingInstrumentationService\n ) { super(); }\n\n /** @deprecated Use {@link TestingDialogService}. */\n public get testingDialogService(): TestingDialogService {\n return this.TestingDialogService;\n }\n /** @deprecated Use {@link TestingDialogService}. */\n public set testingDialogService(value: TestingDialogService) {\n this.TestingDialogService = value;\n }\n\n /** @deprecated Use {@link InstrumentationService}. */\n public get instrumentationService(): TestingInstrumentationService {\n return this.InstrumentationService;\n }\n /** @deprecated Use {@link InstrumentationService}. */\n public set instrumentationService(value: TestingInstrumentationService) {\n this.InstrumentationService = value;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n async ngOnInit(): Promise<void> {\n this.loadUserSettings();\n this.setupSettingsPersistence();\n this.IsLoading = true;\n this.cdr.markForCheck();\n\n try {\n await TestEngineBase.Instance.Config(false);\n await this.LoadData();\n } catch (err) {\n console.error('TestingExplorerComponent: Failed to load data', err);\n } finally {\n this.IsLoading = false;\n this.cdr.markForCheck();\n }\n\n this.subscribeToStateChanges();\n\n this.TestingDialogService.PanelStateChanged$.pipe(\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.cdr.detectChanges();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n document.removeEventListener('mousemove', this.onResizeMove);\n document.removeEventListener('mouseup', this.onResizeEnd);\n UserInfoEngine.Instance.FlushPendingSettings();\n }\n\n // ---------------------------------------------------------------------------\n // Public Methods\n // ---------------------------------------------------------------------------\n\n async LoadData(): Promise<void> {\n this.loadCachedMetadata();\n await this.loadTestRunStats();\n this.buildSuiteCards();\n this.buildTestCards();\n this.buildSuiteTree();\n this.computeCounts();\n this.applyFilters();\n }\n\n IsSidebarSelected(id: string): boolean {\n return UUIDsEqual(this.SelectedSidebar.ID, id);\n }\n\n SelectSidebarItem(selection: SidebarSelection): void {\n this._selectedSidebar$.next(selection);\n }\n\n ToggleStatus(status: string): void {\n const current = new Set(this._statusFilters$.value);\n if (current.has(status)) {\n current.delete(status);\n } else {\n current.add(status);\n }\n this._statusFilters$.next(current);\n }\n\n IsStatusActive(status: string): boolean {\n return this.StatusFilters.has(status);\n }\n\n SetDisplayMode(mode: DisplayMode): void {\n this._displayMode$.next(mode);\n }\n\n SetViewMode(mode: ViewMode): void {\n this._viewMode$.next(mode);\n }\n\n OnSearchInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n this._searchTerm$.next(input.value);\n }\n\n ClearSearch(): void {\n this._searchTerm$.next('');\n }\n\n ToggleSuiteExpand(node: SuiteTreeNode): void {\n node.Expanded = !node.Expanded;\n this.cdr.markForCheck();\n }\n\n // ---------------------------------------------------------------------------\n // <mj-left-nav> adapters\n //\n // The rail is one <mj-left-nav> with three logical sections. Internal state\n // still lives on SelectedSidebar (typed Type+ID) and on SuiteTreeNode.Expanded\n // booleans — these getters translate to/from the primitive's flat\n // string-id interface.\n // ---------------------------------------------------------------------------\n\n /** Composite-key sections fed to <mj-left-nav>. */\n get NavSections(): MJLeftNavSection[] {\n const suiteItems = this.FilteredSuiteTree.length === 0\n ? [{ id: '__suites-empty', label: 'No suites found', disabled: true } as MJLeftNavItem]\n : this.FilteredSuiteTree.map(node => this.suiteNodeToNavItem(node));\n\n return [\n {\n label: 'Browse',\n items: [\n { id: 'all', label: 'All Items', icon: 'fa-solid fa-layer-group', badge: this.TotalItemCount },\n { id: 'standalone', label: 'Standalone Tests', icon: 'fa-solid fa-vial', badge: this.StandaloneTestCount },\n ]\n },\n { label: 'Test Suites', items: suiteItems },\n {\n label: 'Test Types',\n items: this.FilteredTestTypes.map(tt => ({\n id: `testType:${tt.ID}`,\n label: tt.Name,\n icon: 'fa-solid fa-tag',\n badge: this.GetTestCountForType(tt.ID)\n }))\n }\n ];\n }\n\n /** Recursive map SuiteTreeNode -> MJLeftNavItem. Leaves keep `children: []`\n * so the primitive renders a placeholder where the chevron would be —\n * this keeps siblings vertically aligned. */\n private suiteNodeToNavItem(node: SuiteTreeNode): MJLeftNavItem {\n return {\n id: `suite:${node.ID}`,\n label: node.Name,\n icon: 'fa-solid fa-folder',\n badge: node.TestCount,\n children: node.Children.map(child => this.suiteNodeToNavItem(child))\n };\n }\n\n /** Translate SelectedSidebar (typed Type+ID) to the rail's composite key. */\n get ActiveNavId(): string {\n const sel = this.SelectedSidebar;\n if (sel.Type === 'suite' || sel.Type === 'testType') {\n return `${sel.Type}:${sel.ID ?? ''}`;\n }\n return sel.Type;\n }\n\n /** Suite-node IDs that are currently expanded, walked from FilteredSuiteTree. */\n get ExpandedNavIds(): string[] {\n const out: string[] = [];\n const walk = (nodes: SuiteTreeNode[]): void => {\n for (const n of nodes) {\n if (n.Expanded) out.push(`suite:${n.ID}`);\n walk(n.Children);\n }\n };\n walk(this.FilteredSuiteTree);\n return out;\n }\n\n /** Parse composite id and delegate to the existing SelectSidebarItem path. */\n OnNavItemClicked(item: MJLeftNavItem): void {\n const id = item.id;\n if (id === 'all') {\n this.SelectSidebarItem({ Type: 'all', ID: null });\n } else if (id === 'standalone') {\n this.SelectSidebarItem({ Type: 'standalone', ID: null });\n } else if (id.startsWith('suite:')) {\n this.SelectSidebarItem({ Type: 'suite', ID: id.substring('suite:'.length) });\n } else if (id.startsWith('testType:')) {\n this.SelectSidebarItem({ Type: 'testType', ID: id.substring('testType:'.length) });\n }\n }\n\n /** Chevron click on a suite item — toggle that node's Expanded flag. */\n OnNavItemToggled(item: MJLeftNavItem): void {\n if (!item.id.startsWith('suite:')) return;\n const suiteId = item.id.substring('suite:'.length);\n const node = this.findSuiteNode(this.FilteredSuiteTree, suiteId);\n if (node) this.ToggleSuiteExpand(node);\n }\n\n private findSuiteNode(tree: SuiteTreeNode[], id: string): SuiteTreeNode | null {\n for (const node of tree) {\n if (UUIDsEqual(node.ID, id)) return node;\n const found = this.findSuiteNode(node.Children, id);\n if (found) return found;\n }\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // Sort filter-popover wiring\n //\n // The chrome surfaces SortField + SortDirection through a <mj-filter-popover>\n // — same pattern AI Analytics → Model Performance uses for its SortBy\n // selection. Was previously a single direction-toggle button in chrome\n // [actions] with no way to change the field from the UI.\n // ---------------------------------------------------------------------------\n\n public readonly SortFieldOptions = [\n { text: 'Name', value: 'name' },\n { text: 'Updated', value: 'updated' },\n { text: 'Status', value: 'status' },\n ];\n\n /** @deprecated Use {@link SortFieldOptions}. */\n public get sortFieldOptions() {\n return this.SortFieldOptions;\n }\n\n public readonly SortDirectionOptions = [\n { text: 'Ascending', value: 'asc' },\n { text: 'Descending', value: 'desc' },\n ];\n\n /** @deprecated Use {@link SortDirectionOptions}. */\n public get sortDirectionOptions() {\n return this.SortDirectionOptions;\n }\n\n /**\n * Concise-chrome model: every filter (View · Status · Sort) lives behind a\n * single \"Filter\" button via this one mj-filter-panel field set. The applied\n * state is surfaced separately as removable chips (see AppliedFilters), so\n * input (the button) and state (the chips) are cleanly separated.\n */\n public get FilterFields(): FilterFieldConfig[] {\n return [\n { key: 'displayMode', type: 'chips', label: 'View', chipOptions: [\n { text: 'All', value: 'all' },\n { text: 'Suites', value: 'suites' },\n { text: 'Tests', value: 'tests' },\n ] },\n { key: 'status', type: 'chips', label: 'Status', multi: true, chipOptions: [\n { text: 'Active', value: 'Active' },\n { text: 'Pending', value: 'Pending' },\n { text: 'Disabled', value: 'Disabled' },\n ] },\n { key: 'SortField', type: 'dropdown', label: 'Sort by',\n icon: 'fa-solid fa-arrow-down-wide-short', options: this.SortFieldOptions },\n { key: 'SortDirection', type: 'dropdown', label: 'Direction',\n icon: 'fa-solid fa-arrow-up-arrow-down', options: this.SortDirectionOptions },\n ];\n }\n\n /** @deprecated Use {@link FilterFields}. */\n public get filterFields(): FilterFieldConfig[] {\n return this.FilterFields;\n }\n\n public get FilterValues(): Record<string, unknown> {\n return {\n displayMode: this.DisplayMode,\n status: Array.from(this.StatusFilters),\n SortField: this.SortField,\n SortDirection: this.SortDirection,\n };\n }\n\n /** @deprecated Use {@link FilterValues}. */\n public get filterValues(): Record<string, unknown> {\n return this.FilterValues;\n }\n\n public OnFilterValuesChange(values: Record<string, unknown>): void {\n if ('displayMode' in values) {\n this._displayMode$.next(values['displayMode'] as DisplayMode);\n }\n if ('status' in values) {\n const arr = Array.isArray(values['status']) ? (values['status'] as string[]) : [];\n this._statusFilters$.next(new Set(arr));\n }\n if ('SortField' in values) {\n this._sortField$.next(values['SortField'] as SortField);\n }\n if ('SortDirection' in values) {\n this._sortDirection$.next(values['SortDirection'] as SortDirection);\n }\n }\n\n /** @deprecated Use {@link OnFilterValuesChange}. */\n public onFilterValuesChange(values: Record<string, unknown>): void {\n return this.OnFilterValuesChange(values);\n }\n\n public ResetSortFilters(): void {\n this._sortField$.next('name');\n this._sortDirection$.next('asc');\n }\n\n /** @deprecated Use {@link ResetSortFilters}. */\n public resetSortFilters(): void {\n return this.ResetSortFilters();\n }\n\n /** Clears every filter (View · Status · Sort) back to defaults. */\n public ResetAllFilters(): void {\n this._displayMode$.next('all');\n this._statusFilters$.next(new Set<string>());\n this.ResetSortFilters();\n }\n\n /** @deprecated Use {@link ResetAllFilters}. */\n public resetAllFilters(): void {\n return this.ResetAllFilters();\n }\n\n /** Active sort changes from defaults — contributes to the filter badge + chips. */\n public get ActiveSortFilterCount(): number {\n let count = 0;\n if (this.SortField !== 'name') count++;\n if (this.SortDirection !== 'asc') count++;\n return count;\n }\n\n /** Total active filters (View + Status + Sort) — drives the Filter button badge. */\n public get TotalActiveFilterCount(): number {\n const displayModeActive = this.DisplayMode !== 'all' ? 1 : 0;\n return this.ActiveSortFilterCount + this.StatusFilters.size + displayModeActive;\n }\n\n\n RunTest(testId: string): void {\n this.TestingDialogService.OpenTestPanel(testId);\n }\n\n RunSuite(suiteId: string): void {\n this.TestingDialogService.OpenSuitePanel(suiteId);\n }\n\n OnPanelClosed(): void {\n this.TestingDialogService.ClosePanel();\n this.cdr.detectChanges();\n }\n\n EditItem(entityName: string, id: string): void {\n SharedService.Instance.OpenEntityRecord(entityName, CompositeKey.FromURLSegment(this.ProviderToUse.EntityByName(entityName), id));\n }\n\n ViewTestHistory(testId: string): void {\n SharedService.Instance.OpenEntityRecord('MJ: Tests', CompositeKey.FromID(testId));\n }\n\n ViewSuiteResults(suiteId: string): void {\n SharedService.Instance.OpenEntityRecord('MJ: Test Suites', CompositeKey.FromID(suiteId));\n }\n\n OnNewTest(): void {\n this.OpenSlideout('test');\n }\n\n OnNewSuite(): void {\n this.OpenSlideout('suite');\n }\n\n OpenSlideout(type: 'test' | 'suite'): void {\n this.SlideoutCreateType = type;\n this.resetForm();\n this.SlideoutOpen = true;\n this.cdr.markForCheck();\n }\n\n CloseSlideout(): void {\n this.SlideoutOpen = false;\n this.FormErrorMessage = '';\n this.cdr.markForCheck();\n }\n\n SetSlideoutCreateType(type: 'test' | 'suite'): void {\n this.SlideoutCreateType = type;\n this.resetForm();\n this.cdr.markForCheck();\n }\n\n async SaveForm(): Promise<void> {\n if (!this.IsFormValid || this.IsSaving) return;\n\n this.IsSaving = true;\n this.FormErrorMessage = '';\n this.cdr.markForCheck();\n\n try {\n if (this.SlideoutCreateType === 'test') {\n await this.saveNewTest();\n } else {\n await this.saveNewSuite();\n }\n this.CloseSlideout();\n await TestEngineBase.Instance.Config(true);\n await this.LoadData();\n this.cdr.markForCheck();\n } catch (err) {\n const message = err instanceof Error ? err.message : 'An error occurred while saving.';\n this.FormErrorMessage = message;\n console.error('TestingExplorerComponent: Save failed', err);\n } finally {\n this.IsSaving = false;\n this.cdr.markForCheck();\n }\n }\n\n // ── Resize ──────────────────────────────────────────\n OnResizeStart(event: MouseEvent): void {\n event.preventDefault();\n this.resizeStartX = event.clientX;\n this.resizeStartWidth = this.SlideoutWidth;\n document.addEventListener('mousemove', this.onResizeMove);\n document.addEventListener('mouseup', this.onResizeEnd);\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n }\n\n private onResizeMove = (event: MouseEvent): void => {\n const delta = this.resizeStartX - event.clientX;\n this.SlideoutWidth = Math.max(400, Math.min(900, this.resizeStartWidth + delta));\n this.cdr.detectChanges();\n };\n\n private onResizeEnd = (): void => {\n document.removeEventListener('mousemove', this.onResizeMove);\n document.removeEventListener('mouseup', this.onResizeEnd);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n UserInfoEngine.Instance.SetSettingDebounced(\n TestingExplorerComponent.PANEL_WIDTH_KEY,\n String(this.SlideoutWidth)\n );\n };\n\n GetTestCountForType(typeId: string): number {\n return this.allTests.filter(t => UUIDsEqual(t.TypeID, typeId)).length\n }\n\n // ---------------------------------------------------------------------------\n // Formatting Helpers\n // ---------------------------------------------------------------------------\n\n FormatDuration(ms: number): string {\n if (ms <= 0) return '0s';\n if (ms < 1000) return `${Math.round(ms)}ms`;\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes > 0) return `${minutes}m ${seconds}s`;\n return `${seconds}s`;\n }\n\n FormatDurationSeconds(seconds: number): string {\n if (seconds <= 0) return '0s';\n const minutes = Math.floor(seconds / 60);\n const secs = seconds % 60;\n if (minutes > 0) return `${minutes}m ${secs}s`;\n return `${secs}s`;\n }\n\n FormatRelativeTime(date: Date | null): string {\n if (!date) return 'Never';\n const d = date instanceof Date ? date : new Date(date);\n const now = Date.now();\n const diffMs = now - d.getTime();\n const diffMinutes = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMinutes < 1) return 'Just now';\n if (diffMinutes < 60) return `${diffMinutes}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 30) return `${diffDays}d ago`;\n return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n }\n\n FormatPercent(value: number): string {\n return `${Math.round(value)}%`;\n }\n\n FormatCost(cost: number): string {\n if (cost < 0.01) return '$0.00';\n return `$${cost.toFixed(2)}`;\n }\n\n GetScoreClass(score: number): string {\n if (score >= 0.7) return 'good';\n if (score >= 0.4) return 'warn';\n return 'bad';\n }\n\n GetStatusClass(status: string): string {\n switch (status.toLowerCase()) {\n case 'passed': return 'status-passed';\n case 'failed': return 'status-failed';\n case 'error': return 'status-error';\n case 'running': return 'status-running';\n default: return 'status-default';\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private: Data Loading\n // ---------------------------------------------------------------------------\n\n private loadCachedMetadata(): void {\n const engine = TestEngineBase.Instance;\n this.allTests = engine.Tests;\n this.AllSuites = engine.TestSuites;\n this.allSuiteTests = engine.TestSuiteTests;\n this.AllTestTypes = engine.TestTypes;\n }\n\n private async loadTestRunStats(): Promise<void> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<TestRunStatRow>({\n EntityName: 'MJ: Test Runs',\n Fields: ['ID', 'TestID', 'Status', 'Score', 'CostUSD', 'StartedAt', 'CompletedAt'],\n OrderBy: 'StartedAt DESC',\n MaxRows: 5000,\n ResultType: 'simple'\n });\n\n this.testRunStats = result.Success ? (result.Results || []) : [];\n }\n\n // ---------------------------------------------------------------------------\n // Private: Build Card Data\n // ---------------------------------------------------------------------------\n\n private buildSuiteCards(): void {\n this.suiteCards = this.AllSuites.map(suite => this.buildSingleSuiteCard(suite));\n }\n\n private buildSingleSuiteCard(suite: MJTestSuiteEntity): SuiteCardData {\n const suiteTestLinks = this.allSuiteTests.filter(st => UUIDsEqual(st.SuiteID, suite.ID));\n const testIds = new Set(suiteTestLinks.map(st => st.TestID));\n const runsForSuite = this.testRunStats.filter(r => testIds.has(r.TestID));\n\n const passedRuns = runsForSuite.filter(r => r.Status === 'Passed');\n const passRate = runsForSuite.length > 0 ? (passedRuns.length / runsForSuite.length) * 100 : 0;\n const avgScore = runsForSuite.length > 0\n ? runsForSuite.reduce((s, r) => s + (r.Score || 0), 0) / runsForSuite.length\n : 0;\n const avgDuration = this.computeAvgDuration(runsForSuite);\n const lastRunDate = this.findLastRunDate(runsForSuite);\n const previewTests = this.buildSuiteTestPreviews(suiteTestLinks);\n\n return {\n ID: suite.ID,\n Name: suite.Name,\n Description: suite.Description || '',\n Status: suite.Status,\n TestCount: testIds.size,\n PassRate: passRate,\n AvgScore: avgScore,\n AvgDuration: avgDuration,\n LastRunDate: lastRunDate,\n Tags: this.parseTags(suite.Tags),\n Tests: previewTests,\n TotalTestsInSuite: testIds.size\n };\n }\n\n private buildSuiteTestPreviews(suiteTestLinks: MJTestSuiteTestEntity[]): SuiteTestItem[] {\n return suiteTestLinks\n .sort((a, b) => a.Sequence - b.Sequence)\n .slice(0, 5)\n .map(st => {\n const test = this.allTests.find(t => UUIDsEqual(t.ID, st.TestID));\n const lastRun = this.findLastRunForTest(st.TestID);\n return {\n TestID: st.TestID,\n TestName: test?.Name || st.Test || 'Unknown',\n LastStatus: lastRun?.Status || '',\n LastScore: lastRun?.Score || 0\n };\n });\n }\n\n private buildTestCards(): void {\n this.testCards = this.allTests.map(test => this.buildSingleTestCard(test));\n }\n\n private buildSingleTestCard(test: MJTestEntity): TestCardData {\n const runsForTest = this.testRunStats.filter(r => UUIDsEqual(r.TestID, test.ID));\n const lastRun = runsForTest.length > 0 ? runsForTest[0] : null; // already sorted DESC\n const passedRuns = runsForTest.filter(r => r.Status === 'Passed');\n const passRate = runsForTest.length > 0 ? (passedRuns.length / runsForTest.length) * 100 : 0;\n\n const typeName = this.AllTestTypes.find(t => UUIDsEqual(t.ID, test.TypeID))?.Name || '';\n const suiteName = this.findSuiteNameForTest(test.ID);\n\n return {\n ID: test.ID,\n Name: test.Name,\n Description: test.Description || '',\n Status: test.Status,\n TypeName: typeName,\n SuiteName: suiteName,\n LastRunStatus: lastRun?.Status || '',\n LastScore: lastRun?.Score || 0,\n TotalRuns: runsForTest.length,\n PassRate: passRate,\n EstDuration: test.EstimatedDurationSeconds || 0,\n EstCost: test.EstimatedCostUSD || 0,\n LastRunDate: lastRun ? this.toDate(lastRun.StartedAt) : null,\n Tags: this.parseTags(test.Tags),\n UpdatedAt: test.__mj_UpdatedAt\n };\n }\n\n // ---------------------------------------------------------------------------\n // Private: Build Suite Tree\n // ---------------------------------------------------------------------------\n\n private buildSuiteTree(): void {\n const filteredSuites = this.AllSuites;\n\n const nodeMap = new Map<string, SuiteTreeNode>();\n\n for (const suite of filteredSuites) {\n nodeMap.set(suite.ID, {\n ID: suite.ID,\n Name: suite.Name,\n ParentID: suite.ParentID,\n TestCount: this.allSuiteTests.filter(st => UUIDsEqual(st.SuiteID, suite.ID)).length,\n Children: [],\n Expanded: false\n });\n }\n\n const roots: SuiteTreeNode[] = [];\n nodeMap.forEach(node => {\n if (node.ParentID && nodeMap.has(node.ParentID)) {\n nodeMap.get(node.ParentID)!.Children.push(node);\n } else {\n roots.push(node);\n }\n });\n\n this.FilteredSuiteTree = roots;\n this.filterTestTypes();\n }\n\n private filterTestTypes(): void {\n this.FilteredTestTypes = this.AllTestTypes;\n }\n\n // ---------------------------------------------------------------------------\n // Private: Filtering & Sorting\n // ---------------------------------------------------------------------------\n\n private subscribeToStateChanges(): void {\n combineLatest([\n this._searchTerm$,\n this._statusFilters$,\n this._displayMode$,\n this._selectedSidebar$,\n this._sortField$,\n this._sortDirection$,\n this._viewMode$\n ]).pipe(\n takeUntil(this.destroy$)\n ).subscribe(([searchTerm, statusFilters, displayMode, selectedSidebar, sortField, sortDirection, viewMode]) => {\n this.SearchTerm = searchTerm;\n this.StatusFilters = statusFilters;\n this.DisplayMode = displayMode;\n this.SelectedSidebar = selectedSidebar;\n this.SortField = sortField;\n this.SortDirection = sortDirection;\n this.ViewMode = viewMode;\n this.applyFilters();\n this.settingsPersistSubject.next();\n this.cdr.markForCheck();\n });\n }\n\n private applyFilters(): void {\n this.FilteredSuites = this.filterSuiteCards();\n this.FilteredTests = this.filterTestCards();\n this.FilteredResultCount = this.FilteredSuites.length + this.FilteredTests.length;\n }\n\n private filterSuiteCards(): SuiteCardData[] {\n let result = [...this.suiteCards];\n result = this.applySidebarFilterToSuites(result);\n result = this.applySearchFilterToSuites(result);\n result = this.applyStatusFilterToSuites(result);\n result = this.sortSuiteCards(result);\n return result;\n }\n\n private filterTestCards(): TestCardData[] {\n let result = [...this.testCards];\n result = this.applySidebarFilterToTests(result);\n result = this.applySearchFilterToTests(result);\n result = this.applyStatusFilterToTests(result);\n result = this.sortTestCards(result);\n return result;\n }\n\n private applySidebarFilterToSuites(suites: SuiteCardData[]): SuiteCardData[] {\n const sel = this.SelectedSidebar;\n switch (sel.Type) {\n case 'suite':\n return suites.filter(s => UUIDsEqual(s.ID, sel.ID));\n case 'standalone':\n return []; // standalone = tests only\n case 'testType':\n return []; // test types apply to tests only\n default:\n return suites;\n }\n }\n\n private applySidebarFilterToTests(tests: TestCardData[]): TestCardData[] {\n const sel = this.SelectedSidebar;\n switch (sel.Type) {\n case 'suite': {\n const testIds = new Set(\n this.allSuiteTests.filter(st => UUIDsEqual(st.SuiteID, sel.ID)).map(st => st.TestID)\n );\n return tests.filter(t => testIds.has(t.ID));\n }\n case 'standalone': {\n const testIdsInSuites = new Set(this.allSuiteTests.map(st => st.TestID));\n return tests.filter(t => !testIdsInSuites.has(t.ID));\n }\n case 'testType':\n return tests.filter(t => {\n const testEntity = this.allTests.find(te => UUIDsEqual(te.ID, t.ID));\n return UUIDsEqual(testEntity?.TypeID, sel.ID);\n });\n default:\n return tests;\n }\n }\n\n private applySearchFilterToSuites(suites: SuiteCardData[]): SuiteCardData[] {\n const term = this.SearchTerm.toLowerCase().trim();\n if (!term) return suites;\n return suites.filter(s =>\n s.Name.toLowerCase().includes(term) ||\n s.Description.toLowerCase().includes(term)\n );\n }\n\n private applySearchFilterToTests(tests: TestCardData[]): TestCardData[] {\n const term = this.SearchTerm.toLowerCase().trim();\n if (!term) return tests;\n return tests.filter(t =>\n t.Name.toLowerCase().includes(term) ||\n t.Description.toLowerCase().includes(term)\n );\n }\n\n private applyStatusFilterToSuites(suites: SuiteCardData[]): SuiteCardData[] {\n if (this.StatusFilters.size === 0) return suites;\n return suites.filter(s => this.StatusFilters.has(s.Status));\n }\n\n private applyStatusFilterToTests(tests: TestCardData[]): TestCardData[] {\n if (this.StatusFilters.size === 0) return tests;\n return tests.filter(t => this.StatusFilters.has(t.Status));\n }\n\n private sortSuiteCards(suites: SuiteCardData[]): SuiteCardData[] {\n const dir = this.SortDirection === 'asc' ? 1 : -1;\n return suites.sort((a, b) => this.compareBySortField(a.Name, a.Status, a.LastRunDate, b.Name, b.Status, b.LastRunDate, dir));\n }\n\n private sortTestCards(tests: TestCardData[]): TestCardData[] {\n const dir = this.SortDirection === 'asc' ? 1 : -1;\n return tests.sort((a, b) => this.compareBySortField(a.Name, a.Status, a.UpdatedAt, b.Name, b.Status, b.UpdatedAt, dir));\n }\n\n private compareBySortField(\n aName: string, aStatus: string, aDate: Date | null,\n bName: string, bStatus: string, bDate: Date | null,\n dir: number\n ): number {\n switch (this.SortField) {\n case 'name':\n return aName.localeCompare(bName) * dir;\n case 'status':\n return aStatus.localeCompare(bStatus) * dir;\n case 'updated': {\n const aTime = aDate ? new Date(aDate).getTime() : 0;\n const bTime = bDate ? new Date(bDate).getTime() : 0;\n return (aTime - bTime) * dir;\n }\n default:\n return 0;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private: Helpers\n // ---------------------------------------------------------------------------\n\n private computeCounts(): void {\n const testIdsInSuites = new Set(this.allSuiteTests.map(st => st.TestID));\n this.StandaloneTestCount = this.allTests.filter(t => !testIdsInSuites.has(t.ID)).length;\n this.TotalItemCount = this.allTests.length + this.AllSuites.length;\n }\n\n private computeAvgDuration(runs: TestRunStatRow[]): number {\n const completed = runs.filter(r => r.CompletedAt != null && r.StartedAt != null);\n if (completed.length === 0) return 0;\n\n const totalMs = completed.reduce((sum, r) => {\n const start = this.toDate(r.StartedAt).getTime();\n const end = this.toDate(r.CompletedAt!).getTime();\n return sum + (end - start);\n }, 0);\n\n return totalMs / completed.length;\n }\n\n private findLastRunDate(runs: TestRunStatRow[]): Date | null {\n if (runs.length === 0) return null;\n return this.toDate(runs[0].StartedAt);\n }\n\n private findLastRunForTest(testId: string): TestRunStatRow | null {\n return this.testRunStats.find(r => UUIDsEqual(r.TestID, testId)) || null;\n }\n\n private findSuiteNameForTest(testId: string): string {\n const suiteTest = this.allSuiteTests.find(st => UUIDsEqual(st.TestID, testId));\n if (!suiteTest) return '';\n const suite = this.AllSuites.find(s => UUIDsEqual(s.ID, suiteTest.SuiteID));\n return suite?.Name || suiteTest.Suite || '';\n }\n\n private parseTags(tagsJson: string | null): string[] {\n if (!tagsJson) return [];\n try {\n const parsed = JSON.parse(tagsJson);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n }\n\n private toDate(value: string | Date | null): Date {\n if (!value) return new Date(0);\n return value instanceof Date ? value : new Date(value);\n }\n\n // ---------------------------------------------------------------------------\n // Private: User Settings\n // ---------------------------------------------------------------------------\n\n private loadUserSettings(): void {\n try {\n const widthStr = UserInfoEngine.Instance.GetSetting(TestingExplorerComponent.PANEL_WIDTH_KEY);\n if (widthStr) {\n const width = parseInt(widthStr, 10);\n if (!isNaN(width) && width >= 400 && width <= 900) {\n this.SlideoutWidth = width;\n }\n }\n const stateStr = UserInfoEngine.Instance.GetSetting(TestingExplorerComponent.SEARCH_STATE_KEY);\n if (stateStr) {\n const state = JSON.parse(stateStr) as Record<string, string>;\n if (state.searchTerm) {\n this.SearchTerm = state.searchTerm;\n this._searchTerm$.next(state.searchTerm);\n }\n }\n this.RailCollapsed = UserInfoEngine.Instance.GetSetting(TestingExplorerComponent.RAIL_COLLAPSED_KEY) === 'true';\n } catch (error) {\n console.warn('[TestingExplorer] Failed to load user settings:', error);\n } finally {\n this.settingsLoaded = true;\n }\n }\n\n private setupSettingsPersistence(): void {\n this.settingsPersistSubject.pipe(\n debounceTime(500),\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.persistSearchState();\n });\n }\n\n /** The rail toggled — take the new state and persist it (the component only presents). */\n OnRailCollapsedChange(collapsed: boolean): void {\n this.RailCollapsed = collapsed;\n if (!this.settingsLoaded) return;\n try {\n UserInfoEngine.Instance.SetSettingDebounced(\n TestingExplorerComponent.RAIL_COLLAPSED_KEY,\n String(collapsed)\n );\n } catch (error) {\n console.warn('[TestingExplorer] Failed to persist rail collapsed state:', error);\n }\n }\n\n private persistSearchState(): void {\n if (!this.settingsLoaded) return;\n try {\n const state = { searchTerm: this.SearchTerm };\n UserInfoEngine.Instance.SetSettingDebounced(\n TestingExplorerComponent.SEARCH_STATE_KEY,\n JSON.stringify(state)\n );\n } catch (error) {\n console.warn('[TestingExplorer] Failed to persist search state:', error);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private: Form Management\n // ---------------------------------------------------------------------------\n\n private resetForm(): void {\n this.FormName = '';\n this.FormDescription = '';\n this.FormTypeID = this.AllTestTypes.length > 0 ? this.AllTestTypes[0].ID : '';\n this.FormStatus = 'Active';\n this.FormParentSuiteID = '';\n this.FormEstDuration = 0;\n this.FormEstCost = 0;\n this.FormTags = '';\n this.FormErrorMessage = '';\n }\n\n private async saveNewTest(): Promise<void> {\n const md = this.ProviderToUse;\n const test = await md.GetEntityObject<MJTestEntity>('MJ: Tests');\n test.NewRecord();\n test.Name = this.FormName.trim();\n test.Description = this.FormDescription.trim() || null;\n test.TypeID = this.FormTypeID;\n test.Status = this.FormStatus;\n if (this.FormEstDuration > 0) test.EstimatedDurationSeconds = this.FormEstDuration;\n if (this.FormEstCost > 0) test.EstimatedCostUSD = this.FormEstCost;\n if (this.FormTags.trim()) {\n const tags = this.FormTags.split(',').map(t => t.trim()).filter(t => t.length > 0);\n test.Tags = JSON.stringify(tags);\n }\n const saved = await test.Save();\n if (!saved) throw new Error('Failed to save test. Please check your input and try again.');\n }\n\n private async saveNewSuite(): Promise<void> {\n const md = this.ProviderToUse;\n const suite = await md.GetEntityObject<MJTestSuiteEntity>('MJ: Test Suites');\n suite.NewRecord();\n suite.Name = this.FormName.trim();\n suite.Description = this.FormDescription.trim() || null;\n suite.Status = this.FormStatus;\n if (this.FormParentSuiteID) suite.ParentID = this.FormParentSuiteID;\n if (this.FormTags.trim()) {\n const tags = this.FormTags.split(',').map(t => t.trim()).filter(t => t.length > 0);\n suite.Tags = JSON.stringify(tags);\n }\n const saved = await suite.Save();\n if (!saved) throw new Error('Failed to save test suite. Please check your input and try again.');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"testing-explorer.component.js","sourceRoot":"","sources":["../../../src/Testing/components/testing-explorer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAIT,uBAAuB,EAEvB,KAAK,EACN,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAA4E,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACzI,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAErE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;;;;;;;;;;;IAkF/D,wBAAyD;;;IAAzD,yGAA0C;;;;IAA3B,6CAAyB;;;IAyDtC,wBAAyD;;;;IA9CvD,AARF,AADF,sCAAgB,wBAI4B,aAK9B;IACR,mCAIgB;IAClB,iBAAM;IAEJ,AADF,8BAAa,gBAC2D;IAAvB,4LAAS,mBAAY,KAAC;IACnE,uBAAuC;IAAC,+BAA+B;IAAA,yBAAS;IAClF,AADkF,iBAAO,EAChF;IACT,iCAAmE;IAAtB,4LAAS,kBAAW,KAAC;IAChE,yBAAgC;IAAC,gCAA+B;IAAA,yBAAQ;IAE5E,AADE,AAD0E,iBAAO,EACxE,EACL;IAOJ,AANF,gCAAa,0BASkC;IAA3C,uNAAe,iCAA0B,KAAC;IAC5C,iBAAiB;IACjB,8CAK0C;IAAxC,gOAAqB,wBAAiB,KAAC;IACvC,4CAI8B;IAA5B,AADA,0NAAgB,mCAA4B,KAAC,yLACpC,wBAAiB,KAAC;IAE/B,AADE,iBAAkB,EACA;IACpB,2CAG0C;IAAxC,mNAAa,0BAAyB,KAAC;IAG7C,AADE,AADE,iBAAiB,EACb,EACS;IACjB,2GAA0C;IAC5C,iBAAiB;;;;IA7CT,eAA6B;IAC7B,AADA,kDAA6B,gCACL;IAoBxB,gBAAoB;IAApB,yCAAoB;IAMpB,cAAsC;IACtC,AADA,2DAAsC,mDACK;IAGzC,cAAuB;IACvB,AADA,4CAAuB,+BACA;IAMzB,cAA6B;IAC7B,AADA,kDAA6B,8BACP;IAKb,cAAyB;IAAzB,6CAAyB;;;IAUxC,+BAA8B;IAC5B,iCAAyD;IAC3D,iBAAM;;;IAqCgB,2BAA6B;IAC7B,YACF;;;;IADE,cACF;IADE,yFACF;;;IAGA,wBAA6F;;;;;IAAjE,4GAA4D;;;IA2BpF,+BAA8B;IAC5B,2BAAiF;IACjF,gCAAgC;IAAA,YAAgB;IAAA,iBAAO;IACvD,gCAAiE;IAAA,YAAqC;IAAA,iBAAO;IAC7G,gCAA0B;IACxB,2BAAuH;IACzH,iBAAO;IACP,gCAA6E;IAAA,YAAkB;IACjG,AADiG,iBAAO,EAClG;;;;IAPsB,cAA+C;;IACzC,eAAgB;IAAhB,mCAAgB;IACpB,cAAoC;IAApC,mDAAoC;IAAC,cAAqC;IAArC,iEAAqC;IAEjC,eAA4C;IAA5C,2DAA4C;IAAhF,kDAAmC;IAEvC,cAA+C;;IAAC,cAAkB;IAAlB,qCAAkB;;;IARnG,gLAAa;;;IAAb,6CAUC;;;IAGD,+BAA0B;IAAA,YAA6C;IAAA,iBAAM;;;IAAnD,cAA6C;IAA7C,yEAA6C;;;IAf3E,+BAAgC;IAC9B,0KAYC;IACD,wKAAmC;IAGrC,iBAAM;;;IAhBJ,cAYC;IAZD,6BAYC;IACD,eAEC;IAFD,yDAEC;;;;IArDH,AADF,AADF,+BAAwB,cACG,cACK;IAE1B,AADA,wBAA4D,eACyB;;IACrF,gCAA2E;IAAA,YAAkB;IAC/F,AAD+F,iBAAO,EAChG;IACN,+BAA2B;IACzB,YACA;IAAA,gJAAyB;IAI3B,iBAAM;IACN,yJAAyB;IAG3B,iBAAM;IAIF,AADF,AADF,gCAAwB,eACJ,gBACS;IAAA,0BAAS;IAAA,iBAAO;IACzC,iCAAuE;IAAA,aAAmC;IAC5G,AAD4G,iBAAO,EAC7G;IAEJ,AADF,gCAAkB,gBACS;IAAA,sBAAK;IAAA,iBAAO;IACrC,iCAAyB;IAAA,aAAqB;IAChD,AADgD,iBAAO,EACjD;IAEJ,AADF,gCAAkB,gBACS;IAAA,0BAAS;IAAA,iBAAO;IACzC,iCAAiE;IAAA,aAAwC;IAC3G,AAD2G,iBAAO,EAC5G;IAEJ,AADF,gCAAkB,gBACS;IAAA,6BAAY;IAAA,iBAAO;IAC5C,iCAAyB;IAAA,aAAuC;IAEpE,AADE,AADkE,iBAAO,EACnE,EACF;IAEN,2JAA8B;IAsB5B,AADF,gCAA0B,kBAC4C;IAA7B,yQAAS,4BAAkB,KAAC;IACjE,yBAAgC;IAAC,4BACnC;IAAA,iBAAS;IACT,mCAA8E;IAArC,yQAAS,oCAA0B,KAAC;IAC3E,yBAAqC;IAAC,0BACxC;IAAA,iBAAS;IACT,mCAAyF;IAAhD,yQAAS,gBAAS,iBAAiB,cAAW,KAAC;IACtF,yBAA+B;IAAC,uBAClC;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;;IAlEwB,eAAqD;IAArD,sGAAqD;IAClD,eAA+C;;IAAC,cAAkB;IAAlB,qCAAkB;IAG7F,eACA;IADA,yDACA;IAAA,cAGC;IAHD,gDAGC;IAEH,cAEC;IAFD,gDAEC;IAM0B,eAA6C;IAA7C,4DAA6C;IAAC,cAAmC;IAAnC,6DAAmC;IAIjF,eAAqB;IAArB,wCAAqB;IAIrB,eAAuC;IAAvC,sDAAuC;IAAC,cAAwC;IAAxC,oEAAwC;IAIhF,eAAuC;IAAvC,iEAAuC;IAIpE,cAmBC;IAnBD,qDAmBC;;;IAhEP,AADF,+BAA6B,aACD;IACxB,wBAAkC;IAClC,6BACA;IAAA,gCAA4B;IAAA,YAA2B;IACzD,AADyD,iBAAO,EAC3D;IACL,+BAAuB;IACrB,sJAwEC;IAEL,AADE,iBAAM,EACF;;;IA7E0B,eAA2B;IAA3B,kDAA2B;IAGvD,eAwEC;IAxED,oCAwEC;;;IAhFP,qIAAiC;;;IAAjC,2DAmFC;;;IAwBe,2BAA6B;IAC7B,YACF;;;IADE,cACF;IADE,mDACF;;;IAGA,wBAA4F;;;;;IAAhE,4GAA2D;;;IAIrF,gCAAwB;IAAA,wBAAiC;IAAC,YAAmB;IAAA,iBAAO;;;IAA1B,eAAmB;IAAnB,6CAAmB;;;IAG7E,gCAAwB;IAAA,wBAAiC;IAAC,YAA8C;IAAA,iBAAO;;;;IAArD,eAA8C;IAA9C,+EAA8C;;;IAGxG,gCAAwB;IAAA,wBAAuC;IAAC,YAA8B;IAAA,iBAAO;;;;IAArC,eAA8B;IAA9B,+DAA8B;;;IAQ1F,gCAAkB;IAAA,YAAS;IAAA,iBAAO;;;IAAhB,cAAS;IAAT,6BAAS;;;IAD7B,+KAAa;;;IAAb,8CAEC;;;IAGD,gCAA2B;IAAA,YAA2B;IAAA,iBAAO;;;IAAlC,cAA2B;IAA3B,oDAA2B;;;IAP1D,+BAAuB;IACrB,4LAIC;IACD,yKAA4B;IAG9B,iBAAM;;;IARJ,cAIC;IAJD,4BAIC;IACD,eAEC;IAFD,mDAEC;;;;IApCL,AADF,AADF,+BAAuB,cACI,cACK;IAE1B,AADA,wBAAoD,eACgC;;IACpF,gCAA0E;IAAA,YAAiB;IAC7F,AAD6F,iBAAO,EAC9F;IACN,+BAA2B;IACzB,YACA;IAAA,gJAAsB;IAIxB,iBAAM;IACN,yJAAwB;IAGxB,gCAA2B;IACzB,4JAAqB;IAGrB,4JAA4B;IAG5B,4JAAwB;IAGxB,iCAAwB;IAAA,yBAAoC;IAAC,aAAwC;IACvG,AADuG,iBAAO,EACxG;IACN,2JAA4B;IAY9B,iBAAM;IAIF,AADF,AADF,gCAAwB,eACJ,gBACS;IAAA,4BAAW;IAAA,iBAAO;IAC3C,iCAA2F;IAAA,aAAiC;IAC9H,AAD8H,iBAAO,EAC/H;IAEJ,AADF,gCAAkB,gBACS;IAAA,sBAAK;IAAA,iBAAO;IACrC,iCAAiE;IAAA,aAA0E;IAC7I,AAD6I,iBAAO,EAC9I;IAEJ,AADF,gCAAkB,gBACS;IAAA,2BAAU;IAAA,iBAAO;IAC1C,iCAAyB;IAAA,aAAoB;IAC/C,AAD+C,iBAAO,EAChD;IAEJ,AADF,gCAAkB,gBACS;IAAA,0BAAS;IAAA,iBAAO;IACzC,iCAAsE;IAAA,aAA+D;IAEzI,AADE,AADuI,iBAAO,EACxI,EACF;IAGJ,AADF,gCAA0B,kBAC0C;IAA3B,0QAAS,2BAAgB,KAAC;IAC/D,yBAAgC;IAAC,sBACnC;IAAA,iBAAS;IACT,mCAA4E;IAAnC,0QAAS,mCAAwB,KAAC;IACzE,yBAAmC;IAAC,0BACtC;IAAA,iBAAS;IACT,mCAAkF;IAAzC,0QAAS,gBAAS,WAAW,cAAU,KAAC;IAC/E,yBAA+B;IAAC,uBAClC;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;;IArEwB,eAAoD;IAApD,sGAAoD;IACjD,eAA8C;;IAAC,cAAiB;IAAjB,qCAAiB;IAG3F,eACA;IADA,kDACA;IAAA,cAGC;IAHD,8CAGC;IAEH,cAEC;IAFD,gDAEC;IAEC,eAEC;IAFD,6CAEC;IACD,cAEC;IAFD,oDAEC;IACD,cAEC;IAFD,gDAEC;IAC4D,eAAwC;IAAxC,yEAAwC;IAEvG,cAWC;IAXD,oDAWC;IAMsC,eAAqD;;IAAC,cAAiC;IAAjC,qDAAiC;IAInG,eAAuC;IAAvC,uDAAuC;IAAC,cAA0E;IAA1E,kGAA0E;IAIlH,eAAoB;IAApB,wCAAoB;IAIpB,eAA4C;IAA5C,4DAA4C;IAAC,cAA+D;IAA/D,8FAA+D;;;IAjE/I,AADF,+BAA6B,aACD;IACxB,wBAAgC;IAChC,uBACA;IAAA,gCAA4B;IAAA,YAA0B;IACxD,AADwD,iBAAO,EAC1D;IACL,+BAAuB;IACrB,sJA2EC;IAEL,AADE,iBAAM,EACF;;;IAhF0B,eAA0B;IAA1B,iDAA0B;IAGtD,eA2EC;IA3ED,mCA2EC;;;IAnFP,qIAAgC;;;IAAhC,0DAsFC;;;IAKD,qCAEoD;;;;IArM1D,uCAS2C;IAAzC,AADA,AADA,0OAAmB,oCAA6B,KAAC,qNAClC,+BAAwB,KAAC,qNACzB,+BAAwB,KAAC;IAC1C,iBAAc;IAGZ,AADF,2CAAqB,4BACI;IAErB,4GAAyD;IAwFzD,4GAAwD;IA2FxD,kIAAiE;IAMrE,AADE,iBAAwB,EACJ;;;IAlMpB,AADA,AADA,AADA,AADA,6CAAwB,gCACA,sCACM,qBACV,mCACO;IASzB,eAqFC;IArFD,0FAqFC;IAGD,cAwFC;IAxFD,yFAwFC;IAGD,cAIC;IAJD,kGAIC;;;;IAOP,+BAAyD;IAA1B,yMAAS,sBAAe,KAAC;IAAC,iBAAM;;;IA0CzD,+BAA4B;IAC1B,yBAA8C;IAC9C,4BAAM;IAAA,YAAsB;IAC9B,AAD8B,iBAAO,EAC/B;;;IADE,eAAsB;IAAtB,6CAAsB;;;IAoClB,kCAAwB;IAAA,YAAa;IAAA,iBAAS;;;IAAtC,iCAAe;IAAC,cAAa;IAAb,iCAAa;;;;IAJzC,AADF,+BAAwB,gBACI;IAAA,0BAAU;IAAA,gCAA4B;IAAA,iBAAC;IAAO,AAAP,iBAAO,EAAQ;IAChF,kCAAoD;IAAzB,oVAAwB;IACjD,mCAA0B;IAAA,8BAAc;IAAA,iBAAS;IACjD,0IAEC;IAEL,AADE,iBAAS,EACL;;;IANuB,eAAwB;IAAxB,iDAAwB;IAEjD,eAEC;IAFD,kCAEC;;;IAUC,kCAAuB;IAAA,YAAY;IAAA,iBAAS;;;IAApC,gCAAc;IAAC,cAAY;IAAZ,gCAAY;;;;IAJvC,AADF,+BAAwB,gBACI;IAAA,4BAAY;IAAA,iBAAQ;IAC9C,kCAA2D;IAAhC,kWAA+B;IACxD,mCAAiB;IAAA,gCAAgB;IAAA,iBAAS;IAC1C,0IAEC;IAEL,AADE,iBAAS,EACL;;;IANuB,eAA+B;IAA/B,wDAA+B;IAExD,eAEC;IAFD,+BAEC;;;IAQD,kCAAyB;IAAA,YAAY;IAAA,iBAAS;;;IAAtC,kCAAgB;IAAC,cAAY;IAAZ,gCAAY;;;;IAS3C,AADF,+BAA0B,cACQ;IAAA,yBAAS;IAAA,iBAAM;IAG3C,AADF,AADF,+BAAsB,cACI,gBACI;IAAA,kCAAkB;IAAA,iBAAQ;IACpD,kCAME;IAHA,6VAA6B;IAIjC,AAPE,iBAME,EACE;IAEJ,AADF,+BAAwB,gBACI;IAAA,2BAAU;IAAA,iBAAQ;IAC5C,mCAOE;IAJA,sVAAyB;IAOjC,AADE,AADE,AARE,iBAOE,EACE,EACF,EACF;;;IAjBE,eAA6B;IAA7B,sDAA6B;IAU7B,eAAyB;IAAzB,kDAAyB;;;IA6B/B,wBAA2C;;;IAE3C,yBAAiC;;;;IAlJrC,AADF,AAFF,+BAAgC,cAED,cACK;IAC9B,wBAA2D;IAC3D,gCAAkC;IAChC,YACF;IACF,AADE,iBAAO,EACH;IACN,kCAA6D;IAA1B,4MAAS,sBAAe,KAAC;IAC1D,wBAAiC;IAErC,AADE,iBAAS,EACL;IAIJ,AADF,+BAAkC,iBAK/B;IADC,4MAAS,6BAAsB,MAAM,CAAC,KAAC;IAEvC,yBAAgC;IAAC,uBACnC;IAAA,iBAAS;IACT,mCAIC;IADC,6MAAS,6BAAsB,OAAO,CAAC,KAAC;IAExC,yBAAkC;IAAC,wBACrC;IACF,AADE,iBAAS,EACL;IAGN,yHAAwB;IAUpB,AADF,AADF,gCAA2B,eACC,eACQ;IAAA,wBAAO;IAAA,iBAAM;IAG3C,AADF,gCAAwB,iBACI;IAAA,sBAAK;IAAA,iCAA4B;IAAA,kBAAC;IAAO,AAAP,iBAAO,EAAQ;IAC3E,kCAKE;IAFA,iUAAsB;IAG1B,AANE,iBAKE,EACE;IAGJ,AADF,gCAAwB,iBACI;IAAA,4BAAW;IAAA,iBAAQ;IAC7C,qCAKC;IAHC,kVAA6B;IAIjC,AADG,iBAAW,EACR;IAEN,gCAAsB;IACpB,0HAAqC;IAWrC,yHAAsC;IAYpC,AADF,gCAAwB,iBACI;IAAA,uBAAM;IAAA,iBAAQ;IACxC,mCAAoD;IAAzB,sUAAwB;IACjD,+IAEC;IAIT,AADE,AADE,AADE,iBAAS,EACL,EACF,EACF;IAEN,0HAAqC;IA8BnC,AADF,gCAA0B,eACQ;IAAA,qBAAI;IAAA,iBAAM;IAExC,AADF,gCAAwB,iBAMpB;IAFA,iUAAsB;IAHxB,iBAKE;IACF,iCAAwB;IAAA,mDAAkC;IAGhE,AADE,AADE,AAD4D,iBAAO,EAC7D,EACF,EACF;IAIJ,AADF,gCAA6B,kBACiC;IAA1B,6MAAS,sBAAe,KAAC;IAAC,uBAAM;IAAA,iBAAS;IAC3E,mCAA2F;IAA3D,6MAAS,iBAAU,KAAC;IAGhD,AAFF,uHAAgB,kGAEP;IAGT,aACF;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;IApJE,eACF;IADE,oGACF;IAWA,eAA8C;IAA9C,8DAA8C;IAO9C,eAA+C;IAA/C,+DAA+C;IAQnD,eAKC;IALD,mDAKC;IAYO,gBAAsB;IAAtB,+CAAsB;IACtB,wIAAmH;IAQnH,eAA6B;IAA7B,sDAA6B;IAE7B,sIAAiH;IAKnH,eAUC;IAVD,gEAUC;IACD,cAUC;IAVD,iEAUC;IAG4B,eAAwB;IAAxB,iDAAwB;IACjD,cAEC;IAFD,uCAEC;IAMT,eA2BC;IA3BD,gEA2BC;IAQK,eAAsB;IAAtB,+CAAsB;IAWyB,eAAqC;IAArC,iEAAqC;IACxF,cAIC;IAJD,2CAIC;IACD,eACF;IADE,+FACF;;;;IAQN,2CAI6B;IAA3B,sNAAU,sBAAe,KAAC;IAC1B,gDAKiC;IAA/B,mOAAc,sBAAe,KAAC;IAElC,AADE,iBAAsB,EACP;;;IATf,gCAAkB;IAGhB,cAAkB;IAGlB,AADA,AADA,AADA,gCAAkB,uIACkD,yIACE,gIACT;;;;IApYjE,wCAA8D;IAK5D,AAJF,yGAAiB,wEAIR;IA6MX,yGAAoB;IAMlB,AADF,+BAAyF,cACf;IAApC,uMAAa,4BAAqB,KAAC;IAAC,iBAAM;IAE9E,2GAAoB;IA6JtB,iBAAM;IAGN,oHAAwC;IAetC,iBAAe;;;IAzYa,AAAd,2BAAa,kBAAkB;IAC7C,cA8MC;IA9MD,0CA8MC;IAGH,eAEC;IAFD,8CAEC;IAGuD,cAAgC;IAAhC,mDAAgC;IAA5D,2CAA2B;IAGrD,eA4JC;IA5JD,8CA4JC;IAIH,cAcC;IAdD,kEAcC;;AAssBL,MAAM,OAAO,wBAAyB,SAAQ,oBAAoB;IA8GtD;IACA;IACD;IACA;IA/GO,iBAAiB,GAAuB;QACtD,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,WAAW,EAAE;QAC7D,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,WAAW,EAAE;KAC9D,CAAC;IAEc,kBAAkB,GAAuB;QACvD,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;QAC5B,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;QAClC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;KACjC,CAAC;IAEF,yFAAyF;IAClF,kBAAkB,CAAC,KAAa;QACrC,MAAM,SAAS,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAsB,CAAC;QAC5D,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,0FAA0F;IACjF,WAAW,GAAG,KAAK,CAAC;IAErB,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAEvC,kBAAkB;IACV,QAAQ,GAAmB,EAAE,CAAC;IACtC,SAAS,GAAwB,EAAE,CAAC;IAC5B,aAAa,GAA4B,EAAE,CAAC;IACpD,YAAY,GAAuB,EAAE,CAAC;IAC9B,YAAY,GAAqB,EAAE,CAAC;IAE5C,qBAAqB;IACb,UAAU,GAAoB,EAAE,CAAC;IACjC,SAAS,GAAmB,EAAE,CAAC;IAEvC,iBAAiB;IACT,YAAY,GAAG,IAAI,eAAe,CAAS,EAAE,CAAC,CAAC;IAC/C,eAAe,GAAG,IAAI,eAAe,CAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAC9D,UAAU,GAAG,IAAI,eAAe,CAAW,MAAM,CAAC,CAAC;IACnD,aAAa,GAAG,IAAI,eAAe,CAAc,KAAK,CAAC,CAAC;IACxD,iBAAiB,GAAG,IAAI,eAAe,CAAmB,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACrF,WAAW,GAAG,IAAI,eAAe,CAAY,MAAM,CAAC,CAAC;IACrD,eAAe,GAAG,IAAI,eAAe,CAAgB,KAAK,CAAC,CAAC;IAEpE,uBAAuB;IACvB,SAAS,GAAG,IAAI,CAAC;IACjB,UAAU,GAAG,EAAE,CAAC;IAChB,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,QAAQ,GAAa,MAAM,CAAC;IAC5B,WAAW,GAAgB,KAAK,CAAC;IACjC,eAAe,GAAqB,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAC9D,SAAS,GAAc,MAAM,CAAC;IAC9B,aAAa,GAAkB,KAAK,CAAC;IAErC,mBAAmB;IACnB,cAAc,GAAoB,EAAE,CAAC;IACrC,aAAa,GAAmB,EAAE,CAAC;IACnC,iBAAiB,GAAoB,EAAE,CAAC;IACxC,iBAAiB,GAAuB,EAAE,CAAC;IAE3C,SAAS;IACT,cAAc,GAAG,CAAC,CAAC;IACnB,mBAAmB,GAAG,CAAC,CAAC;IACxB,mBAAmB,GAAG,CAAC,CAAC;IAEf,aAAa,GAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC5D,iBAAiB,GAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAEzE,gBAAgB;IACR,MAAM,CAAU,eAAe,GAAG,4BAA4B,CAAC;IAC/D,MAAM,CAAU,gBAAgB,GAAG,6BAA6B,CAAC;IACjE,MAAM,CAAU,kBAAkB,GAAG,+BAA+B,CAAC;IAE7E;;;;OAIG;IACH,aAAa,GAAG,KAAK,CAAC;IACd,sBAAsB,GAAG,IAAI,OAAO,EAAQ,CAAC;IAC7C,cAAc,GAAG,KAAK,CAAC;IAE/B,iBAAiB;IACjB,YAAY,GAAG,KAAK,CAAC;IACrB,kBAAkB,GAAqB,MAAM,CAAC;IAC9C,aAAa,GAAG,GAAG,CAAC;IACpB,QAAQ,GAAG,KAAK,CAAC;IACjB,gBAAgB,GAAG,EAAE,CAAC;IAEtB,eAAe;IACP,YAAY,GAAG,CAAC,CAAC;IACjB,gBAAgB,GAAG,CAAC,CAAC;IAE7B,cAAc;IACd,QAAQ,GAAG,EAAE,CAAC;IACd,eAAe,GAAG,EAAE,CAAC;IACrB,UAAU,GAAG,EAAE,CAAC;IAChB,UAAU,GAAsC,QAAQ,CAAC;IACzD,iBAAiB,GAAG,EAAE,CAAC;IACvB,eAAe,GAAG,CAAC,CAAC;IACpB,WAAW,GAAG,CAAC,CAAC;IAChB,QAAQ,GAAG,EAAE,CAAC;IAEd,IAAI,WAAW;QACb,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,IAAI,CAAC,kBAAkB,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QACzE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YACU,GAAsB,EACtB,gBAAkC,EACnC,oBAA0C,EAC1C,sBAAqD;QAC1D,KAAK,EAAE,CAAC;QAJF,QAAG,GAAH,GAAG,CAAmB;QACtB,qBAAgB,GAAhB,gBAAgB,CAAkB;QACnC,yBAAoB,GAApB,oBAAoB,CAAsB;QAC1C,2BAAsB,GAAtB,sBAAsB,CAA+B;IACjD,CAAC;IAEd,oDAAoD;IACpD,IAAW,oBAAoB;QAC7B,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IACD,oDAAoD;IACpD,IAAW,oBAAoB,CAAC,KAA2B;QACzD,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC;IACpC,CAAC;IAED,sDAAsD;IACtD,IAAW,sBAAsB;QAC/B,OAAO,IAAI,CAAC,sBAAsB,CAAC;IACrC,CAAC;IACD,sDAAsD;IACtD,IAAW,sBAAsB,CAAC,KAAoC;QACpE,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAC;IACtC,CAAC;IAED,8EAA8E;IAC9E,YAAY;IACZ,8EAA8E;IAE9E,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAExB,IAAI,CAAC;YACH,MAAM,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5C,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAE/B,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,IAAI,CAC/C,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB,CAAC,SAAS,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,WAAW;QACT,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACzB,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7D,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1D,cAAc,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;IACjD,CAAC;IAED,8EAA8E;IAC9E,iBAAiB;IACjB,8EAA8E;IAE9E,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9B,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,iBAAiB,CAAC,EAAU;QAC1B,OAAO,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,iBAAiB,CAAC,SAA2B;QAC3C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,cAAc,CAAC,MAAc;QAC3B,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,cAAc,CAAC,IAAiB;QAC9B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,WAAW,CAAC,IAAc;QACxB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,aAAa,CAAC,KAAY;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,MAA0B,CAAC;QAC/C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,WAAW;QACT,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,iBAAiB,CAAC,IAAmB;QACnC,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,8EAA8E;IAC9E,yBAAyB;IACzB,EAAE;IACF,4EAA4E;IAC5E,+EAA+E;IAC/E,kEAAkE;IAClE,uBAAuB;IACvB,8EAA8E;IAE9E,mDAAmD;IACnD,IAAI,WAAW;QACb,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YACpD,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,IAAI,EAAmB,CAAC;YACvF,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QAEtE,OAAO;YACL;gBACE,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE;oBACL,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE;oBAC9F,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE;iBAC3G;aACF;YACD,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE;YAC3C;gBACE,KAAK,EAAE,YAAY;gBACnB,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;oBACvC,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE;oBACvB,KAAK,EAAE,EAAE,CAAC,IAAI;oBACd,IAAI,EAAE,iBAAiB;oBACvB,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,CAAC;iBACvC,CAAC,CAAC;aACJ;SACF,CAAC;IACJ,CAAC;IAED;;kDAE8C;IACtC,kBAAkB,CAAC,IAAmB;QAC5C,OAAO;YACL,EAAE,EAAE,SAAS,IAAI,CAAC,EAAE,EAAE;YACtB,KAAK,EAAE,IAAI,CAAC,IAAI;YAChB,IAAI,EAAE,oBAAoB;YAC1B,KAAK,EAAE,IAAI,CAAC,SAAS;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;SACrE,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,IAAI,WAAW;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC;QACjC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACpD,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QACvC,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,iFAAiF;IACjF,IAAI,cAAc;QAChB,MAAM,GAAG,GAAa,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,KAAsB,EAAQ,EAAE;YAC5C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC,CAAC,QAAQ;oBAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC1C,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACnB,CAAC;QACH,CAAC,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,8EAA8E;IAC9E,gBAAgB,CAAC,IAAmB;QAClC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACnB,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;YACjB,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;aAAM,IAAI,EAAE,KAAK,YAAY,EAAE,CAAC;YAC/B,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/E,CAAC;aAAM,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,gBAAgB,CAAC,IAAmB;QAClC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;QACjE,IAAI,IAAI;YAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAEO,aAAa,CAAC,IAAqB,EAAE,EAAU;QACrD,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC;gBAAE,OAAO,IAAI,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACpD,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8EAA8E;IAC9E,6BAA6B;IAC7B,EAAE;IACF,8EAA8E;IAC9E,sEAAsE;IACtE,uEAAuE;IACvE,yDAAyD;IACzD,8EAA8E;IAE9D,gBAAgB,GAAG;QACjC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;QAC/B,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;QACrC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;KACpC,CAAC;IAEF,gDAAgD;IAChD,IAAW,gBAAgB;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAEe,oBAAoB,GAAG;QACrC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE;QACnC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE;KACtC,CAAC;IAEF,oDAAoD;IACpD,IAAW,oBAAoB;QAC7B,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,IAAW,YAAY;QACrB,OAAO;YACL,EAAE,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE;oBAC/D,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;oBAC7B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;oBACnC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;iBAClC,EAAE;YACH,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE;oBACzE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;oBACnC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;oBACrC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;iBACxC,EAAE;YACH,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS;gBACpD,IAAI,EAAE,mCAAmC,EAAE,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE;YAC7E,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;gBAC1D,IAAI,EAAE,iCAAiC,EAAE,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE;SAChF,CAAC;IACJ,CAAC;IAED,4CAA4C;IAC5C,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,IAAW,YAAY;QACrB,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;YACtC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,aAAa,EAAE,IAAI,CAAC,aAAa;SAClC,CAAC;IACJ,CAAC;IAED,4CAA4C;IAC5C,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAEM,oBAAoB,CAAC,MAA+B;QACzD,IAAI,aAAa,IAAI,MAAM,EAAE,CAAC;YAC5B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAgB,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,QAAQ,CAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YAClF,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,WAAW,IAAI,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAc,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,eAAe,IAAI,MAAM,EAAE,CAAC;YAC9B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAkB,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,oDAAoD;IAC7C,oBAAoB,CAAC,MAA+B;QACzD,OAAO,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAEM,gBAAgB;QACrB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,gDAAgD;IACzC,gBAAgB;QACrB,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;IAED,mEAAmE;IAC5D,eAAe;QACpB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,GAAG,EAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED,+CAA+C;IACxC,eAAe;QACpB,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;IAChC,CAAC;IAED,mFAAmF;IACnF,IAAW,qBAAqB;QAC9B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM;YAAE,KAAK,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,aAAa,KAAK,KAAK;YAAE,KAAK,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oFAAoF;IACpF,IAAW,sBAAsB;QAC/B,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAClF,CAAC;IAGD,OAAO,CAAC,MAAc;QACpB,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,QAAQ,CAAC,OAAe;QACtB,IAAI,CAAC,oBAAoB,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,aAAa;QACX,IAAI,CAAC,oBAAoB,CAAC,UAAU,EAAE,CAAC;QACvC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,QAAQ,CAAC,UAAkB,EAAE,EAAU;QACrC,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,UAAU,EAAE,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACpI,CAAC;IAED,eAAe,CAAC,MAAc;QAC5B,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,gBAAgB,CAAC,OAAe;QAC9B,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED,SAAS;QACP,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,UAAU;QACR,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,YAAY,CAAC,IAAsB;QACjC,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,aAAa;QACX,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,qBAAqB,CAAC,IAAsB;QAC1C,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAE/C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAExB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,kBAAkB,KAAK,MAAM,EAAE,CAAC;gBACvC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,MAAM,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC;YACvF,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,aAAa,CAAC,KAAiB;QAC7B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,aAAa,CAAC;QAC3C,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1D,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACvD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;IAC1C,CAAC;IAEO,YAAY,GAAG,CAAC,KAAiB,EAAQ,EAAE;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,CAAC,CAAC;QACjF,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC,CAAC;IAEM,WAAW,GAAG,GAAS,EAAE;QAC/B,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7D,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1D,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;QACpC,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CACzC,wBAAwB,CAAC,eAAe,EACxC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAC3B,CAAC;IACJ,CAAC,CAAC;IAEF,mBAAmB,CAAC,MAAc;QAChC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;IACvE,CAAC;IAED,8EAA8E;IAC9E,qBAAqB;IACrB,8EAA8E;IAE9E,cAAc,CAAC,EAAU;QACvB,IAAI,EAAE,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,EAAE,GAAG,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;QAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC;QAClC,IAAI,OAAO,GAAG,CAAC;YAAE,OAAO,GAAG,OAAO,KAAK,OAAO,GAAG,CAAC;QAClD,OAAO,GAAG,OAAO,GAAG,CAAC;IACvB,CAAC;IAED,qBAAqB,CAAC,OAAe;QACnC,IAAI,OAAO,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,OAAO,GAAG,EAAE,CAAC;QAC1B,IAAI,OAAO,GAAG,CAAC;YAAE,OAAO,GAAG,OAAO,KAAK,IAAI,GAAG,CAAC;QAC/C,OAAO,GAAG,IAAI,GAAG,CAAC;IACpB,CAAC;IAED,kBAAkB,CAAC,IAAiB;QAClC,IAAI,CAAC,IAAI;YAAE,OAAO,OAAO,CAAC;QAC1B,MAAM,CAAC,GAAG,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;QAE/C,IAAI,WAAW,GAAG,CAAC;YAAE,OAAO,UAAU,CAAC;QACvC,IAAI,WAAW,GAAG,EAAE;YAAE,OAAO,GAAG,WAAW,OAAO,CAAC;QACnD,IAAI,SAAS,GAAG,EAAE;YAAE,OAAO,GAAG,SAAS,OAAO,CAAC;QAC/C,IAAI,QAAQ,GAAG,EAAE;YAAE,OAAO,GAAG,QAAQ,OAAO,CAAC;QAC7C,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,aAAa,CAAC,KAAa;QACzB,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;IACjC,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,IAAI,IAAI,GAAG,IAAI;YAAE,OAAO,OAAO,CAAC;QAChC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/B,CAAC;IAED,aAAa,CAAC,KAAa;QACzB,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,MAAM,CAAC;QAChC,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,MAAM,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,cAAc,CAAC,MAAc;QAC3B,QAAQ,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7B,KAAK,QAAQ,CAAC,CAAC,OAAO,eAAe,CAAC;YACtC,KAAK,QAAQ,CAAC,CAAC,OAAO,eAAe,CAAC;YACtC,KAAK,OAAO,CAAC,CAAC,OAAO,cAAc,CAAC;YACpC,KAAK,SAAS,CAAC,CAAC,OAAO,gBAAgB,CAAC;YACxC,OAAO,CAAC,CAAC,OAAO,gBAAgB,CAAC;QACnC,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,wBAAwB;IACxB,8EAA8E;IAEtE,kBAAkB;QACxB,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC;QAC3C,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAiB;YAC9C,UAAU,EAAE,eAAe;YAC3B,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,CAAC;YAClF,OAAO,EAAE,gBAAgB;YACzB,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,CAAC;IAED,8EAA8E;IAC9E,2BAA2B;IAC3B,8EAA8E;IAEtE,eAAe;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;IAClF,CAAC;IAEO,oBAAoB,CAAC,KAAwB;QACnD,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACzF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAE1E,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/F,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC;YACtC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM;YAC5E,CAAC,CAAC,CAAC,CAAC;QACN,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QACvD,MAAM,YAAY,GAAG,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;QAEjE,OAAO;YACL,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;YACpC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,SAAS,EAAE,OAAO,CAAC,IAAI;YACvB,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,WAAW;YACxB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;YAChC,KAAK,EAAE,YAAY;YACnB,iBAAiB,EAAE,OAAO,CAAC,IAAI;SAChC,CAAC;IACJ,CAAC;IAEO,sBAAsB,CAAC,cAAuC;QACpE,OAAO,cAAc;aAClB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;aACvC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,EAAE,CAAC,EAAE;YACR,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;YAClE,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YACnD,OAAO;gBACL,MAAM,EAAE,EAAE,CAAC,MAAM;gBACjB,QAAQ,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,SAAS;gBAC5C,UAAU,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;gBACjC,SAAS,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;aAC/B,CAAC;QACJ,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,CAAC;IAEO,mBAAmB,CAAC,IAAkB;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACjF,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,sBAAsB;QACtF,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;QAClE,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7F,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;QACxF,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAErD,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,QAAQ;YAClB,SAAS,EAAE,SAAS;YACpB,aAAa,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;YACpC,SAAS,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;YAC9B,SAAS,EAAE,WAAW,CAAC,MAAM;YAC7B,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,IAAI,CAAC,wBAAwB,IAAI,CAAC;YAC/C,OAAO,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC;YACnC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;YAC5D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;YAC/B,SAAS,EAAE,IAAI,CAAC,cAAc;SAC/B,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,4BAA4B;IAC5B,8EAA8E;IAEtE,cAAc;QACpB,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;QAEtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;QACjD,MAAM,gBAAgB,GAAG,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QAE3E,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE;gBACpB,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,SAAS,EAAE,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;gBAC9C,QAAQ,EAAE,EAAE;gBACZ,QAAQ,EAAE,KAAK;aAChB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,KAAK,GAAoB,EAAE,CAAC;QAClC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACrB,IAAI,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAChD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,YAAY,CAAC;IAC7C,CAAC;IAED,8EAA8E;IAC9E,+BAA+B;IAC/B,8EAA8E;IAEtE,uBAAuB;QAC7B,aAAa,CAAC;YACZ,IAAI,CAAC,YAAY;YACjB,IAAI,CAAC,eAAe;YACpB,IAAI,CAAC,aAAa;YAClB,IAAI,CAAC,iBAAiB;YACtB,IAAI,CAAC,WAAW;YAChB,IAAI,CAAC,eAAe;YACpB,IAAI,CAAC,UAAU;SAChB,CAAC,CAAC,IAAI,CACL,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,EAAE;YAC5G,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC7B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;YACnC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;YAC/B,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;YACvC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;YAC3B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;YACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACzB,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,YAAY;QAClB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5C,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;IACpF,CAAC;IAEO,gBAAgB;QACtB,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,MAAM,GAAG,IAAI,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACrC,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,eAAe;QACrB,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,0BAA0B,CAAC,MAAuB;QACxD,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC;QACjC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,OAAO;gBACV,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACtD,KAAK,YAAY;gBACf,OAAO,EAAE,CAAC,CAAC,0BAA0B;YACvC,KAAK,UAAU;gBACb,OAAO,EAAE,CAAC,CAAC,iCAAiC;YAC9C;gBACE,OAAO,MAAM,CAAC;QAClB,CAAC;IACH,CAAC;IAEO,yBAAyB,CAAC,KAAqB;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC;QACjC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CACrF,CAAC;gBACF,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9C,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;gBACzE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACvD,CAAC;YACD,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC7C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5E,CAAC;YACD;gBACE,OAAO,KAAK,CAAC;QACjB,CAAC;IACH,CAAC;IAEO,yBAAyB,CAAC,MAAuB;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAClD,IAAI,CAAC,IAAI;YAAE,OAAO,MAAM,CAAC;QACzB,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACvB,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YACnC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAC3C,CAAC;IACJ,CAAC;IAEO,wBAAwB,CAAC,KAAqB;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAClD,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACtB,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YACnC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAC3C,CAAC;IACJ,CAAC;IAEO,yBAAyB,CAAC,MAAuB;QACvD,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;QACjD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC;IAEO,wBAAwB,CAAC,KAAqB;QACpD,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAChD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,CAAC;IAEO,cAAc,CAAC,MAAuB;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/H,CAAC;IAEO,aAAa,CAAC,KAAqB;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1H,CAAC;IAEO,kBAAkB,CACxB,KAAa,EAAE,OAAe,EAAE,KAAkB,EAClD,KAAa,EAAE,OAAe,EAAE,KAAkB,EAClD,GAAW;QAEX,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;YACvB,KAAK,MAAM;gBACT,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;YAC1C,KAAK,QAAQ;gBACX,OAAO,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC;YAC9C,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC;YAC/B,CAAC;YACD;gBACE,OAAO,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,mBAAmB;IACnB,8EAA8E;IAEtE,aAAa;QACnB,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QACxF,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;IACrE,CAAC;IAEO,kBAAkB,CAAC,IAAsB;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC;QACjF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAErC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;YACjD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAY,CAAC,CAAC,OAAO,EAAE,CAAC;YAClD,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;QAC7B,CAAC,EAAE,CAAC,CAAC,CAAC;QAEN,OAAO,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC;IACpC,CAAC;IAEO,eAAe,CAAC,IAAsB;QAC5C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACnC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAEO,kBAAkB,CAAC,MAAc;QACvC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC;IAC3E,CAAC;IAEO,oBAAoB,CAAC,MAAc;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5E,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;IAC9C,CAAC;IAEO,SAAS,CAAC,QAAuB;QACvC,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACpC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,KAA2B;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,OAAO,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IACzD,CAAC;IAED,8EAA8E;IAC9E,yBAAyB;IACzB,8EAA8E;IAEtE,gBAAgB;QACtB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC;YAC9F,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACrC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;oBAClD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;gBAC7B,CAAC;YACH,CAAC;YACD,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;YAC/F,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAA2B,CAAC;gBAC7D,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;oBACrB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;oBACnC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,KAAK,MAAM,CAAC;QAClH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,iDAAiD,EAAE,KAAK,CAAC,CAAC;QACzE,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAEO,wBAAwB;QAC9B,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAC9B,YAAY,CAAC,GAAG,CAAC,EACjB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB,CAAC,SAAS,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,0FAA0F;IAC1F,qBAAqB,CAAC,SAAkB;QACtC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO;QACjC,IAAI,CAAC;YACH,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CACzC,wBAAwB,CAAC,kBAAkB,EAC3C,MAAM,CAAC,SAAS,CAAC,CAClB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,2DAA2D,EAAE,KAAK,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO;QACjC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;YAC9C,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CACzC,wBAAwB,CAAC,gBAAgB,EACzC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CACtB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,mDAAmD,EAAE,KAAK,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,2BAA2B;IAC3B,8EAA8E;IAEtE,SAAS;QACf,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,WAAW;QACvB,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,eAAe,CAAe,WAAW,CAAC,CAAC;QACjE,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;QACvD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;QAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC;YAAE,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,eAAe,CAAC;QACnF,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC;YAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC;QACnE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnF,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC7F,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,eAAe,CAAoB,iBAAiB,CAAC,CAAC;QAC7E,KAAK,CAAC,SAAS,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAClC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;QACxD,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;QAC/B,IAAI,IAAI,CAAC,iBAAiB;YAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACpE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnF,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACnG,CAAC;kHA5kCU,wBAAwB;6DAAxB,wBAAwB;YA9oC/B,AAFF,gGAAmB,8EAEV;YA4DT,2HAAsB;;YA9DtB,yCA4DC;;;iFAolCQ,wBAAwB;cArpCpC,SAAS;6BACI,KAAK,YACP,sBAAsB,mBACf,uBAAuB,CAAC,MAAM,YACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8cT;;kBAutBA,KAAK;;kFApBK,wBAAwB","sourcesContent":["import {\n Component,\n OnInit,\n OnDestroy,\n ChangeDetectorRef,\n ChangeDetectionStrategy,\n ViewContainerRef,\n Input\n} from '@angular/core';\nimport { ViewToggleOption, MJLeftNavItem, MJLeftNavSection, FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport { Subject, BehaviorSubject, combineLatest } from 'rxjs';\nimport { takeUntil, debounceTime } from 'rxjs/operators';\nimport { RunView, CompositeKey } from '@memberjunction/core';\nimport { MJTestEntity, MJTestSuiteEntity, MJTestSuiteTestEntity, MJTestTypeEntity, UserInfoEngine } from '@memberjunction/core-entities';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { TestingDialogService } from '@memberjunction/ng-testing';\nimport { TestEngineBase } from '@memberjunction/testing-engine-base';\nimport { TestingInstrumentationService } from '../services/testing-instrumentation.service';\nimport { CountByUUID, IndexByUUID, UUIDsEqual } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\n// ---------------------------------------------------------------------------\n// Interfaces\n// ---------------------------------------------------------------------------\n\ninterface SuiteCardData {\n ID: string;\n Name: string;\n Description: string;\n Status: string;\n TestCount: number;\n PassRate: number;\n AvgScore: number;\n AvgDuration: number; // ms\n LastRunDate: Date | null;\n Tags: string[];\n Tests: SuiteTestItem[]; // first 4-5 for preview\n TotalTestsInSuite: number;\n}\n\ninterface SuiteTestItem {\n TestID: string;\n TestName: string;\n LastStatus: string;\n LastScore: number;\n}\n\ninterface TestCardData {\n ID: string;\n Name: string;\n Description: string;\n Status: string;\n TypeName: string;\n SuiteName: string;\n LastRunStatus: string;\n LastScore: number;\n TotalRuns: number;\n PassRate: number;\n EstDuration: number; // seconds\n EstCost: number;\n LastRunDate: Date | null;\n Tags: string[];\n UpdatedAt: Date;\n}\n\ninterface SidebarSelection {\n Type: 'all' | 'standalone' | 'suite' | 'testType';\n ID: string | null;\n}\n\ninterface SuiteTreeNode {\n ID: string;\n Name: string;\n ParentID: string | null;\n TestCount: number;\n Children: SuiteTreeNode[];\n Expanded: boolean;\n}\n\ntype DisplayMode = 'all' | 'suites' | 'tests';\ntype ViewMode = 'card' | 'list';\ntype SortField = 'name' | 'updated' | 'status';\ntype SortDirection = 'asc' | 'desc';\n\n/** Simple result type for test run stats queries */\ninterface TestRunStatRow {\n ID: string;\n TestID: string;\n Status: string;\n Score: number;\n CostUSD: number;\n StartedAt: string | Date;\n CompletedAt: string | Date | null;\n}\n\n@Component({\n standalone: false,\n selector: 'app-testing-explorer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (HideToolbar) {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n } @else {\n <mj-page-layout>\n <mj-page-header\n Title=\"Test Explorer\"\n Icon=\"fa-solid fa-compass\"\n Subtitle=\"Browse tests and test suites\">\n <!-- X-of-Y filtered count earns its meta spot per chrome conventions §2.\n TotalItemCount and FilteredResultCount are both kept in sync by\n the component as the rail selection / status chips / search input\n narrow the data. -->\n <div meta>\n <mj-stat-badge\n [Count]=\"FilteredResultCount\"\n [Total]=\"TotalItemCount\"\n Label=\"results\">\n </mj-stat-badge>\n </div>\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"OnNewSuite()\">\n <i class=\"fa-solid fa-folder-plus\"></i> <span class=\"action-btn-label\">New Suite</span>\n </button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewTest()\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"action-btn-label\">New Test</span>\n </button>\n </div>\n <div toolbar>\n <!-- Concise-chrome control bar: search · Filter · view, together.\n Search is persistent wayfinding (never a filter field); all\n filters live behind the one Filter button (docks as a bottom\n sheet on mobile); applied filters render as removable chips\n below the bar (see <mj-applied-filters>). -->\n <mj-page-search\n Placeholder=\"Search tests and suites...\"\n [Value]=\"SearchTerm\"\n (ValueChange)=\"OnSearchInputValue($event)\">\n </mj-page-search>\n <mj-filter-popover\n Label=\"Filters\"\n Icon=\"fa-solid fa-filter\"\n [ActiveCount]=\"TotalActiveFilterCount\"\n [ShowClearAll]=\"TotalActiveFilterCount > 0\"\n (ClearAllRequested)=\"resetAllFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterValuesChange($event)\"\n (Reset)=\"resetAllFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n <mj-view-toggle\n [Options]=\"HeaderViewOptions\"\n [ActiveKey]=\"ViewMode\"\n (KeyChange)=\"SetViewMode($any($event))\">\n </mj-view-toggle>\n </div>\n </mj-page-header>\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </mj-page-layout>\n }\n\n <ng-template #content>\n <!-- Shared chrome primitives instead of bespoke wrappers: mj-page-body\n (row) is the rail+content layout, mj-page-body-interior is the\n scroller. Both reflow / scroll correctly on mobile. -->\n <mj-page-body [Flex]=\"true\" [Padding]=\"false\" Direction=\"row\">\n @if (IsLoading) {\n <div class=\"explorer-loading\">\n <mj-loading text=\"Loading test explorer...\"></mj-loading>\n </div>\n } @else {\n <mj-left-nav\n MobileTitle=\"Browse Tests\"\n [Sections]=\"NavSections\"\n [ActiveId]=\"ActiveNavId\"\n [ExpandedIds]=\"ExpandedNavIds\"\n [Collapsible]=\"true\"\n [Collapsed]=\"RailCollapsed\"\n (CollapsedChange)=\"OnRailCollapsedChange($event)\"\n (ItemClicked)=\"OnNavItemClicked($event)\"\n (ItemToggled)=\"OnNavItemToggled($event)\">\n </mj-left-nav>\n\n <mj-left-nav-content>\n <mj-page-body-interior>\n <!-- Suites Section -->\n @if (DisplayMode === 'all' || DisplayMode === 'suites') {\n @if (FilteredSuites.length > 0) {\n <div class=\"content-section\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-folder\"></i>\n Test Suites\n <span class=\"section-count\">{{ FilteredSuites.length }}</span>\n </h3>\n <div class=\"card-grid\">\n @for (suite of FilteredSuites; track suite.ID) {\n <div class=\"suite-card\">\n <div class=\"card-header\">\n <div class=\"card-title-row\">\n <i class=\"fa-solid fa-folder-open card-icon suite-icon\"></i>\n <span class=\"card-name\" [innerHTML]=\"suite.Name | highlightSearch:SearchTerm\"></span>\n <span class=\"status-badge\" [attr.data-status]=\"suite.Status.toLowerCase()\">{{ suite.Status }}</span>\n </div>\n <div class=\"card-subtitle\">\n {{ suite.TestCount }} tests\n @if (suite.LastRunDate) {\n <span class=\"dot-sep\"></span>\n Last run {{ FormatRelativeTime(suite.LastRunDate) }}\n }\n </div>\n @if (suite.Description) {\n <p class=\"card-description\" [innerHTML]=\"suite.Description | highlightSearch:SearchTerm\"></p>\n }\n </div>\n\n <div class=\"card-stats\">\n <div class=\"stat\">\n <span class=\"stat-label\">Pass Rate</span>\n <span class=\"stat-value\" [class]=\"GetScoreClass(suite.PassRate / 100)\">{{ FormatPercent(suite.PassRate) }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Tests</span>\n <span class=\"stat-value\">{{ suite.TestCount }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Avg Score</span>\n <span class=\"stat-value\" [class]=\"GetScoreClass(suite.AvgScore)\">{{ (suite.AvgScore * 100).toFixed(0) }}%</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Avg Duration</span>\n <span class=\"stat-value\">{{ FormatDuration(suite.AvgDuration) }}</span>\n </div>\n </div>\n\n @if (suite.Tests.length > 0) {\n <div class=\"card-tests-preview\">\n @for (t of suite.Tests; track t.TestID; let i = $index) {\n @if (i < 4) {\n <div class=\"preview-test-row\">\n <span class=\"preview-dot\" [attr.data-status]=\"t.LastStatus.toLowerCase()\"></span>\n <span class=\"preview-test-name\">{{ t.TestName }}</span>\n <span class=\"preview-score\" [class]=\"GetScoreClass(t.LastScore)\">{{ (t.LastScore * 100).toFixed(0) }}%</span>\n <span class=\"preview-bar\">\n <span class=\"preview-bar-fill\" [style.width.%]=\"t.LastScore * 100\" [class]=\"GetScoreClass(t.LastScore) + '-bg'\"></span>\n </span>\n <span class=\"preview-status\" [attr.data-status]=\"t.LastStatus.toLowerCase()\">{{ t.LastStatus }}</span>\n </div>\n }\n }\n @if (suite.TotalTestsInSuite > 4) {\n <div class=\"preview-more\">+{{ suite.TotalTestsInSuite - 4 }} more tests</div>\n }\n </div>\n }\n\n <div class=\"card-actions\">\n <button class=\"btn btn-sm btn-primary\" (click)=\"RunSuite(suite.ID)\">\n <i class=\"fa-solid fa-play\"></i> Run Suite\n </button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"ViewSuiteResults(suite.ID)\">\n <i class=\"fa-solid fa-chart-bar\"></i> Results\n </button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"EditItem('MJ: Test Suites', suite.ID)\">\n <i class=\"fa-solid fa-pen\"></i> Edit\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n }\n }\n\n <!-- Tests Section -->\n @if (DisplayMode === 'all' || DisplayMode === 'tests') {\n @if (FilteredTests.length > 0) {\n <div class=\"content-section\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-vial\"></i>\n Tests\n <span class=\"section-count\">{{ FilteredTests.length }}</span>\n </h3>\n <div class=\"card-grid\">\n @for (test of FilteredTests; track test.ID) {\n <div class=\"test-card\">\n <div class=\"card-header\">\n <div class=\"card-title-row\">\n <i class=\"fa-solid fa-vial card-icon test-icon\"></i>\n <span class=\"card-name\" [innerHTML]=\"test.Name | highlightSearch:SearchTerm\"></span>\n <span class=\"status-badge\" [attr.data-status]=\"test.Status.toLowerCase()\">{{ test.Status }}</span>\n </div>\n <div class=\"card-subtitle\">\n {{ test.TypeName }}\n @if (test.SuiteName) {\n <span class=\"dot-sep\"></span>\n {{ test.SuiteName }}\n }\n </div>\n @if (test.Description) {\n <p class=\"card-description\" [innerHTML]=\"test.Description | highlightSearch:SearchTerm\"></p>\n }\n <div class=\"card-meta-row\">\n @if (test.TypeName) {\n <span class=\"meta-item\"><i class=\"fa-solid fa-robot\"></i> {{ test.TypeName }}</span>\n }\n @if (test.EstDuration > 0) {\n <span class=\"meta-item\"><i class=\"fa-solid fa-clock\"></i> ~{{ FormatDurationSeconds(test.EstDuration) }}</span>\n }\n @if (test.EstCost > 0) {\n <span class=\"meta-item\"><i class=\"fa-solid fa-dollar-sign\"></i> {{ FormatCost(test.EstCost) }}</span>\n }\n <span class=\"meta-item\"><i class=\"fa-solid fa-calendar\"></i> {{ FormatRelativeTime(test.UpdatedAt) }}</span>\n </div>\n @if (test.Tags.length > 0) {\n <div class=\"card-tags\">\n @for (tag of test.Tags; track tag; let i = $index) {\n @if (i < 4) {\n <span class=\"tag\">{{ tag }}</span>\n }\n }\n @if (test.Tags.length > 4) {\n <span class=\"tag tag-more\">+{{ test.Tags.length - 4 }}</span>\n }\n </div>\n }\n </div>\n\n <div class=\"card-stats\">\n <div class=\"stat\">\n <span class=\"stat-label\">Last Status</span>\n <span class=\"stat-value status-text\" [attr.data-status]=\"test.LastRunStatus.toLowerCase()\">{{ test.LastRunStatus || 'N/A' }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Score</span>\n <span class=\"stat-value\" [class]=\"GetScoreClass(test.LastScore)\">{{ test.LastScore > 0 ? (test.LastScore * 100).toFixed(0) + '%' : 'N/A' }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Total Runs</span>\n <span class=\"stat-value\">{{ test.TotalRuns }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-label\">Pass Rate</span>\n <span class=\"stat-value\" [class]=\"GetScoreClass(test.PassRate / 100)\">{{ test.TotalRuns > 0 ? FormatPercent(test.PassRate) : 'N/A' }}</span>\n </div>\n </div>\n\n <div class=\"card-actions\">\n <button class=\"btn btn-sm btn-primary\" (click)=\"RunTest(test.ID)\">\n <i class=\"fa-solid fa-play\"></i> Run\n </button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"ViewTestHistory(test.ID)\">\n <i class=\"fa-solid fa-history\"></i> History\n </button>\n <button class=\"btn btn-sm btn-secondary\" (click)=\"EditItem('MJ: Tests', test.ID)\">\n <i class=\"fa-solid fa-pen\"></i> Edit\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n }\n }\n\n <!-- Empty State -->\n @if (FilteredSuites.length === 0 && FilteredTests.length === 0) {\n <mj-empty-state Variant=\"no-results\" Icon=\"fa-solid fa-inbox\"\n Title=\"No tests or suites found\"\n Message=\"Try adjusting your search or filters.\" />\n }\n </mj-page-body-interior>\n </mj-left-nav-content>\n }\n\n <!-- Slideout Backdrop -->\n @if (SlideoutOpen) {\n <div class=\"slideout-backdrop\" (click)=\"CloseSlideout()\"></div>\n }\n\n <!-- Slideout Panel -->\n <div class=\"slideout-panel\" [class.open]=\"SlideoutOpen\" [style.width.px]=\"SlideoutWidth\">\n <div class=\"slideout-resize-handle\" (mousedown)=\"OnResizeStart($event)\"></div>\n\n @if (SlideoutOpen) {\n <div class=\"slideout-container\">\n <!-- Slideout Header -->\n <div class=\"slideout-header\">\n <div class=\"slideout-title-row\">\n <i class=\"fa-solid fa-plus-circle slideout-title-icon\"></i>\n <span class=\"slideout-title-text\">\n Create {{ SlideoutCreateType === 'test' ? 'Test' : 'Test Suite' }}\n </span>\n </div>\n <button class=\"slideout-close-btn\" (click)=\"CloseSlideout()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <!-- Type Toggle -->\n <div class=\"slideout-type-toggle\">\n <button\n class=\"type-toggle-btn\"\n [class.active]=\"SlideoutCreateType === 'test'\"\n (click)=\"SetSlideoutCreateType('test')\"\n >\n <i class=\"fa-solid fa-vial\"></i> Test\n </button>\n <button\n class=\"type-toggle-btn\"\n [class.active]=\"SlideoutCreateType === 'suite'\"\n (click)=\"SetSlideoutCreateType('suite')\"\n >\n <i class=\"fa-solid fa-folder\"></i> Suite\n </button>\n </div>\n\n <!-- Error Banner -->\n @if (FormErrorMessage) {\n <div class=\"slideout-error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n <span>{{ FormErrorMessage }}</span>\n </div>\n }\n\n <!-- Slideout Body -->\n <div class=\"slideout-body\">\n <div class=\"form-section\">\n <div class=\"form-section-title\">General</div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Name <span class=\"form-required\">*</span></label>\n <input\n class=\"form-input\"\n type=\"text\"\n [(ngModel)]=\"FormName\"\n [placeholder]=\"SlideoutCreateType === 'test' ? 'e.g., Agent Response Quality Test' : 'e.g., Core Agent Test Suite'\"\n />\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Description</label>\n <textarea\n class=\"form-textarea\"\n [(ngModel)]=\"FormDescription\"\n rows=\"3\"\n [placeholder]=\"SlideoutCreateType === 'test' ? 'What does this test evaluate?' : 'What does this suite contain?'\"\n ></textarea>\n </div>\n\n <div class=\"form-row\">\n @if (SlideoutCreateType === 'test') {\n <div class=\"form-group\">\n <label class=\"form-label\">Test Type <span class=\"form-required\">*</span></label>\n <select class=\"form-input\" [(ngModel)]=\"FormTypeID\">\n <option value=\"\" disabled>Select type...</option>\n @for (tt of AllTestTypes; track tt.ID) {\n <option [value]=\"tt.ID\">{{ tt.Name }}</option>\n }\n </select>\n </div>\n }\n @if (SlideoutCreateType === 'suite') {\n <div class=\"form-group\">\n <label class=\"form-label\">Parent Suite</label>\n <select class=\"form-input\" [(ngModel)]=\"FormParentSuiteID\">\n <option value=\"\">None (top-level)</option>\n @for (s of AllSuites; track s.ID) {\n <option [value]=\"s.ID\">{{ s.Name }}</option>\n }\n </select>\n </div>\n }\n <div class=\"form-group\">\n <label class=\"form-label\">Status</label>\n <select class=\"form-input\" [(ngModel)]=\"FormStatus\">\n @for (status of FormStatusOptions; track status) {\n <option [value]=\"status\">{{ status }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n\n @if (SlideoutCreateType === 'test') {\n <div class=\"form-section\">\n <div class=\"form-section-title\">Estimates</div>\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label class=\"form-label\">Duration (seconds)</label>\n <input\n class=\"form-input\"\n type=\"number\"\n [(ngModel)]=\"FormEstDuration\"\n min=\"0\"\n placeholder=\"0\"\n />\n </div>\n <div class=\"form-group\">\n <label class=\"form-label\">Cost (USD)</label>\n <input\n class=\"form-input\"\n type=\"number\"\n [(ngModel)]=\"FormEstCost\"\n min=\"0\"\n step=\"0.01\"\n placeholder=\"0.00\"\n />\n </div>\n </div>\n </div>\n }\n\n <div class=\"form-section\">\n <div class=\"form-section-title\">Tags</div>\n <div class=\"form-group\">\n <input\n class=\"form-input\"\n type=\"text\"\n [(ngModel)]=\"FormTags\"\n placeholder=\"Comma-separated tags, e.g., agent, quality, v2\"\n />\n <span class=\"form-hint\">Separate multiple tags with commas</span>\n </div>\n </div>\n </div>\n\n <!-- Slideout Footer -->\n <div class=\"slideout-footer\">\n <button class=\"btn btn-secondary\" (click)=\"CloseSlideout()\">Cancel</button>\n <button class=\"btn btn-primary\" (click)=\"SaveForm()\" [disabled]=\"!IsFormValid || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-check\"></i>\n }\n Create {{ SlideoutCreateType === 'test' ? 'Test' : 'Suite' }}\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Slide Panel for Test Execution -->\n @if (testingDialogService.IsPanelOpen) {\n <mj-slide-panel\n Mode=\"slide\"\n Title=\"Run Test\"\n [Resizable]=\"true\"\n (Closed)=\"OnPanelClosed()\">\n <app-test-run-dialog\n [PanelMode]=\"true\"\n [selectedTestId]=\"testingDialogService.PanelOptions?.testId ?? null\"\n [selectedSuiteId]=\"testingDialogService.PanelOptions?.suiteId ?? null\"\n [runMode]=\"testingDialogService.PanelOptions?.mode ?? 'test'\"\n (PanelClose)=\"OnPanelClosed()\">\n </app-test-run-dialog>\n </mj-slide-panel>\n }\n </mj-page-body>\n </ng-template>\n `,\n styles: [`\n /* ==========================================\n Testing Explorer Component\n ========================================== */\n\n :host {\n display: block;\n height: 100%;\n width: 100%;\n }\n\n /* Loading */\n .explorer-loading {\n flex: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface-sunken);\n }\n\n /* The rail + content layout is the shared <mj-page-body Direction=\"row\">\n (it reflows to a column on mobile) and the scroller is the shared\n <mj-page-body-interior> — no bespoke .explorer-layout / .content-area. */\n\n /* Mobile search-grow + icon-only action buttons are handled by the shared\n <mj-page-header> rules (action-btn-label + toolbar search-grow). */\n\n /* ==========================================\n Main Content\n — left rail + content pane handled by <mj-left-nav> + <mj-left-nav-content>\n ========================================== */\n\n /* Buttons */\n .btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 9px 16px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n }\n\n .btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n }\n\n .btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n }\n\n .btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n border: 1px solid var(--mj-border-default);\n }\n\n .btn-secondary:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .btn-sm {\n padding: 6px 12px;\n font-size: 12px;\n }\n\n .content-section {\n margin-bottom: 32px;\n }\n\n .section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .section-title i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n }\n\n .section-count {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 10px;\n }\n\n /* Card Grid */\n .card-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));\n gap: 16px;\n }\n\n /* Suite Card */\n .suite-card,\n .test-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n transition: all 0.2s ease;\n }\n\n .suite-card:hover,\n .test-card:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-md);\n }\n\n .card-header {\n padding: 16px 16px 12px;\n }\n\n .card-title-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n }\n\n .card-icon {\n font-size: 14px;\n flex-shrink: 0;\n }\n\n .suite-icon {\n color: var(--mj-brand-primary);\n }\n\n .test-icon {\n color: var(--mj-brand-primary);\n }\n\n .card-name {\n flex: 1;\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .status-badge {\n font-size: 10px;\n font-weight: 700;\n padding: 3px 8px;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n flex-shrink: 0;\n }\n\n .status-badge[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n\n .status-badge[data-status=\"pending\"] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n\n .status-badge[data-status=\"disabled\"] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n .card-subtitle {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n }\n\n .dot-sep {\n display: inline-block;\n width: 3px;\n height: 3px;\n background: var(--mj-text-disabled);\n border-radius: 50%;\n vertical-align: middle;\n margin: 0 6px;\n }\n\n .card-description {\n margin: 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .card-meta-row {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n margin-top: 8px;\n }\n\n .meta-item {\n font-size: 11px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .meta-item i {\n font-size: 10px;\n color: var(--mj-text-disabled);\n }\n\n .card-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-top: 8px;\n }\n\n .tag {\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n border-radius: 4px;\n }\n\n .tag-more {\n background: var(--mj-border-default);\n color: var(--mj-text-disabled);\n }\n\n /* Card Stats */\n .card-stats {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 1px;\n background: var(--mj-border-default);\n border-top: 1px solid var(--mj-border-default);\n }\n\n .stat {\n background: var(--mj-bg-surface-card);\n padding: 10px 12px;\n text-align: center;\n }\n\n .stat-label {\n display: block;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 2px;\n }\n\n .stat-value {\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .stat-value.good { color: var(--mj-status-success); }\n .stat-value.warn { color: var(--mj-status-warning); }\n .stat-value.bad { color: var(--mj-status-error); }\n\n .status-text[data-status=\"passed\"] { color: var(--mj-status-success); }\n .status-text[data-status=\"failed\"] { color: var(--mj-status-error); }\n .status-text[data-status=\"error\"] { color: var(--mj-status-warning); }\n .status-text[data-status=\"running\"] { color: var(--mj-brand-primary); }\n .status-text[data-status=\"pending\"] { color: var(--mj-status-warning); }\n .status-text[data-status=\"skipped\"] { color: var(--mj-text-muted); }\n\n /* Suite Tests Preview */\n .card-tests-preview {\n padding: 10px 16px;\n border-top: 1px solid var(--mj-border-default);\n }\n\n .preview-test-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n font-size: 12px;\n }\n\n .preview-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .preview-dot[data-status=\"passed\"] { background: var(--mj-status-success); }\n .preview-dot[data-status=\"failed\"] { background: var(--mj-status-error); }\n .preview-dot[data-status=\"error\"] { background: var(--mj-status-warning); }\n .preview-dot[data-status=\"running\"] { background: var(--mj-brand-primary); }\n .preview-dot[data-status=\"\"] { background: var(--mj-text-disabled); }\n\n .preview-test-name {\n flex: 1;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .preview-score {\n font-weight: 600;\n font-size: 11px;\n min-width: 32px;\n text-align: right;\n }\n\n .preview-score.good { color: var(--mj-status-success); }\n .preview-score.warn { color: var(--mj-status-warning); }\n .preview-score.bad { color: var(--mj-status-error); }\n\n .preview-bar {\n width: 48px;\n height: 4px;\n background: var(--mj-border-default);\n border-radius: 2px;\n overflow: hidden;\n flex-shrink: 0;\n }\n\n .preview-bar-fill {\n height: 100%;\n border-radius: 2px;\n transition: width 0.3s ease;\n }\n\n .good-bg { background: var(--mj-status-success); }\n .warn-bg { background: var(--mj-status-warning); }\n .bad-bg { background: var(--mj-status-error); }\n\n .preview-status {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n min-width: 44px;\n text-align: right;\n }\n\n .preview-status[data-status=\"passed\"] { color: var(--mj-status-success); }\n .preview-status[data-status=\"failed\"] { color: var(--mj-status-error); }\n .preview-status[data-status=\"error\"] { color: var(--mj-status-warning); }\n .preview-status[data-status=\"\"] { color: var(--mj-text-disabled); }\n\n .preview-more {\n padding: 4px 0 0;\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-style: italic;\n }\n\n /* Card Actions */\n .card-actions {\n display: flex;\n gap: 8px;\n padding: 12px 16px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n }\n\n /* ==========================================\n Slideout Panel\n ========================================== */\n .slideout-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n animation: fadeInBackdrop 0.2s ease;\n }\n\n @keyframes fadeInBackdrop {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n .slideout-panel {\n position: fixed;\n top: 0;\n right: -100%;\n height: 100vh;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .slideout-panel.open {\n right: 0;\n }\n\n .slideout-resize-handle {\n position: absolute;\n top: 0;\n left: 0;\n width: 5px;\n height: 100%;\n cursor: col-resize;\n background: transparent;\n z-index: 10;\n transition: background 0.2s;\n }\n\n .slideout-resize-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n\n .slideout-resize-handle:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n }\n\n .slideout-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n }\n\n .slideout-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n .slideout-title-row {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .slideout-title-icon {\n font-size: 18px;\n color: var(--mj-brand-primary);\n }\n\n .slideout-title-text {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .slideout-close-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 14px;\n transition: all 0.15s ease;\n }\n\n .slideout-close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n }\n\n /* Type Toggle */\n .slideout-type-toggle {\n display: flex;\n gap: 0;\n padding: 16px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n .type-toggle-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .type-toggle-btn:first-child {\n border-radius: 8px 0 0 8px;\n border-right: none;\n }\n\n .type-toggle-btn:last-child {\n border-radius: 0 8px 8px 0;\n }\n\n .type-toggle-btn.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n }\n\n .type-toggle-btn:hover:not(.active) {\n background: var(--mj-border-default);\n }\n\n /* Error Banner */\n .slideout-error {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 16px 24px 0;\n padding: 12px 16px;\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface));\n border-radius: 8px;\n color: var(--mj-status-error);\n font-size: 13px;\n flex-shrink: 0;\n }\n\n .slideout-error i {\n font-size: 14px;\n flex-shrink: 0;\n }\n\n /* Slideout Body */\n .slideout-body {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n }\n\n .form-section {\n margin-bottom: 24px;\n }\n\n .form-section-title {\n font-size: 12px;\n font-weight: 700;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.8px;\n margin-bottom: 14px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .form-group {\n margin-bottom: 16px;\n }\n\n .form-label {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 6px;\n }\n\n .form-required {\n color: var(--mj-status-error);\n }\n\n .form-input,\n .form-textarea {\n width: 100%;\n padding: 10px 14px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-text-primary);\n transition: border-color 0.2s ease;\n outline: none;\n box-sizing: border-box;\n font-family: inherit;\n }\n\n .form-input:focus,\n .form-textarea:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n .form-input::placeholder,\n .form-textarea::placeholder {\n color: var(--mj-text-disabled);\n }\n\n .form-textarea {\n resize: vertical;\n min-height: 80px;\n }\n\n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n }\n\n .form-hint {\n display: block;\n font-size: 11px;\n color: var(--mj-text-disabled);\n margin-top: 4px;\n }\n\n /* Slideout Footer */\n .slideout-footer {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding: 16px 24px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n }\n\n .slideout-footer .btn {\n min-width: 100px;\n justify-content: center;\n }\n\n .slideout-footer .btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n box-shadow: none;\n }\n\n /* Search Highlight */\n ::ng-deep mark.search-highlight {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n color: inherit;\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: 700;\n }\n\n /* ==========================================\n Responsive\n ========================================== */\n @media (max-width: 1200px) {\n .card-grid {\n grid-template-columns: 1fr;\n }\n }\n\n @media (max-width: 600px) {\n .card-stats {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .slideout-panel {\n width: 100% !important;\n }\n\n .slideout-resize-handle {\n display: none;\n }\n\n .form-row {\n grid-template-columns: 1fr;\n }\n }\n `]\n})\nexport class TestingExplorerComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n\n public readonly HeaderViewOptions: ViewToggleOption[] = [\n { key: 'card', icon: 'fa-solid fa-grip', title: 'Card view' },\n { key: 'list', icon: 'fa-solid fa-list', title: 'List view' }\n ];\n\n public readonly DisplayModeOptions: ViewToggleOption[] = [\n { key: 'all', label: 'All' },\n { key: 'suites', label: 'Suites' },\n { key: 'tests', label: 'Tests' }\n ];\n\n /** mj-page-search emits a string; bridge it to the inner's Event-based OnSearchInput. */\n public OnSearchInputValue(value: string): void {\n const fakeEvent = { target: { value } } as unknown as Event;\n this.OnSearchInput(fakeEvent);\n }\n\n /** When true, the inner bespoke .toolbar is hidden — the parent shell owns the chrome. */\n @Input() HideToolbar = false;\n\n private destroy$ = new Subject<void>();\n\n // Raw cached data\n private allTests: MJTestEntity[] = [];\n AllSuites: MJTestSuiteEntity[] = [];\n private allSuiteTests: MJTestSuiteTestEntity[] = [];\n AllTestTypes: MJTestTypeEntity[] = [];\n private testRunStats: TestRunStatRow[] = [];\n\n // Computed card data\n private suiteCards: SuiteCardData[] = [];\n private testCards: TestCardData[] = [];\n\n // State subjects\n private _searchTerm$ = new BehaviorSubject<string>('');\n private _statusFilters$ = new BehaviorSubject<Set<string>>(new Set());\n private _viewMode$ = new BehaviorSubject<ViewMode>('card');\n private _displayMode$ = new BehaviorSubject<DisplayMode>('all');\n private _selectedSidebar$ = new BehaviorSubject<SidebarSelection>({ Type: 'all', ID: null });\n private _sortField$ = new BehaviorSubject<SortField>('name');\n private _sortDirection$ = new BehaviorSubject<SortDirection>('asc');\n\n // Template-bound state\n IsLoading = true;\n SearchTerm = '';\n StatusFilters = new Set<string>();\n ViewMode: ViewMode = 'card';\n DisplayMode: DisplayMode = 'all';\n SelectedSidebar: SidebarSelection = { Type: 'all', ID: null };\n SortField: SortField = 'name';\n SortDirection: SortDirection = 'asc';\n\n // Filtered results\n FilteredSuites: SuiteCardData[] = [];\n FilteredTests: TestCardData[] = [];\n FilteredSuiteTree: SuiteTreeNode[] = [];\n FilteredTestTypes: MJTestTypeEntity[] = [];\n\n // Counts\n TotalItemCount = 0;\n StandaloneTestCount = 0;\n FilteredResultCount = 0;\n\n readonly StatusOptions: string[] = ['Active', 'Pending', 'Disabled'];\n readonly FormStatusOptions: string[] = ['Active', 'Pending', 'Disabled'];\n\n // Settings keys\n private static readonly PANEL_WIDTH_KEY = 'Testing.ExplorerPanelWidth';\n private static readonly SEARCH_STATE_KEY = 'Testing.ExplorerSearchState';\n private static readonly RAIL_COLLAPSED_KEY = 'Testing.ExplorerRailCollapsed';\n\n /**\n * Whether the browse rail is collapsed to icons. `<mj-left-nav>` owns the presentation; we own\n * the state, same split as `ExpandedIds` — so it survives a reload and follows the user across\n * devices via `UserInfoEngine` rather than dying in one browser's localStorage.\n */\n RailCollapsed = false;\n private settingsPersistSubject = new Subject<void>();\n private settingsLoaded = false;\n\n // Slideout state\n SlideoutOpen = false;\n SlideoutCreateType: 'test' | 'suite' = 'test';\n SlideoutWidth = 560;\n IsSaving = false;\n FormErrorMessage = '';\n\n // Resize state\n private resizeStartX = 0;\n private resizeStartWidth = 0;\n\n // Form fields\n FormName = '';\n FormDescription = '';\n FormTypeID = '';\n FormStatus: 'Active' | 'Pending' | 'Disabled' = 'Active';\n FormParentSuiteID = '';\n FormEstDuration = 0;\n FormEstCost = 0;\n FormTags = '';\n\n get IsFormValid(): boolean {\n if (!this.FormName.trim()) return false;\n if (this.SlideoutCreateType === 'test' && !this.FormTypeID) return false;\n return true;\n }\n\n constructor(\n private cdr: ChangeDetectorRef,\n private viewContainerRef: ViewContainerRef,\n public TestingDialogService: TestingDialogService,\n public InstrumentationService: TestingInstrumentationService\n ) { super(); }\n\n /** @deprecated Use {@link TestingDialogService}. */\n public get testingDialogService(): TestingDialogService {\n return this.TestingDialogService;\n }\n /** @deprecated Use {@link TestingDialogService}. */\n public set testingDialogService(value: TestingDialogService) {\n this.TestingDialogService = value;\n }\n\n /** @deprecated Use {@link InstrumentationService}. */\n public get instrumentationService(): TestingInstrumentationService {\n return this.InstrumentationService;\n }\n /** @deprecated Use {@link InstrumentationService}. */\n public set instrumentationService(value: TestingInstrumentationService) {\n this.InstrumentationService = value;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n async ngOnInit(): Promise<void> {\n this.loadUserSettings();\n this.setupSettingsPersistence();\n this.IsLoading = true;\n this.cdr.markForCheck();\n\n try {\n await TestEngineBase.Instance.Config(false);\n await this.LoadData();\n } catch (err) {\n console.error('TestingExplorerComponent: Failed to load data', err);\n } finally {\n this.IsLoading = false;\n this.cdr.markForCheck();\n }\n\n this.subscribeToStateChanges();\n\n this.TestingDialogService.PanelStateChanged$.pipe(\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.cdr.detectChanges();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n document.removeEventListener('mousemove', this.onResizeMove);\n document.removeEventListener('mouseup', this.onResizeEnd);\n UserInfoEngine.Instance.FlushPendingSettings();\n }\n\n // ---------------------------------------------------------------------------\n // Public Methods\n // ---------------------------------------------------------------------------\n\n async LoadData(): Promise<void> {\n this.loadCachedMetadata();\n await this.loadTestRunStats();\n this.buildSuiteCards();\n this.buildTestCards();\n this.buildSuiteTree();\n this.computeCounts();\n this.applyFilters();\n }\n\n IsSidebarSelected(id: string): boolean {\n return UUIDsEqual(this.SelectedSidebar.ID, id);\n }\n\n SelectSidebarItem(selection: SidebarSelection): void {\n this._selectedSidebar$.next(selection);\n }\n\n ToggleStatus(status: string): void {\n const current = new Set(this._statusFilters$.value);\n if (current.has(status)) {\n current.delete(status);\n } else {\n current.add(status);\n }\n this._statusFilters$.next(current);\n }\n\n IsStatusActive(status: string): boolean {\n return this.StatusFilters.has(status);\n }\n\n SetDisplayMode(mode: DisplayMode): void {\n this._displayMode$.next(mode);\n }\n\n SetViewMode(mode: ViewMode): void {\n this._viewMode$.next(mode);\n }\n\n OnSearchInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n this._searchTerm$.next(input.value);\n }\n\n ClearSearch(): void {\n this._searchTerm$.next('');\n }\n\n ToggleSuiteExpand(node: SuiteTreeNode): void {\n node.Expanded = !node.Expanded;\n this.cdr.markForCheck();\n }\n\n // ---------------------------------------------------------------------------\n // <mj-left-nav> adapters\n //\n // The rail is one <mj-left-nav> with three logical sections. Internal state\n // still lives on SelectedSidebar (typed Type+ID) and on SuiteTreeNode.Expanded\n // booleans — these getters translate to/from the primitive's flat\n // string-id interface.\n // ---------------------------------------------------------------------------\n\n /** Composite-key sections fed to <mj-left-nav>. */\n get NavSections(): MJLeftNavSection[] {\n const suiteItems = this.FilteredSuiteTree.length === 0\n ? [{ id: '__suites-empty', label: 'No suites found', disabled: true } as MJLeftNavItem]\n : this.FilteredSuiteTree.map(node => this.suiteNodeToNavItem(node));\n\n return [\n {\n label: 'Browse',\n items: [\n { id: 'all', label: 'All Items', icon: 'fa-solid fa-layer-group', badge: this.TotalItemCount },\n { id: 'standalone', label: 'Standalone Tests', icon: 'fa-solid fa-vial', badge: this.StandaloneTestCount },\n ]\n },\n { label: 'Test Suites', items: suiteItems },\n {\n label: 'Test Types',\n items: this.FilteredTestTypes.map(tt => ({\n id: `testType:${tt.ID}`,\n label: tt.Name,\n icon: 'fa-solid fa-tag',\n badge: this.GetTestCountForType(tt.ID)\n }))\n }\n ];\n }\n\n /** Recursive map SuiteTreeNode -> MJLeftNavItem. Leaves keep `children: []`\n * so the primitive renders a placeholder where the chevron would be —\n * this keeps siblings vertically aligned. */\n private suiteNodeToNavItem(node: SuiteTreeNode): MJLeftNavItem {\n return {\n id: `suite:${node.ID}`,\n label: node.Name,\n icon: 'fa-solid fa-folder',\n badge: node.TestCount,\n children: node.Children.map(child => this.suiteNodeToNavItem(child))\n };\n }\n\n /** Translate SelectedSidebar (typed Type+ID) to the rail's composite key. */\n get ActiveNavId(): string {\n const sel = this.SelectedSidebar;\n if (sel.Type === 'suite' || sel.Type === 'testType') {\n return `${sel.Type}:${sel.ID ?? ''}`;\n }\n return sel.Type;\n }\n\n /** Suite-node IDs that are currently expanded, walked from FilteredSuiteTree. */\n get ExpandedNavIds(): string[] {\n const out: string[] = [];\n const walk = (nodes: SuiteTreeNode[]): void => {\n for (const n of nodes) {\n if (n.Expanded) out.push(`suite:${n.ID}`);\n walk(n.Children);\n }\n };\n walk(this.FilteredSuiteTree);\n return out;\n }\n\n /** Parse composite id and delegate to the existing SelectSidebarItem path. */\n OnNavItemClicked(item: MJLeftNavItem): void {\n const id = item.id;\n if (id === 'all') {\n this.SelectSidebarItem({ Type: 'all', ID: null });\n } else if (id === 'standalone') {\n this.SelectSidebarItem({ Type: 'standalone', ID: null });\n } else if (id.startsWith('suite:')) {\n this.SelectSidebarItem({ Type: 'suite', ID: id.substring('suite:'.length) });\n } else if (id.startsWith('testType:')) {\n this.SelectSidebarItem({ Type: 'testType', ID: id.substring('testType:'.length) });\n }\n }\n\n /** Chevron click on a suite item — toggle that node's Expanded flag. */\n OnNavItemToggled(item: MJLeftNavItem): void {\n if (!item.id.startsWith('suite:')) return;\n const suiteId = item.id.substring('suite:'.length);\n const node = this.findSuiteNode(this.FilteredSuiteTree, suiteId);\n if (node) this.ToggleSuiteExpand(node);\n }\n\n private findSuiteNode(tree: SuiteTreeNode[], id: string): SuiteTreeNode | null {\n for (const node of tree) {\n if (UUIDsEqual(node.ID, id)) return node;\n const found = this.findSuiteNode(node.Children, id);\n if (found) return found;\n }\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // Sort filter-popover wiring\n //\n // The chrome surfaces SortField + SortDirection through a <mj-filter-popover>\n // — same pattern AI Analytics → Model Performance uses for its SortBy\n // selection. Was previously a single direction-toggle button in chrome\n // [actions] with no way to change the field from the UI.\n // ---------------------------------------------------------------------------\n\n public readonly SortFieldOptions = [\n { text: 'Name', value: 'name' },\n { text: 'Updated', value: 'updated' },\n { text: 'Status', value: 'status' },\n ];\n\n /** @deprecated Use {@link SortFieldOptions}. */\n public get sortFieldOptions() {\n return this.SortFieldOptions;\n }\n\n public readonly SortDirectionOptions = [\n { text: 'Ascending', value: 'asc' },\n { text: 'Descending', value: 'desc' },\n ];\n\n /** @deprecated Use {@link SortDirectionOptions}. */\n public get sortDirectionOptions() {\n return this.SortDirectionOptions;\n }\n\n /**\n * Concise-chrome model: every filter (View · Status · Sort) lives behind a\n * single \"Filter\" button via this one mj-filter-panel field set. The applied\n * state is surfaced separately as removable chips (see AppliedFilters), so\n * input (the button) and state (the chips) are cleanly separated.\n */\n public get FilterFields(): FilterFieldConfig[] {\n return [\n { key: 'displayMode', type: 'chips', label: 'View', chipOptions: [\n { text: 'All', value: 'all' },\n { text: 'Suites', value: 'suites' },\n { text: 'Tests', value: 'tests' },\n ] },\n { key: 'status', type: 'chips', label: 'Status', multi: true, chipOptions: [\n { text: 'Active', value: 'Active' },\n { text: 'Pending', value: 'Pending' },\n { text: 'Disabled', value: 'Disabled' },\n ] },\n { key: 'SortField', type: 'dropdown', label: 'Sort by',\n icon: 'fa-solid fa-arrow-down-wide-short', options: this.SortFieldOptions },\n { key: 'SortDirection', type: 'dropdown', label: 'Direction',\n icon: 'fa-solid fa-arrow-up-arrow-down', options: this.SortDirectionOptions },\n ];\n }\n\n /** @deprecated Use {@link FilterFields}. */\n public get filterFields(): FilterFieldConfig[] {\n return this.FilterFields;\n }\n\n public get FilterValues(): Record<string, unknown> {\n return {\n displayMode: this.DisplayMode,\n status: Array.from(this.StatusFilters),\n SortField: this.SortField,\n SortDirection: this.SortDirection,\n };\n }\n\n /** @deprecated Use {@link FilterValues}. */\n public get filterValues(): Record<string, unknown> {\n return this.FilterValues;\n }\n\n public OnFilterValuesChange(values: Record<string, unknown>): void {\n if ('displayMode' in values) {\n this._displayMode$.next(values['displayMode'] as DisplayMode);\n }\n if ('status' in values) {\n const arr = Array.isArray(values['status']) ? (values['status'] as string[]) : [];\n this._statusFilters$.next(new Set(arr));\n }\n if ('SortField' in values) {\n this._sortField$.next(values['SortField'] as SortField);\n }\n if ('SortDirection' in values) {\n this._sortDirection$.next(values['SortDirection'] as SortDirection);\n }\n }\n\n /** @deprecated Use {@link OnFilterValuesChange}. */\n public onFilterValuesChange(values: Record<string, unknown>): void {\n return this.OnFilterValuesChange(values);\n }\n\n public ResetSortFilters(): void {\n this._sortField$.next('name');\n this._sortDirection$.next('asc');\n }\n\n /** @deprecated Use {@link ResetSortFilters}. */\n public resetSortFilters(): void {\n return this.ResetSortFilters();\n }\n\n /** Clears every filter (View · Status · Sort) back to defaults. */\n public ResetAllFilters(): void {\n this._displayMode$.next('all');\n this._statusFilters$.next(new Set<string>());\n this.ResetSortFilters();\n }\n\n /** @deprecated Use {@link ResetAllFilters}. */\n public resetAllFilters(): void {\n return this.ResetAllFilters();\n }\n\n /** Active sort changes from defaults — contributes to the filter badge + chips. */\n public get ActiveSortFilterCount(): number {\n let count = 0;\n if (this.SortField !== 'name') count++;\n if (this.SortDirection !== 'asc') count++;\n return count;\n }\n\n /** Total active filters (View + Status + Sort) — drives the Filter button badge. */\n public get TotalActiveFilterCount(): number {\n const displayModeActive = this.DisplayMode !== 'all' ? 1 : 0;\n return this.ActiveSortFilterCount + this.StatusFilters.size + displayModeActive;\n }\n\n\n RunTest(testId: string): void {\n this.TestingDialogService.OpenTestPanel(testId);\n }\n\n RunSuite(suiteId: string): void {\n this.TestingDialogService.OpenSuitePanel(suiteId);\n }\n\n OnPanelClosed(): void {\n this.TestingDialogService.ClosePanel();\n this.cdr.detectChanges();\n }\n\n EditItem(entityName: string, id: string): void {\n SharedService.Instance.OpenEntityRecord(entityName, CompositeKey.FromURLSegment(this.ProviderToUse.EntityByName(entityName), id));\n }\n\n ViewTestHistory(testId: string): void {\n SharedService.Instance.OpenEntityRecord('MJ: Tests', CompositeKey.FromID(testId));\n }\n\n ViewSuiteResults(suiteId: string): void {\n SharedService.Instance.OpenEntityRecord('MJ: Test Suites', CompositeKey.FromID(suiteId));\n }\n\n OnNewTest(): void {\n this.OpenSlideout('test');\n }\n\n OnNewSuite(): void {\n this.OpenSlideout('suite');\n }\n\n OpenSlideout(type: 'test' | 'suite'): void {\n this.SlideoutCreateType = type;\n this.resetForm();\n this.SlideoutOpen = true;\n this.cdr.markForCheck();\n }\n\n CloseSlideout(): void {\n this.SlideoutOpen = false;\n this.FormErrorMessage = '';\n this.cdr.markForCheck();\n }\n\n SetSlideoutCreateType(type: 'test' | 'suite'): void {\n this.SlideoutCreateType = type;\n this.resetForm();\n this.cdr.markForCheck();\n }\n\n async SaveForm(): Promise<void> {\n if (!this.IsFormValid || this.IsSaving) return;\n\n this.IsSaving = true;\n this.FormErrorMessage = '';\n this.cdr.markForCheck();\n\n try {\n if (this.SlideoutCreateType === 'test') {\n await this.saveNewTest();\n } else {\n await this.saveNewSuite();\n }\n this.CloseSlideout();\n await TestEngineBase.Instance.Config(true);\n await this.LoadData();\n this.cdr.markForCheck();\n } catch (err) {\n const message = err instanceof Error ? err.message : 'An error occurred while saving.';\n this.FormErrorMessage = message;\n console.error('TestingExplorerComponent: Save failed', err);\n } finally {\n this.IsSaving = false;\n this.cdr.markForCheck();\n }\n }\n\n // ── Resize ──────────────────────────────────────────\n OnResizeStart(event: MouseEvent): void {\n event.preventDefault();\n this.resizeStartX = event.clientX;\n this.resizeStartWidth = this.SlideoutWidth;\n document.addEventListener('mousemove', this.onResizeMove);\n document.addEventListener('mouseup', this.onResizeEnd);\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n }\n\n private onResizeMove = (event: MouseEvent): void => {\n const delta = this.resizeStartX - event.clientX;\n this.SlideoutWidth = Math.max(400, Math.min(900, this.resizeStartWidth + delta));\n this.cdr.detectChanges();\n };\n\n private onResizeEnd = (): void => {\n document.removeEventListener('mousemove', this.onResizeMove);\n document.removeEventListener('mouseup', this.onResizeEnd);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n UserInfoEngine.Instance.SetSettingDebounced(\n TestingExplorerComponent.PANEL_WIDTH_KEY,\n String(this.SlideoutWidth)\n );\n };\n\n GetTestCountForType(typeId: string): number {\n return this.allTests.filter(t => UUIDsEqual(t.TypeID, typeId)).length\n }\n\n // ---------------------------------------------------------------------------\n // Formatting Helpers\n // ---------------------------------------------------------------------------\n\n FormatDuration(ms: number): string {\n if (ms <= 0) return '0s';\n if (ms < 1000) return `${Math.round(ms)}ms`;\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes > 0) return `${minutes}m ${seconds}s`;\n return `${seconds}s`;\n }\n\n FormatDurationSeconds(seconds: number): string {\n if (seconds <= 0) return '0s';\n const minutes = Math.floor(seconds / 60);\n const secs = seconds % 60;\n if (minutes > 0) return `${minutes}m ${secs}s`;\n return `${secs}s`;\n }\n\n FormatRelativeTime(date: Date | null): string {\n if (!date) return 'Never';\n const d = date instanceof Date ? date : new Date(date);\n const now = Date.now();\n const diffMs = now - d.getTime();\n const diffMinutes = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMinutes < 1) return 'Just now';\n if (diffMinutes < 60) return `${diffMinutes}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 30) return `${diffDays}d ago`;\n return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n }\n\n FormatPercent(value: number): string {\n return `${Math.round(value)}%`;\n }\n\n FormatCost(cost: number): string {\n if (cost < 0.01) return '$0.00';\n return `$${cost.toFixed(2)}`;\n }\n\n GetScoreClass(score: number): string {\n if (score >= 0.7) return 'good';\n if (score >= 0.4) return 'warn';\n return 'bad';\n }\n\n GetStatusClass(status: string): string {\n switch (status.toLowerCase()) {\n case 'passed': return 'status-passed';\n case 'failed': return 'status-failed';\n case 'error': return 'status-error';\n case 'running': return 'status-running';\n default: return 'status-default';\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private: Data Loading\n // ---------------------------------------------------------------------------\n\n private loadCachedMetadata(): void {\n const engine = TestEngineBase.Instance;\n this.allTests = engine.Tests;\n this.AllSuites = engine.TestSuites;\n this.allSuiteTests = engine.TestSuiteTests;\n this.AllTestTypes = engine.TestTypes;\n }\n\n private async loadTestRunStats(): Promise<void> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<TestRunStatRow>({\n EntityName: 'MJ: Test Runs',\n Fields: ['ID', 'TestID', 'Status', 'Score', 'CostUSD', 'StartedAt', 'CompletedAt'],\n OrderBy: 'StartedAt DESC',\n MaxRows: 5000,\n ResultType: 'simple'\n });\n\n this.testRunStats = result.Success ? (result.Results || []) : [];\n }\n\n // ---------------------------------------------------------------------------\n // Private: Build Card Data\n // ---------------------------------------------------------------------------\n\n private buildSuiteCards(): void {\n this.suiteCards = this.AllSuites.map(suite => this.buildSingleSuiteCard(suite));\n }\n\n private buildSingleSuiteCard(suite: MJTestSuiteEntity): SuiteCardData {\n const suiteTestLinks = this.allSuiteTests.filter(st => UUIDsEqual(st.SuiteID, suite.ID));\n const testIds = new Set(suiteTestLinks.map(st => st.TestID));\n const runsForSuite = this.testRunStats.filter(r => testIds.has(r.TestID));\n\n const passedRuns = runsForSuite.filter(r => r.Status === 'Passed');\n const passRate = runsForSuite.length > 0 ? (passedRuns.length / runsForSuite.length) * 100 : 0;\n const avgScore = runsForSuite.length > 0\n ? runsForSuite.reduce((s, r) => s + (r.Score || 0), 0) / runsForSuite.length\n : 0;\n const avgDuration = this.computeAvgDuration(runsForSuite);\n const lastRunDate = this.findLastRunDate(runsForSuite);\n const previewTests = this.buildSuiteTestPreviews(suiteTestLinks);\n\n return {\n ID: suite.ID,\n Name: suite.Name,\n Description: suite.Description || '',\n Status: suite.Status,\n TestCount: testIds.size,\n PassRate: passRate,\n AvgScore: avgScore,\n AvgDuration: avgDuration,\n LastRunDate: lastRunDate,\n Tags: this.parseTags(suite.Tags),\n Tests: previewTests,\n TotalTestsInSuite: testIds.size\n };\n }\n\n private buildSuiteTestPreviews(suiteTestLinks: MJTestSuiteTestEntity[]): SuiteTestItem[] {\n return suiteTestLinks\n .sort((a, b) => a.Sequence - b.Sequence)\n .slice(0, 5)\n .map(st => {\n const test = this.allTests.find(t => UUIDsEqual(t.ID, st.TestID));\n const lastRun = this.findLastRunForTest(st.TestID);\n return {\n TestID: st.TestID,\n TestName: test?.Name || st.Test || 'Unknown',\n LastStatus: lastRun?.Status || '',\n LastScore: lastRun?.Score || 0\n };\n });\n }\n\n private buildTestCards(): void {\n this.testCards = this.allTests.map(test => this.buildSingleTestCard(test));\n }\n\n private buildSingleTestCard(test: MJTestEntity): TestCardData {\n const runsForTest = this.testRunStats.filter(r => UUIDsEqual(r.TestID, test.ID));\n const lastRun = runsForTest.length > 0 ? runsForTest[0] : null; // already sorted DESC\n const passedRuns = runsForTest.filter(r => r.Status === 'Passed');\n const passRate = runsForTest.length > 0 ? (passedRuns.length / runsForTest.length) * 100 : 0;\n\n const typeName = this.AllTestTypes.find(t => UUIDsEqual(t.ID, test.TypeID))?.Name || '';\n const suiteName = this.findSuiteNameForTest(test.ID);\n\n return {\n ID: test.ID,\n Name: test.Name,\n Description: test.Description || '',\n Status: test.Status,\n TypeName: typeName,\n SuiteName: suiteName,\n LastRunStatus: lastRun?.Status || '',\n LastScore: lastRun?.Score || 0,\n TotalRuns: runsForTest.length,\n PassRate: passRate,\n EstDuration: test.EstimatedDurationSeconds || 0,\n EstCost: test.EstimatedCostUSD || 0,\n LastRunDate: lastRun ? this.toDate(lastRun.StartedAt) : null,\n Tags: this.parseTags(test.Tags),\n UpdatedAt: test.__mj_UpdatedAt\n };\n }\n\n // ---------------------------------------------------------------------------\n // Private: Build Suite Tree\n // ---------------------------------------------------------------------------\n\n private buildSuiteTree(): void {\n const filteredSuites = this.AllSuites;\n\n const nodeMap = new Map<string, SuiteTreeNode>();\n const testCountBySuite = CountByUUID(this.allSuiteTests, st => st.SuiteID);\n\n for (const suite of filteredSuites) {\n nodeMap.set(suite.ID, {\n ID: suite.ID,\n Name: suite.Name,\n ParentID: suite.ParentID,\n TestCount: testCountBySuite.Get(suite.ID) ?? 0,\n Children: [],\n Expanded: false\n });\n }\n\n const roots: SuiteTreeNode[] = [];\n nodeMap.forEach(node => {\n if (node.ParentID && nodeMap.has(node.ParentID)) {\n nodeMap.get(node.ParentID)!.Children.push(node);\n } else {\n roots.push(node);\n }\n });\n\n this.FilteredSuiteTree = roots;\n this.filterTestTypes();\n }\n\n private filterTestTypes(): void {\n this.FilteredTestTypes = this.AllTestTypes;\n }\n\n // ---------------------------------------------------------------------------\n // Private: Filtering & Sorting\n // ---------------------------------------------------------------------------\n\n private subscribeToStateChanges(): void {\n combineLatest([\n this._searchTerm$,\n this._statusFilters$,\n this._displayMode$,\n this._selectedSidebar$,\n this._sortField$,\n this._sortDirection$,\n this._viewMode$\n ]).pipe(\n takeUntil(this.destroy$)\n ).subscribe(([searchTerm, statusFilters, displayMode, selectedSidebar, sortField, sortDirection, viewMode]) => {\n this.SearchTerm = searchTerm;\n this.StatusFilters = statusFilters;\n this.DisplayMode = displayMode;\n this.SelectedSidebar = selectedSidebar;\n this.SortField = sortField;\n this.SortDirection = sortDirection;\n this.ViewMode = viewMode;\n this.applyFilters();\n this.settingsPersistSubject.next();\n this.cdr.markForCheck();\n });\n }\n\n private applyFilters(): void {\n this.FilteredSuites = this.filterSuiteCards();\n this.FilteredTests = this.filterTestCards();\n this.FilteredResultCount = this.FilteredSuites.length + this.FilteredTests.length;\n }\n\n private filterSuiteCards(): SuiteCardData[] {\n let result = [...this.suiteCards];\n result = this.applySidebarFilterToSuites(result);\n result = this.applySearchFilterToSuites(result);\n result = this.applyStatusFilterToSuites(result);\n result = this.sortSuiteCards(result);\n return result;\n }\n\n private filterTestCards(): TestCardData[] {\n let result = [...this.testCards];\n result = this.applySidebarFilterToTests(result);\n result = this.applySearchFilterToTests(result);\n result = this.applyStatusFilterToTests(result);\n result = this.sortTestCards(result);\n return result;\n }\n\n private applySidebarFilterToSuites(suites: SuiteCardData[]): SuiteCardData[] {\n const sel = this.SelectedSidebar;\n switch (sel.Type) {\n case 'suite':\n return suites.filter(s => UUIDsEqual(s.ID, sel.ID));\n case 'standalone':\n return []; // standalone = tests only\n case 'testType':\n return []; // test types apply to tests only\n default:\n return suites;\n }\n }\n\n private applySidebarFilterToTests(tests: TestCardData[]): TestCardData[] {\n const sel = this.SelectedSidebar;\n switch (sel.Type) {\n case 'suite': {\n const testIds = new Set(\n this.allSuiteTests.filter(st => UUIDsEqual(st.SuiteID, sel.ID)).map(st => st.TestID)\n );\n return tests.filter(t => testIds.has(t.ID));\n }\n case 'standalone': {\n const testIdsInSuites = new Set(this.allSuiteTests.map(st => st.TestID));\n return tests.filter(t => !testIdsInSuites.has(t.ID));\n }\n case 'testType': {\n const testsByID = IndexByUUID(this.allTests);\n return tests.filter(t => UUIDsEqual(testsByID.Get(t.ID)?.TypeID, sel.ID));\n }\n default:\n return tests;\n }\n }\n\n private applySearchFilterToSuites(suites: SuiteCardData[]): SuiteCardData[] {\n const term = this.SearchTerm.toLowerCase().trim();\n if (!term) return suites;\n return suites.filter(s =>\n s.Name.toLowerCase().includes(term) ||\n s.Description.toLowerCase().includes(term)\n );\n }\n\n private applySearchFilterToTests(tests: TestCardData[]): TestCardData[] {\n const term = this.SearchTerm.toLowerCase().trim();\n if (!term) return tests;\n return tests.filter(t =>\n t.Name.toLowerCase().includes(term) ||\n t.Description.toLowerCase().includes(term)\n );\n }\n\n private applyStatusFilterToSuites(suites: SuiteCardData[]): SuiteCardData[] {\n if (this.StatusFilters.size === 0) return suites;\n return suites.filter(s => this.StatusFilters.has(s.Status));\n }\n\n private applyStatusFilterToTests(tests: TestCardData[]): TestCardData[] {\n if (this.StatusFilters.size === 0) return tests;\n return tests.filter(t => this.StatusFilters.has(t.Status));\n }\n\n private sortSuiteCards(suites: SuiteCardData[]): SuiteCardData[] {\n const dir = this.SortDirection === 'asc' ? 1 : -1;\n return suites.sort((a, b) => this.compareBySortField(a.Name, a.Status, a.LastRunDate, b.Name, b.Status, b.LastRunDate, dir));\n }\n\n private sortTestCards(tests: TestCardData[]): TestCardData[] {\n const dir = this.SortDirection === 'asc' ? 1 : -1;\n return tests.sort((a, b) => this.compareBySortField(a.Name, a.Status, a.UpdatedAt, b.Name, b.Status, b.UpdatedAt, dir));\n }\n\n private compareBySortField(\n aName: string, aStatus: string, aDate: Date | null,\n bName: string, bStatus: string, bDate: Date | null,\n dir: number\n ): number {\n switch (this.SortField) {\n case 'name':\n return aName.localeCompare(bName) * dir;\n case 'status':\n return aStatus.localeCompare(bStatus) * dir;\n case 'updated': {\n const aTime = aDate ? new Date(aDate).getTime() : 0;\n const bTime = bDate ? new Date(bDate).getTime() : 0;\n return (aTime - bTime) * dir;\n }\n default:\n return 0;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private: Helpers\n // ---------------------------------------------------------------------------\n\n private computeCounts(): void {\n const testIdsInSuites = new Set(this.allSuiteTests.map(st => st.TestID));\n this.StandaloneTestCount = this.allTests.filter(t => !testIdsInSuites.has(t.ID)).length;\n this.TotalItemCount = this.allTests.length + this.AllSuites.length;\n }\n\n private computeAvgDuration(runs: TestRunStatRow[]): number {\n const completed = runs.filter(r => r.CompletedAt != null && r.StartedAt != null);\n if (completed.length === 0) return 0;\n\n const totalMs = completed.reduce((sum, r) => {\n const start = this.toDate(r.StartedAt).getTime();\n const end = this.toDate(r.CompletedAt!).getTime();\n return sum + (end - start);\n }, 0);\n\n return totalMs / completed.length;\n }\n\n private findLastRunDate(runs: TestRunStatRow[]): Date | null {\n if (runs.length === 0) return null;\n return this.toDate(runs[0].StartedAt);\n }\n\n private findLastRunForTest(testId: string): TestRunStatRow | null {\n return this.testRunStats.find(r => UUIDsEqual(r.TestID, testId)) || null;\n }\n\n private findSuiteNameForTest(testId: string): string {\n const suiteTest = this.allSuiteTests.find(st => UUIDsEqual(st.TestID, testId));\n if (!suiteTest) return '';\n const suite = this.AllSuites.find(s => UUIDsEqual(s.ID, suiteTest.SuiteID));\n return suite?.Name || suiteTest.Suite || '';\n }\n\n private parseTags(tagsJson: string | null): string[] {\n if (!tagsJson) return [];\n try {\n const parsed = JSON.parse(tagsJson);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n }\n\n private toDate(value: string | Date | null): Date {\n if (!value) return new Date(0);\n return value instanceof Date ? value : new Date(value);\n }\n\n // ---------------------------------------------------------------------------\n // Private: User Settings\n // ---------------------------------------------------------------------------\n\n private loadUserSettings(): void {\n try {\n const widthStr = UserInfoEngine.Instance.GetSetting(TestingExplorerComponent.PANEL_WIDTH_KEY);\n if (widthStr) {\n const width = parseInt(widthStr, 10);\n if (!isNaN(width) && width >= 400 && width <= 900) {\n this.SlideoutWidth = width;\n }\n }\n const stateStr = UserInfoEngine.Instance.GetSetting(TestingExplorerComponent.SEARCH_STATE_KEY);\n if (stateStr) {\n const state = JSON.parse(stateStr) as Record<string, string>;\n if (state.searchTerm) {\n this.SearchTerm = state.searchTerm;\n this._searchTerm$.next(state.searchTerm);\n }\n }\n this.RailCollapsed = UserInfoEngine.Instance.GetSetting(TestingExplorerComponent.RAIL_COLLAPSED_KEY) === 'true';\n } catch (error) {\n console.warn('[TestingExplorer] Failed to load user settings:', error);\n } finally {\n this.settingsLoaded = true;\n }\n }\n\n private setupSettingsPersistence(): void {\n this.settingsPersistSubject.pipe(\n debounceTime(500),\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.persistSearchState();\n });\n }\n\n /** The rail toggled — take the new state and persist it (the component only presents). */\n OnRailCollapsedChange(collapsed: boolean): void {\n this.RailCollapsed = collapsed;\n if (!this.settingsLoaded) return;\n try {\n UserInfoEngine.Instance.SetSettingDebounced(\n TestingExplorerComponent.RAIL_COLLAPSED_KEY,\n String(collapsed)\n );\n } catch (error) {\n console.warn('[TestingExplorer] Failed to persist rail collapsed state:', error);\n }\n }\n\n private persistSearchState(): void {\n if (!this.settingsLoaded) return;\n try {\n const state = { searchTerm: this.SearchTerm };\n UserInfoEngine.Instance.SetSettingDebounced(\n TestingExplorerComponent.SEARCH_STATE_KEY,\n JSON.stringify(state)\n );\n } catch (error) {\n console.warn('[TestingExplorer] Failed to persist search state:', error);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private: Form Management\n // ---------------------------------------------------------------------------\n\n private resetForm(): void {\n this.FormName = '';\n this.FormDescription = '';\n this.FormTypeID = this.AllTestTypes.length > 0 ? this.AllTestTypes[0].ID : '';\n this.FormStatus = 'Active';\n this.FormParentSuiteID = '';\n this.FormEstDuration = 0;\n this.FormEstCost = 0;\n this.FormTags = '';\n this.FormErrorMessage = '';\n }\n\n private async saveNewTest(): Promise<void> {\n const md = this.ProviderToUse;\n const test = await md.GetEntityObject<MJTestEntity>('MJ: Tests');\n test.NewRecord();\n test.Name = this.FormName.trim();\n test.Description = this.FormDescription.trim() || null;\n test.TypeID = this.FormTypeID;\n test.Status = this.FormStatus;\n if (this.FormEstDuration > 0) test.EstimatedDurationSeconds = this.FormEstDuration;\n if (this.FormEstCost > 0) test.EstimatedCostUSD = this.FormEstCost;\n if (this.FormTags.trim()) {\n const tags = this.FormTags.split(',').map(t => t.trim()).filter(t => t.length > 0);\n test.Tags = JSON.stringify(tags);\n }\n const saved = await test.Save();\n if (!saved) throw new Error('Failed to save test. Please check your input and try again.');\n }\n\n private async saveNewSuite(): Promise<void> {\n const md = this.ProviderToUse;\n const suite = await md.GetEntityObject<MJTestSuiteEntity>('MJ: Test Suites');\n suite.NewRecord();\n suite.Name = this.FormName.trim();\n suite.Description = this.FormDescription.trim() || null;\n suite.Status = this.FormStatus;\n if (this.FormParentSuiteID) suite.ParentID = this.FormParentSuiteID;\n if (this.FormTags.trim()) {\n const tags = this.FormTags.split(',').map(t => t.trim()).filter(t => t.length > 0);\n suite.Tags = JSON.stringify(tags);\n }\n const saved = await suite.Save();\n if (!saved) throw new Error('Failed to save test suite. Please check your input and try again.');\n }\n}\n"]}
|