@memberjunction/ng-core-entity-forms 5.42.0 → 5.44.0
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/__tests__/model-prediction.logic.test.d.ts +2 -0
- package/dist/__tests__/model-prediction.logic.test.d.ts.map +1 -0
- package/dist/__tests__/model-prediction.logic.test.js +140 -0
- package/dist/__tests__/model-prediction.logic.test.js.map +1 -0
- package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js +79 -105
- package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js +7 -10
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js +46 -51
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +2 -0
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js +300 -378
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +22 -29
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +15 -17
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +27 -34
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts +11 -0
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +48 -47
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +438 -454
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js +48 -51
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +253 -282
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-execution-log-form.component.js +24 -33
- package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.js +263 -311
- package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.d.ts +6 -0
- package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.js +475 -493
- package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
- package/dist/lib/custom/Lists/list-form.component.js +122 -173
- package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.js +190 -248
- package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-run-dialog.component.js +19 -23
- package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
- package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts +16 -0
- package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts.map +1 -0
- package/dist/lib/custom/RecordProcesses/record-process-form.component.js +54 -0
- package/dist/lib/custom/RecordProcesses/record-process-form.component.js.map +1 -0
- package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js +23 -24
- package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.js +25 -46
- package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.js +100 -130
- package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-run-form.component.js +187 -205
- package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts +8 -0
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.js +412 -489
- package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.js +100 -126
- package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +166 -184
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +42 -61
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +8 -17
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +0 -2
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +183 -188
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts +108 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js +665 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts +94 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js +257 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts +38 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.js +200 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts +44 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js +180 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts +12 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js +46 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts +64 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js +267 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts +53 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js +111 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts +42 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js +193 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js.map +1 -0
- package/dist/lib/custom/custom-forms.module.d.ts +58 -49
- package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
- package/dist/lib/custom/custom-forms.module.js +64 -16
- package/dist/lib/custom/custom-forms.module.js.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts +2 -0
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.js +25 -25
- package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +280 -216
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentChannel/mjaiagentchannel.form.component.js +25 -21
- package/dist/lib/generated/Entities/MJAIAgentChannel/mjaiagentchannel.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +68 -14
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js +44 -32
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.js +66 -0
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +55 -19
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +28 -10
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.js +167 -0
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.js +64 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.js +82 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.js +64 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAction/mjaction.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js +35 -17
- package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js +59 -51
- package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js +25 -7
- package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJCollectionArtifact/mjcollectionartifact.form.component.js +11 -7
- package/dist/lib/generated/Entities/MJCollectionArtifact/mjcollectionartifact.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +56 -46
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js +73 -59
- package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js +24 -4
- package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +137 -87
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntityActionInvocation/mjentityactioninvocation.form.component.js +10 -8
- package/dist/lib/generated/Entities/MJEntityActionInvocation/mjentityactioninvocation.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js +47 -29
- package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.js +99 -0
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.js +101 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.js +115 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJFile/mjfile.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js +63 -9
- package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js +32 -14
- package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.js +161 -0
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.js +89 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.js +76 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js +141 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.js +88 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js +143 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js +110 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.js +56 -24
- package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js +19 -17
- package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js +46 -26
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRemoteOperation/mjremoteoperation.form.component.js +12 -6
- package/dist/lib/generated/Entities/MJRemoteOperation/mjremoteoperation.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js +36 -18
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJSchemaInfo/mjschemainfo.form.component.js +8 -6
- package/dist/lib/generated/Entities/MJSchemaInfo/mjschemainfo.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.js +78 -0
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +145 -109
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
- package/dist/lib/generated/generated-forms.module.d.ts +356 -335
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
- package/dist/lib/generated/generated-forms.module.js +304 -226
- package/dist/lib/generated/generated-forms.module.js.map +1 -1
- package/dist/lib/panels/ai-agents/agent-realtime.panel.js +44 -44
- package/dist/lib/panels/ai-agents/agent-realtime.panel.js.map +1 -1
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts +43 -0
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts.map +1 -0
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js +240 -0
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts +69 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.js +130 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.js.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts +83 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.js +293 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.js.map +1 -0
- package/package.json +38 -36
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts +0 -82
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts.map +0 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js +0 -1033
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js.map +0 -1
|
@@ -27,19 +27,17 @@ const _c1 = () => [1, 2];
|
|
|
27
27
|
const _c2 = () => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
28
28
|
function MJTestRunFormComponentExtended_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
29
29
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
30
|
-
i0.ɵɵelementStart(0, "
|
|
31
|
-
i0.ɵɵ
|
|
32
|
-
i0.ɵɵelement(1, "i", 65);
|
|
33
|
-
i0.ɵɵelementStart(2, "span");
|
|
34
|
-
i0.ɵɵtext(3);
|
|
30
|
+
i0.ɵɵelementStart(0, "mj-alert", 1)(1, "span");
|
|
31
|
+
i0.ɵɵtext(2);
|
|
35
32
|
i0.ɵɵelementEnd();
|
|
36
|
-
i0.ɵɵelementStart(
|
|
37
|
-
i0.ɵɵ
|
|
38
|
-
i0.ɵɵ
|
|
33
|
+
i0.ɵɵelementStart(3, "button", 64);
|
|
34
|
+
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_1_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.retryLoad()); });
|
|
35
|
+
i0.ɵɵelement(4, "i", 20);
|
|
36
|
+
i0.ɵɵtext(5, " Retry ");
|
|
39
37
|
i0.ɵɵelementEnd()();
|
|
40
38
|
} if (rf & 2) {
|
|
41
39
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
42
|
-
i0.ɵɵadvance(
|
|
40
|
+
i0.ɵɵadvance(2);
|
|
43
41
|
i0.ɵɵtextInterpolate(ctx_r1.error);
|
|
44
42
|
} }
|
|
45
43
|
function MJTestRunFormComponentExtended_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -48,7 +46,7 @@ function MJTestRunFormComponentExtended_Conditional_10_Template(rf, ctx) { if (r
|
|
|
48
46
|
i0.ɵɵelement(1, "i", 8);
|
|
49
47
|
i0.ɵɵelementStart(2, "a", 4);
|
|
50
48
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_10_Template_a_click_2_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openTest()); });
|
|
51
|
-
i0.ɵɵelement(3, "i",
|
|
49
|
+
i0.ɵɵelement(3, "i", 65);
|
|
52
50
|
i0.ɵɵelementStart(4, "span", 6);
|
|
53
51
|
i0.ɵɵtext(5);
|
|
54
52
|
i0.ɵɵelementEnd()()();
|
|
@@ -59,7 +57,7 @@ function MJTestRunFormComponentExtended_Conditional_10_Template(rf, ctx) { if (r
|
|
|
59
57
|
} }
|
|
60
58
|
function MJTestRunFormComponentExtended_Conditional_27_Template(rf, ctx) { if (rf & 1) {
|
|
61
59
|
i0.ɵɵelementStart(0, "span", 17);
|
|
62
|
-
i0.ɵɵelement(1, "i",
|
|
60
|
+
i0.ɵɵelement(1, "i", 65);
|
|
63
61
|
i0.ɵɵtext(2);
|
|
64
62
|
i0.ɵɵelementEnd();
|
|
65
63
|
} if (rf & 2) {
|
|
@@ -69,13 +67,13 @@ function MJTestRunFormComponentExtended_Conditional_27_Template(rf, ctx) { if (r
|
|
|
69
67
|
} }
|
|
70
68
|
function MJTestRunFormComponentExtended_Conditional_28_Template(rf, ctx) { if (rf & 1) {
|
|
71
69
|
i0.ɵɵelementStart(0, "span", 17);
|
|
72
|
-
i0.ɵɵelement(1, "i",
|
|
70
|
+
i0.ɵɵelement(1, "i", 66);
|
|
73
71
|
i0.ɵɵtext(2, " Auto-refreshing ");
|
|
74
72
|
i0.ɵɵelementEnd();
|
|
75
73
|
} }
|
|
76
74
|
function MJTestRunFormComponentExtended_Conditional_66_Template(rf, ctx) { if (rf & 1) {
|
|
77
75
|
i0.ɵɵelementStart(0, "div", 34);
|
|
78
|
-
i0.ɵɵelement(1, "div",
|
|
76
|
+
i0.ɵɵelement(1, "div", 67);
|
|
79
77
|
i0.ɵɵelementEnd();
|
|
80
78
|
} if (rf & 2) {
|
|
81
79
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -84,7 +82,7 @@ function MJTestRunFormComponentExtended_Conditional_66_Template(rf, ctx) { if (r
|
|
|
84
82
|
} }
|
|
85
83
|
function MJTestRunFormComponentExtended_Conditional_75_Template(rf, ctx) { if (rf & 1) {
|
|
86
84
|
i0.ɵɵelementStart(0, "div", 34);
|
|
87
|
-
i0.ɵɵelement(1, "div",
|
|
85
|
+
i0.ɵɵelement(1, "div", 67);
|
|
88
86
|
i0.ɵɵelementEnd();
|
|
89
87
|
} if (rf & 2) {
|
|
90
88
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -92,8 +90,8 @@ function MJTestRunFormComponentExtended_Conditional_75_Template(rf, ctx) { if (r
|
|
|
92
90
|
i0.ɵɵstyleProp("width", ctx_r1.getPassRatePercentage(), "%")("background-color", ctx_r1.getStatusColor());
|
|
93
91
|
} }
|
|
94
92
|
function MJTestRunFormComponentExtended_Conditional_84_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
95
|
-
i0.ɵɵelementStart(0, "span",
|
|
96
|
-
i0.ɵɵelement(1, "i",
|
|
93
|
+
i0.ɵɵelementStart(0, "span", 68);
|
|
94
|
+
i0.ɵɵelement(1, "i", 71);
|
|
97
95
|
i0.ɵɵtext(2);
|
|
98
96
|
i0.ɵɵelementEnd();
|
|
99
97
|
} if (rf & 2) {
|
|
@@ -103,9 +101,9 @@ function MJTestRunFormComponentExtended_Conditional_84_Conditional_1_Template(rf
|
|
|
103
101
|
} }
|
|
104
102
|
function MJTestRunFormComponentExtended_Conditional_84_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
105
103
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
106
|
-
i0.ɵɵelementStart(0, "span",
|
|
104
|
+
i0.ɵɵelementStart(0, "span", 72);
|
|
107
105
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_84_Conditional_2_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openTestSuiteRun()); });
|
|
108
|
-
i0.ɵɵelement(1, "i",
|
|
106
|
+
i0.ɵɵelement(1, "i", 73);
|
|
109
107
|
i0.ɵɵtext(2);
|
|
110
108
|
i0.ɵɵelementEnd();
|
|
111
109
|
} if (rf & 2) {
|
|
@@ -114,16 +112,16 @@ function MJTestRunFormComponentExtended_Conditional_84_Conditional_2_Template(rf
|
|
|
114
112
|
i0.ɵɵtextInterpolate1(" Part of Suite Run (Seq: ", ctx_r1.record.Sequence, ") ");
|
|
115
113
|
} }
|
|
116
114
|
function MJTestRunFormComponentExtended_Conditional_84_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
117
|
-
i0.ɵɵelement(0, "mj-entity-link-pill",
|
|
115
|
+
i0.ɵɵelement(0, "mj-entity-link-pill", 70);
|
|
118
116
|
} if (rf & 2) {
|
|
119
117
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
120
118
|
i0.ɵɵproperty("entityName", ctx_r1.record.TargetLogEntity)("recordId", ctx_r1.record.TargetLogID);
|
|
121
119
|
} }
|
|
122
120
|
function MJTestRunFormComponentExtended_Conditional_84_Template(rf, ctx) { if (rf & 1) {
|
|
123
121
|
i0.ɵɵelementStart(0, "div", 37);
|
|
124
|
-
i0.ɵɵconditionalCreate(1, MJTestRunFormComponentExtended_Conditional_84_Conditional_1_Template, 3, 1, "span",
|
|
125
|
-
i0.ɵɵconditionalCreate(2, MJTestRunFormComponentExtended_Conditional_84_Conditional_2_Template, 3, 1, "span",
|
|
126
|
-
i0.ɵɵconditionalCreate(3, MJTestRunFormComponentExtended_Conditional_84_Conditional_3_Template, 1, 2, "mj-entity-link-pill",
|
|
122
|
+
i0.ɵɵconditionalCreate(1, MJTestRunFormComponentExtended_Conditional_84_Conditional_1_Template, 3, 1, "span", 68);
|
|
123
|
+
i0.ɵɵconditionalCreate(2, MJTestRunFormComponentExtended_Conditional_84_Conditional_2_Template, 3, 1, "span", 69);
|
|
124
|
+
i0.ɵɵconditionalCreate(3, MJTestRunFormComponentExtended_Conditional_84_Conditional_3_Template, 1, 2, "mj-entity-link-pill", 70);
|
|
127
125
|
i0.ɵɵelementEnd();
|
|
128
126
|
} if (rf & 2) {
|
|
129
127
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -135,7 +133,7 @@ function MJTestRunFormComponentExtended_Conditional_84_Template(rf, ctx) { if (r
|
|
|
135
133
|
i0.ɵɵconditional(ctx_r1.record.TargetLogEntityID && ctx_r1.record.TargetLogID ? 3 : -1);
|
|
136
134
|
} }
|
|
137
135
|
function MJTestRunFormComponentExtended_Conditional_85_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
138
|
-
i0.ɵɵelementStart(0, "span",
|
|
136
|
+
i0.ɵɵelementStart(0, "span", 81);
|
|
139
137
|
i0.ɵɵtext(1);
|
|
140
138
|
i0.ɵɵelementEnd();
|
|
141
139
|
} if (rf & 2) {
|
|
@@ -144,8 +142,8 @@ function MJTestRunFormComponentExtended_Conditional_85_Conditional_4_For_2_Templ
|
|
|
144
142
|
i0.ɵɵtextInterpolate(tag_r6);
|
|
145
143
|
} }
|
|
146
144
|
function MJTestRunFormComponentExtended_Conditional_85_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
147
|
-
i0.ɵɵelementStart(0, "div",
|
|
148
|
-
i0.ɵɵrepeaterCreate(1, MJTestRunFormComponentExtended_Conditional_85_Conditional_4_For_2_Template, 2, 1, "span",
|
|
145
|
+
i0.ɵɵelementStart(0, "div", 77);
|
|
146
|
+
i0.ɵɵrepeaterCreate(1, MJTestRunFormComponentExtended_Conditional_85_Conditional_4_For_2_Template, 2, 1, "span", 81, i0.ɵɵrepeaterTrackByIdentity);
|
|
149
147
|
i0.ɵɵelementEnd();
|
|
150
148
|
} if (rf & 2) {
|
|
151
149
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -153,20 +151,20 @@ function MJTestRunFormComponentExtended_Conditional_85_Conditional_4_Template(rf
|
|
|
153
151
|
i0.ɵɵrepeater(ctx_r1.tags);
|
|
154
152
|
} }
|
|
155
153
|
function MJTestRunFormComponentExtended_Conditional_85_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
156
|
-
i0.ɵɵelementStart(0, "span",
|
|
154
|
+
i0.ɵɵelementStart(0, "span", 78);
|
|
157
155
|
i0.ɵɵtext(1, "No tags");
|
|
158
156
|
i0.ɵɵelementEnd();
|
|
159
157
|
} }
|
|
160
158
|
function MJTestRunFormComponentExtended_Conditional_85_Template(rf, ctx) { if (rf & 1) {
|
|
161
159
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
162
|
-
i0.ɵɵelementStart(0, "div", 38)(1, "div",
|
|
163
|
-
i0.ɵɵelement(3, "i",
|
|
160
|
+
i0.ɵɵelementStart(0, "div", 38)(1, "div", 74)(2, "span", 75);
|
|
161
|
+
i0.ɵɵelement(3, "i", 76);
|
|
164
162
|
i0.ɵɵelementEnd();
|
|
165
|
-
i0.ɵɵconditionalCreate(4, MJTestRunFormComponentExtended_Conditional_85_Conditional_4_Template, 3, 0, "div",
|
|
166
|
-
i0.ɵɵconditionalCreate(5, MJTestRunFormComponentExtended_Conditional_85_Conditional_5_Template, 2, 0, "span",
|
|
167
|
-
i0.ɵɵelementStart(6, "button",
|
|
163
|
+
i0.ɵɵconditionalCreate(4, MJTestRunFormComponentExtended_Conditional_85_Conditional_4_Template, 3, 0, "div", 77);
|
|
164
|
+
i0.ɵɵconditionalCreate(5, MJTestRunFormComponentExtended_Conditional_85_Conditional_5_Template, 2, 0, "span", 78);
|
|
165
|
+
i0.ɵɵelementStart(6, "button", 79);
|
|
168
166
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_85_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.startEditingTags()); });
|
|
169
|
-
i0.ɵɵelement(7, "i",
|
|
167
|
+
i0.ɵɵelement(7, "i", 80);
|
|
170
168
|
i0.ɵɵtext(8, " Add ");
|
|
171
169
|
i0.ɵɵelementEnd()()();
|
|
172
170
|
} if (rf & 2) {
|
|
@@ -178,11 +176,11 @@ function MJTestRunFormComponentExtended_Conditional_85_Template(rf, ctx) { if (r
|
|
|
178
176
|
} }
|
|
179
177
|
function MJTestRunFormComponentExtended_Conditional_86_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
180
178
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
181
|
-
i0.ɵɵelementStart(0, "span",
|
|
179
|
+
i0.ɵɵelementStart(0, "span", 86);
|
|
182
180
|
i0.ɵɵtext(1);
|
|
183
|
-
i0.ɵɵelementStart(2, "button",
|
|
181
|
+
i0.ɵɵelementStart(2, "button", 95);
|
|
184
182
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_86_For_8_Template_button_click_2_listener() { const tag_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.removeTag(tag_r9)); });
|
|
185
|
-
i0.ɵɵelement(3, "i",
|
|
183
|
+
i0.ɵɵelement(3, "i", 96);
|
|
186
184
|
i0.ɵɵelementEnd()();
|
|
187
185
|
} if (rf & 2) {
|
|
188
186
|
const tag_r9 = ctx.$implicit;
|
|
@@ -190,37 +188,37 @@ function MJTestRunFormComponentExtended_Conditional_86_For_8_Template(rf, ctx) {
|
|
|
190
188
|
i0.ɵɵtextInterpolate1(" ", tag_r9, " ");
|
|
191
189
|
} }
|
|
192
190
|
function MJTestRunFormComponentExtended_Conditional_86_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
193
|
-
i0.ɵɵelementStart(0, "span",
|
|
191
|
+
i0.ɵɵelementStart(0, "span", 87);
|
|
194
192
|
i0.ɵɵtext(1, "No tags yet");
|
|
195
193
|
i0.ɵɵelementEnd();
|
|
196
194
|
} }
|
|
197
195
|
function MJTestRunFormComponentExtended_Conditional_86_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
198
|
-
i0.ɵɵelement(0, "i",
|
|
196
|
+
i0.ɵɵelement(0, "i", 93);
|
|
199
197
|
} }
|
|
200
198
|
function MJTestRunFormComponentExtended_Conditional_86_Template(rf, ctx) { if (rf & 1) {
|
|
201
199
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
202
|
-
i0.ɵɵelementStart(0, "div", 39)(1, "div",
|
|
203
|
-
i0.ɵɵelement(3, "i",
|
|
200
|
+
i0.ɵɵelementStart(0, "div", 39)(1, "div", 82)(2, "span", 83);
|
|
201
|
+
i0.ɵɵelement(3, "i", 76);
|
|
204
202
|
i0.ɵɵtext(4, " Edit Tags");
|
|
205
203
|
i0.ɵɵelementEnd()();
|
|
206
|
-
i0.ɵɵelementStart(5, "div",
|
|
207
|
-
i0.ɵɵrepeaterCreate(7, MJTestRunFormComponentExtended_Conditional_86_For_8_Template, 4, 1, "span",
|
|
208
|
-
i0.ɵɵconditionalCreate(9, MJTestRunFormComponentExtended_Conditional_86_Conditional_9_Template, 2, 0, "span",
|
|
204
|
+
i0.ɵɵelementStart(5, "div", 84)(6, "div", 85);
|
|
205
|
+
i0.ɵɵrepeaterCreate(7, MJTestRunFormComponentExtended_Conditional_86_For_8_Template, 4, 1, "span", 86, i0.ɵɵrepeaterTrackByIdentity);
|
|
206
|
+
i0.ɵɵconditionalCreate(9, MJTestRunFormComponentExtended_Conditional_86_Conditional_9_Template, 2, 0, "span", 87);
|
|
209
207
|
i0.ɵɵelementEnd();
|
|
210
|
-
i0.ɵɵelementStart(10, "div",
|
|
208
|
+
i0.ɵɵelementStart(10, "div", 88)(11, "input", 89);
|
|
211
209
|
i0.ɵɵtwoWayListener("ngModelChange", function MJTestRunFormComponentExtended_Conditional_86_Template_input_ngModelChange_11_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newTag, $event) || (ctx_r1.newTag = $event); return i0.ɵɵresetView($event); });
|
|
212
210
|
i0.ɵɵlistener("keyup.enter", function MJTestRunFormComponentExtended_Conditional_86_Template_input_keyup_enter_11_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.addTag()); });
|
|
213
211
|
i0.ɵɵelementEnd();
|
|
214
|
-
i0.ɵɵelementStart(12, "button",
|
|
212
|
+
i0.ɵɵelementStart(12, "button", 90);
|
|
215
213
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_86_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.addTag()); });
|
|
216
|
-
i0.ɵɵelement(13, "i",
|
|
214
|
+
i0.ɵɵelement(13, "i", 80);
|
|
217
215
|
i0.ɵɵelementEnd()()();
|
|
218
|
-
i0.ɵɵelementStart(14, "div",
|
|
216
|
+
i0.ɵɵelementStart(14, "div", 91)(15, "button", 92);
|
|
219
217
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_86_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.saveTags()); });
|
|
220
|
-
i0.ɵɵconditionalCreate(16, MJTestRunFormComponentExtended_Conditional_86_Conditional_16_Template, 1, 0, "i",
|
|
218
|
+
i0.ɵɵconditionalCreate(16, MJTestRunFormComponentExtended_Conditional_86_Conditional_16_Template, 1, 0, "i", 93);
|
|
221
219
|
i0.ɵɵtext(17);
|
|
222
220
|
i0.ɵɵelementEnd();
|
|
223
|
-
i0.ɵɵelementStart(18, "button",
|
|
221
|
+
i0.ɵɵelementStart(18, "button", 94);
|
|
224
222
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_86_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelEditingTags()); });
|
|
225
223
|
i0.ɵɵtext(19, "Cancel");
|
|
226
224
|
i0.ɵɵelementEnd()()();
|
|
@@ -261,9 +259,9 @@ function MJTestRunFormComponentExtended_Conditional_106_Template(rf, ctx) { if (
|
|
|
261
259
|
} }
|
|
262
260
|
function MJTestRunFormComponentExtended_Conditional_111_Template(rf, ctx) { if (rf & 1) {
|
|
263
261
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
264
|
-
i0.ɵɵelementStart(0, "button",
|
|
262
|
+
i0.ɵɵelementStart(0, "button", 97);
|
|
265
263
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_111_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.changeTab("log")); });
|
|
266
|
-
i0.ɵɵelement(1, "i",
|
|
264
|
+
i0.ɵɵelement(1, "i", 98);
|
|
267
265
|
i0.ɵɵelementStart(2, "span");
|
|
268
266
|
i0.ɵɵtext(3, "Log");
|
|
269
267
|
i0.ɵɵelementEnd()();
|
|
@@ -273,10 +271,10 @@ function MJTestRunFormComponentExtended_Conditional_111_Template(rf, ctx) { if (
|
|
|
273
271
|
i0.ɵɵattribute("aria-selected", ctx_r1.activeTab === "log");
|
|
274
272
|
} }
|
|
275
273
|
function MJTestRunFormComponentExtended_Conditional_113_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
276
|
-
i0.ɵɵelement(0, "div",
|
|
274
|
+
i0.ɵɵelement(0, "div", 102);
|
|
277
275
|
} }
|
|
278
276
|
function MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
279
|
-
i0.ɵɵelementStart(0, "div",
|
|
277
|
+
i0.ɵɵelementStart(0, "div", 128);
|
|
280
278
|
i0.ɵɵtext(1);
|
|
281
279
|
i0.ɵɵelementEnd();
|
|
282
280
|
} if (rf & 2) {
|
|
@@ -285,7 +283,7 @@ function MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Con
|
|
|
285
283
|
i0.ɵɵtextInterpolate(check_r12.message);
|
|
286
284
|
} }
|
|
287
285
|
function MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
288
|
-
i0.ɵɵelementStart(0, "div",
|
|
286
|
+
i0.ɵɵelementStart(0, "div", 129)(1, "span", 130);
|
|
289
287
|
i0.ɵɵtext(2, "Weight:");
|
|
290
288
|
i0.ɵɵelementEnd();
|
|
291
289
|
i0.ɵɵtext(3);
|
|
@@ -296,20 +294,20 @@ function MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Con
|
|
|
296
294
|
i0.ɵɵtextInterpolate1(" ", check_r12.weight, " ");
|
|
297
295
|
} }
|
|
298
296
|
function MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Template(rf, ctx) { if (rf & 1) {
|
|
299
|
-
i0.ɵɵelementStart(0, "div",
|
|
300
|
-
i0.ɵɵelement(2, "i",
|
|
297
|
+
i0.ɵɵelementStart(0, "div", 123)(1, "div", 124);
|
|
298
|
+
i0.ɵɵelement(2, "i", 125);
|
|
301
299
|
i0.ɵɵelementEnd();
|
|
302
|
-
i0.ɵɵelementStart(3, "div",
|
|
300
|
+
i0.ɵɵelementStart(3, "div", 126)(4, "div", 127);
|
|
303
301
|
i0.ɵɵtext(5);
|
|
304
302
|
i0.ɵɵelementEnd();
|
|
305
|
-
i0.ɵɵconditionalCreate(6, MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Conditional_6_Template, 2, 1, "div",
|
|
303
|
+
i0.ɵɵconditionalCreate(6, MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Conditional_6_Template, 2, 1, "div", 128);
|
|
306
304
|
i0.ɵɵelementEnd();
|
|
307
|
-
i0.ɵɵconditionalCreate(7, MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Conditional_7_Template, 4, 1, "div",
|
|
305
|
+
i0.ɵɵconditionalCreate(7, MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Conditional_7_Template, 4, 1, "div", 129);
|
|
308
306
|
i0.ɵɵelementEnd();
|
|
309
307
|
} if (rf & 2) {
|
|
310
308
|
const check_r12 = ctx.$implicit;
|
|
311
|
-
const ɵ$
|
|
312
|
-
i0.ɵɵstyleProp("animation-delay", ɵ$
|
|
309
|
+
const ɵ$index_373_r13 = ctx.$index;
|
|
310
|
+
i0.ɵɵstyleProp("animation-delay", ɵ$index_373_r13 * 50, "ms");
|
|
313
311
|
i0.ɵɵclassProp("passed", check_r12.passed)("failed", !check_r12.passed);
|
|
314
312
|
i0.ɵɵadvance(2);
|
|
315
313
|
i0.ɵɵclassProp("fa-check-circle", check_r12.passed)("fa-times-circle", !check_r12.passed);
|
|
@@ -321,15 +319,15 @@ function MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Tem
|
|
|
321
319
|
i0.ɵɵconditional(check_r12.weight ? 7 : -1);
|
|
322
320
|
} }
|
|
323
321
|
function MJTestRunFormComponentExtended_Conditional_113_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
324
|
-
i0.ɵɵelementStart(0, "div",
|
|
325
|
-
i0.ɵɵelement(3, "i",
|
|
322
|
+
i0.ɵɵelementStart(0, "div", 108)(1, "div", 110)(2, "h3");
|
|
323
|
+
i0.ɵɵelement(3, "i", 119);
|
|
326
324
|
i0.ɵɵtext(4, " Check Results");
|
|
327
325
|
i0.ɵɵelementEnd();
|
|
328
|
-
i0.ɵɵelementStart(5, "span",
|
|
326
|
+
i0.ɵɵelementStart(5, "span", 120);
|
|
329
327
|
i0.ɵɵtext(6);
|
|
330
328
|
i0.ɵɵelementEnd()();
|
|
331
|
-
i0.ɵɵelementStart(7, "div",
|
|
332
|
-
i0.ɵɵrepeaterCreate(8, MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Template, 8, 13, "div",
|
|
329
|
+
i0.ɵɵelementStart(7, "div", 121);
|
|
330
|
+
i0.ɵɵrepeaterCreate(8, MJTestRunFormComponentExtended_Conditional_113_Conditional_16_For_9_Template, 8, 13, "div", 122, i0.ɵɵrepeaterTrackByIdentity);
|
|
333
331
|
i0.ɵɵelementEnd()();
|
|
334
332
|
} if (rf & 2) {
|
|
335
333
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -340,45 +338,45 @@ function MJTestRunFormComponentExtended_Conditional_113_Conditional_16_Template(
|
|
|
340
338
|
} }
|
|
341
339
|
function MJTestRunFormComponentExtended_Conditional_113_Template(rf, ctx) { if (rf & 1) {
|
|
342
340
|
const _r11 = i0.ɵɵgetCurrentView();
|
|
343
|
-
i0.ɵɵelementStart(0, "div", 55)(1, "div",
|
|
341
|
+
i0.ɵɵelementStart(0, "div", 55)(1, "div", 99)(2, "div", 100)(3, "div", 101);
|
|
344
342
|
i0.ɵɵelement(4, "i", 12);
|
|
345
343
|
i0.ɵɵelementEnd();
|
|
346
|
-
i0.ɵɵconditionalCreate(5, MJTestRunFormComponentExtended_Conditional_113_Conditional_5_Template, 1, 0, "div",
|
|
344
|
+
i0.ɵɵconditionalCreate(5, MJTestRunFormComponentExtended_Conditional_113_Conditional_5_Template, 1, 0, "div", 102);
|
|
347
345
|
i0.ɵɵelementEnd();
|
|
348
|
-
i0.ɵɵelementStart(6, "div",
|
|
346
|
+
i0.ɵɵelementStart(6, "div", 103)(7, "h2");
|
|
349
347
|
i0.ɵɵtext(8);
|
|
350
348
|
i0.ɵɵelementEnd();
|
|
351
|
-
i0.ɵɵelementStart(9, "div",
|
|
349
|
+
i0.ɵɵelementStart(9, "div", 104)(10, "span", 105);
|
|
352
350
|
i0.ɵɵtext(11);
|
|
353
351
|
i0.ɵɵelementEnd();
|
|
354
|
-
i0.ɵɵelementStart(12, "span",
|
|
352
|
+
i0.ɵɵelementStart(12, "span", 106);
|
|
355
353
|
i0.ɵɵtext(13, "|");
|
|
356
354
|
i0.ɵɵelementEnd();
|
|
357
|
-
i0.ɵɵelementStart(14, "span",
|
|
355
|
+
i0.ɵɵelementStart(14, "span", 107);
|
|
358
356
|
i0.ɵɵtext(15);
|
|
359
357
|
i0.ɵɵelementEnd()()()();
|
|
360
|
-
i0.ɵɵconditionalCreate(16, MJTestRunFormComponentExtended_Conditional_113_Conditional_16_Template, 10, 2, "div",
|
|
361
|
-
i0.ɵɵelementStart(17, "div",
|
|
362
|
-
i0.ɵɵelement(20, "i",
|
|
358
|
+
i0.ɵɵconditionalCreate(16, MJTestRunFormComponentExtended_Conditional_113_Conditional_16_Template, 10, 2, "div", 108);
|
|
359
|
+
i0.ɵɵelementStart(17, "div", 109)(18, "div", 110)(19, "h3");
|
|
360
|
+
i0.ɵɵelement(20, "i", 111);
|
|
363
361
|
i0.ɵɵtext(21, " Data Comparison");
|
|
364
362
|
i0.ɵɵelementEnd()();
|
|
365
|
-
i0.ɵɵelementStart(22, "div",
|
|
363
|
+
i0.ɵɵelementStart(22, "div", 112)(23, "button", 113);
|
|
366
364
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_113_Template_button_click_23_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setComparisonView("input")); });
|
|
367
|
-
i0.ɵɵelement(24, "i",
|
|
365
|
+
i0.ɵɵelement(24, "i", 114);
|
|
368
366
|
i0.ɵɵtext(25, " Input ");
|
|
369
367
|
i0.ɵɵelementEnd();
|
|
370
|
-
i0.ɵɵelementStart(26, "button",
|
|
368
|
+
i0.ɵɵelementStart(26, "button", 113);
|
|
371
369
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_113_Template_button_click_26_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setComparisonView("expected")); });
|
|
372
|
-
i0.ɵɵelement(27, "i",
|
|
370
|
+
i0.ɵɵelement(27, "i", 115);
|
|
373
371
|
i0.ɵɵtext(28, " Expected ");
|
|
374
372
|
i0.ɵɵelementEnd();
|
|
375
|
-
i0.ɵɵelementStart(29, "button",
|
|
373
|
+
i0.ɵɵelementStart(29, "button", 113);
|
|
376
374
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_113_Template_button_click_29_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setComparisonView("actual")); });
|
|
377
|
-
i0.ɵɵelement(30, "i",
|
|
375
|
+
i0.ɵɵelement(30, "i", 116);
|
|
378
376
|
i0.ɵɵtext(31, " Actual ");
|
|
379
377
|
i0.ɵɵelementEnd()();
|
|
380
|
-
i0.ɵɵelementStart(32, "div",
|
|
381
|
-
i0.ɵɵelement(33, "mj-code-editor",
|
|
378
|
+
i0.ɵɵelementStart(32, "div", 117);
|
|
379
|
+
i0.ɵɵelement(33, "mj-code-editor", 118);
|
|
382
380
|
i0.ɵɵelementEnd()()();
|
|
383
381
|
} if (rf & 2) {
|
|
384
382
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -408,18 +406,18 @@ function MJTestRunFormComponentExtended_Conditional_113_Template(rf, ctx) { if (
|
|
|
408
406
|
} }
|
|
409
407
|
function MJTestRunFormComponentExtended_Conditional_114_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
410
408
|
const _r14 = i0.ɵɵgetCurrentView();
|
|
411
|
-
i0.ɵɵelementStart(0, "div",
|
|
409
|
+
i0.ɵɵelementStart(0, "div", 146);
|
|
412
410
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_114_Conditional_10_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openTest()); });
|
|
413
|
-
i0.ɵɵelementStart(1, "div",
|
|
414
|
-
i0.ɵɵelement(2, "i",
|
|
411
|
+
i0.ɵɵelementStart(1, "div", 133);
|
|
412
|
+
i0.ɵɵelement(2, "i", 65);
|
|
415
413
|
i0.ɵɵelementEnd();
|
|
416
|
-
i0.ɵɵelementStart(3, "div",
|
|
414
|
+
i0.ɵɵelementStart(3, "div", 135)(4, "div", 136);
|
|
417
415
|
i0.ɵɵtext(5, "Test");
|
|
418
416
|
i0.ɵɵelementEnd();
|
|
419
|
-
i0.ɵɵelementStart(6, "div",
|
|
417
|
+
i0.ɵɵelementStart(6, "div", 147);
|
|
420
418
|
i0.ɵɵtext(7);
|
|
421
419
|
i0.ɵɵelementEnd()();
|
|
422
|
-
i0.ɵɵelement(8, "i",
|
|
420
|
+
i0.ɵɵelement(8, "i", 148);
|
|
423
421
|
i0.ɵɵelementEnd();
|
|
424
422
|
} if (rf & 2) {
|
|
425
423
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -427,12 +425,12 @@ function MJTestRunFormComponentExtended_Conditional_114_Conditional_10_Template(
|
|
|
427
425
|
i0.ɵɵtextInterpolate(ctx_r1.test.Name);
|
|
428
426
|
} }
|
|
429
427
|
function MJTestRunFormComponentExtended_Conditional_114_Conditional_45_Template(rf, ctx) { if (rf & 1) {
|
|
430
|
-
i0.ɵɵelementStart(0, "div",
|
|
431
|
-
i0.ɵɵelement(3, "i",
|
|
428
|
+
i0.ɵɵelementStart(0, "div", 144)(1, "div", 149)(2, "h3");
|
|
429
|
+
i0.ɵɵelement(3, "i", 150);
|
|
432
430
|
i0.ɵɵtext(4, " Error Message");
|
|
433
431
|
i0.ɵɵelementEnd()();
|
|
434
|
-
i0.ɵɵelementStart(5, "div",
|
|
435
|
-
i0.ɵɵelement(6, "mj-code-editor",
|
|
432
|
+
i0.ɵɵelementStart(5, "div", 151);
|
|
433
|
+
i0.ɵɵelement(6, "mj-code-editor", 152);
|
|
436
434
|
i0.ɵɵelementEnd()();
|
|
437
435
|
} if (rf & 2) {
|
|
438
436
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -440,12 +438,12 @@ function MJTestRunFormComponentExtended_Conditional_114_Conditional_45_Template(
|
|
|
440
438
|
i0.ɵɵproperty("value", ctx_r1.record.ErrorMessage)("readonly", true)("toolbar", ctx_r1.jsonToolbar)("lineWrapping", true);
|
|
441
439
|
} }
|
|
442
440
|
function MJTestRunFormComponentExtended_Conditional_114_Conditional_46_Template(rf, ctx) { if (rf & 1) {
|
|
443
|
-
i0.ɵɵelementStart(0, "div",
|
|
444
|
-
i0.ɵɵelement(3, "i",
|
|
441
|
+
i0.ɵɵelementStart(0, "div", 145)(1, "div", 110)(2, "h3");
|
|
442
|
+
i0.ɵɵelement(3, "i", 153);
|
|
445
443
|
i0.ɵɵtext(4, " Result Details");
|
|
446
444
|
i0.ɵɵelementEnd()();
|
|
447
|
-
i0.ɵɵelementStart(5, "div",
|
|
448
|
-
i0.ɵɵelement(6, "mj-code-editor",
|
|
445
|
+
i0.ɵɵelementStart(5, "div", 154);
|
|
446
|
+
i0.ɵɵelement(6, "mj-code-editor", 118);
|
|
449
447
|
i0.ɵɵelementEnd()();
|
|
450
448
|
} if (rf & 2) {
|
|
451
449
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -453,56 +451,56 @@ function MJTestRunFormComponentExtended_Conditional_114_Conditional_46_Template(
|
|
|
453
451
|
i0.ɵɵproperty("value", ctx_r1.getFormattedResultDetails())("readonly", true)("toolbar", ctx_r1.jsonToolbar)("lineWrapping", true);
|
|
454
452
|
} }
|
|
455
453
|
function MJTestRunFormComponentExtended_Conditional_114_Template(rf, ctx) { if (rf & 1) {
|
|
456
|
-
i0.ɵɵelementStart(0, "div", 56)(1, "div",
|
|
457
|
-
i0.ɵɵelement(4, "i",
|
|
454
|
+
i0.ɵɵelementStart(0, "div", 56)(1, "div", 131)(2, "div", 132)(3, "div", 133);
|
|
455
|
+
i0.ɵɵelement(4, "i", 134);
|
|
458
456
|
i0.ɵɵelementEnd();
|
|
459
|
-
i0.ɵɵelementStart(5, "div",
|
|
457
|
+
i0.ɵɵelementStart(5, "div", 135)(6, "div", 136);
|
|
460
458
|
i0.ɵɵtext(7, "Test Run ID");
|
|
461
459
|
i0.ɵɵelementEnd();
|
|
462
|
-
i0.ɵɵelementStart(8, "div",
|
|
460
|
+
i0.ɵɵelementStart(8, "div", 137);
|
|
463
461
|
i0.ɵɵtext(9);
|
|
464
462
|
i0.ɵɵelementEnd()()();
|
|
465
|
-
i0.ɵɵconditionalCreate(10, MJTestRunFormComponentExtended_Conditional_114_Conditional_10_Template, 9, 1, "div",
|
|
466
|
-
i0.ɵɵelementStart(11, "div",
|
|
467
|
-
i0.ɵɵelement(13, "i",
|
|
463
|
+
i0.ɵɵconditionalCreate(10, MJTestRunFormComponentExtended_Conditional_114_Conditional_10_Template, 9, 1, "div", 138);
|
|
464
|
+
i0.ɵɵelementStart(11, "div", 132)(12, "div", 133);
|
|
465
|
+
i0.ɵɵelement(13, "i", 139);
|
|
468
466
|
i0.ɵɵelementEnd();
|
|
469
|
-
i0.ɵɵelementStart(14, "div",
|
|
467
|
+
i0.ɵɵelementStart(14, "div", 135)(15, "div", 136);
|
|
470
468
|
i0.ɵɵtext(16, "Target Type");
|
|
471
469
|
i0.ɵɵelementEnd();
|
|
472
|
-
i0.ɵɵelementStart(17, "div",
|
|
470
|
+
i0.ɵɵelementStart(17, "div", 140);
|
|
473
471
|
i0.ɵɵtext(18);
|
|
474
472
|
i0.ɵɵelementEnd()()();
|
|
475
|
-
i0.ɵɵelementStart(19, "div",
|
|
476
|
-
i0.ɵɵelement(21, "i",
|
|
473
|
+
i0.ɵɵelementStart(19, "div", 132)(20, "div", 133);
|
|
474
|
+
i0.ɵɵelement(21, "i", 141);
|
|
477
475
|
i0.ɵɵelementEnd();
|
|
478
|
-
i0.ɵɵelementStart(22, "div",
|
|
476
|
+
i0.ɵɵelementStart(22, "div", 135)(23, "div", 136);
|
|
479
477
|
i0.ɵɵtext(24, "Started At");
|
|
480
478
|
i0.ɵɵelementEnd();
|
|
481
|
-
i0.ɵɵelementStart(25, "div",
|
|
479
|
+
i0.ɵɵelementStart(25, "div", 140);
|
|
482
480
|
i0.ɵɵtext(26);
|
|
483
481
|
i0.ɵɵpipe(27, "date");
|
|
484
482
|
i0.ɵɵelementEnd()()();
|
|
485
|
-
i0.ɵɵelementStart(28, "div",
|
|
486
|
-
i0.ɵɵelement(30, "i",
|
|
483
|
+
i0.ɵɵelementStart(28, "div", 132)(29, "div", 133);
|
|
484
|
+
i0.ɵɵelement(30, "i", 142);
|
|
487
485
|
i0.ɵɵelementEnd();
|
|
488
|
-
i0.ɵɵelementStart(31, "div",
|
|
486
|
+
i0.ɵɵelementStart(31, "div", 135)(32, "div", 136);
|
|
489
487
|
i0.ɵɵtext(33, "Completed At");
|
|
490
488
|
i0.ɵɵelementEnd();
|
|
491
|
-
i0.ɵɵelementStart(34, "div",
|
|
489
|
+
i0.ɵɵelementStart(34, "div", 140);
|
|
492
490
|
i0.ɵɵtext(35);
|
|
493
491
|
i0.ɵɵpipe(36, "date");
|
|
494
492
|
i0.ɵɵelementEnd()()();
|
|
495
|
-
i0.ɵɵelementStart(37, "div",
|
|
496
|
-
i0.ɵɵelement(39, "i",
|
|
493
|
+
i0.ɵɵelementStart(37, "div", 132)(38, "div", 133);
|
|
494
|
+
i0.ɵɵelement(39, "i", 143);
|
|
497
495
|
i0.ɵɵelementEnd();
|
|
498
|
-
i0.ɵɵelementStart(40, "div",
|
|
496
|
+
i0.ɵɵelementStart(40, "div", 135)(41, "div", 136);
|
|
499
497
|
i0.ɵɵtext(42, "Duration");
|
|
500
498
|
i0.ɵɵelementEnd();
|
|
501
|
-
i0.ɵɵelementStart(43, "div",
|
|
499
|
+
i0.ɵɵelementStart(43, "div", 140);
|
|
502
500
|
i0.ɵɵtext(44);
|
|
503
501
|
i0.ɵɵelementEnd()()()();
|
|
504
|
-
i0.ɵɵconditionalCreate(45, MJTestRunFormComponentExtended_Conditional_114_Conditional_45_Template, 7, 4, "div",
|
|
505
|
-
i0.ɵɵconditionalCreate(46, MJTestRunFormComponentExtended_Conditional_114_Conditional_46_Template, 7, 4, "div",
|
|
502
|
+
i0.ɵɵconditionalCreate(45, MJTestRunFormComponentExtended_Conditional_114_Conditional_45_Template, 7, 4, "div", 144);
|
|
503
|
+
i0.ɵɵconditionalCreate(46, MJTestRunFormComponentExtended_Conditional_114_Conditional_46_Template, 7, 4, "div", 145);
|
|
506
504
|
i0.ɵɵelementEnd();
|
|
507
505
|
} if (rf & 2) {
|
|
508
506
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -525,22 +523,22 @@ function MJTestRunFormComponentExtended_Conditional_114_Template(rf, ctx) { if (
|
|
|
525
523
|
i0.ɵɵconditional(ctx_r1.parsedData.resultDetails ? 46 : -1);
|
|
526
524
|
} }
|
|
527
525
|
function MJTestRunFormComponentExtended_Conditional_115_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
528
|
-
i0.ɵɵelementStart(0, "div",
|
|
529
|
-
i0.ɵɵelement(1, "div",
|
|
530
|
-
i0.ɵɵelementStart(2, "div",
|
|
531
|
-
i0.ɵɵelement(3, "div",
|
|
526
|
+
i0.ɵɵelementStart(0, "div", 159);
|
|
527
|
+
i0.ɵɵelement(1, "div", 160);
|
|
528
|
+
i0.ɵɵelementStart(2, "div", 161);
|
|
529
|
+
i0.ɵɵelement(3, "div", 162)(4, "div", 163);
|
|
532
530
|
i0.ɵɵelementEnd()();
|
|
533
531
|
} }
|
|
534
532
|
function MJTestRunFormComponentExtended_Conditional_115_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
535
|
-
i0.ɵɵelementStart(0, "div",
|
|
536
|
-
i0.ɵɵrepeaterCreate(2, MJTestRunFormComponentExtended_Conditional_115_Conditional_1_For_3_Template, 5, 0, "div",
|
|
533
|
+
i0.ɵɵelementStart(0, "div", 155)(1, "div", 158);
|
|
534
|
+
i0.ɵɵrepeaterCreate(2, MJTestRunFormComponentExtended_Conditional_115_Conditional_1_For_3_Template, 5, 0, "div", 159, i0.ɵɵrepeaterTrackByIdentity);
|
|
537
535
|
i0.ɵɵelementEnd()();
|
|
538
536
|
} if (rf & 2) {
|
|
539
537
|
i0.ɵɵadvance(2);
|
|
540
538
|
i0.ɵɵrepeater(i0.ɵɵpureFunction0(0, _c0));
|
|
541
539
|
} }
|
|
542
540
|
function MJTestRunFormComponentExtended_Conditional_115_Conditional_2_For_9_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
543
|
-
i0.ɵɵelementStart(0, "span",
|
|
541
|
+
i0.ɵɵelementStart(0, "span", 173);
|
|
544
542
|
i0.ɵɵelement(1, "i", 36);
|
|
545
543
|
i0.ɵɵtext(2);
|
|
546
544
|
i0.ɵɵpipe(3, "number");
|
|
@@ -552,20 +550,20 @@ function MJTestRunFormComponentExtended_Conditional_115_Conditional_2_For_9_Cond
|
|
|
552
550
|
} }
|
|
553
551
|
function MJTestRunFormComponentExtended_Conditional_115_Conditional_2_For_9_Template(rf, ctx) { if (rf & 1) {
|
|
554
552
|
const _r15 = i0.ɵɵgetCurrentView();
|
|
555
|
-
i0.ɵɵelementStart(0, "div",
|
|
553
|
+
i0.ɵɵelementStart(0, "div", 167);
|
|
556
554
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_115_Conditional_2_For_9_Template_div_click_0_listener() { const run_r16 = i0.ɵɵrestoreView(_r15).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openAIAgentRun(run_r16.ID)); });
|
|
557
|
-
i0.ɵɵelementStart(1, "div",
|
|
555
|
+
i0.ɵɵelementStart(1, "div", 168);
|
|
558
556
|
i0.ɵɵelement(2, "i", 47);
|
|
559
557
|
i0.ɵɵelementEnd();
|
|
560
|
-
i0.ɵɵelementStart(3, "div",
|
|
558
|
+
i0.ɵɵelementStart(3, "div", 169)(4, "div", 170);
|
|
561
559
|
i0.ɵɵtext(5);
|
|
562
560
|
i0.ɵɵelementEnd();
|
|
563
|
-
i0.ɵɵelementStart(6, "div",
|
|
561
|
+
i0.ɵɵelementStart(6, "div", 171)(7, "span", 172);
|
|
564
562
|
i0.ɵɵtext(8);
|
|
565
563
|
i0.ɵɵelementEnd();
|
|
566
|
-
i0.ɵɵconditionalCreate(9, MJTestRunFormComponentExtended_Conditional_115_Conditional_2_For_9_Conditional_9_Template, 4, 4, "span",
|
|
564
|
+
i0.ɵɵconditionalCreate(9, MJTestRunFormComponentExtended_Conditional_115_Conditional_2_For_9_Conditional_9_Template, 4, 4, "span", 173);
|
|
567
565
|
i0.ɵɵelementEnd()();
|
|
568
|
-
i0.ɵɵelement(10, "i",
|
|
566
|
+
i0.ɵɵelement(10, "i", 174);
|
|
569
567
|
i0.ɵɵelementEnd();
|
|
570
568
|
} if (rf & 2) {
|
|
571
569
|
const run_r16 = ctx.$implicit;
|
|
@@ -579,15 +577,15 @@ function MJTestRunFormComponentExtended_Conditional_115_Conditional_2_For_9_Temp
|
|
|
579
577
|
i0.ɵɵconditional(run_r16.TotalCost ? 9 : -1);
|
|
580
578
|
} }
|
|
581
579
|
function MJTestRunFormComponentExtended_Conditional_115_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
582
|
-
i0.ɵɵelementStart(0, "div",
|
|
580
|
+
i0.ɵɵelementStart(0, "div", 156)(1, "div", 110)(2, "h3");
|
|
583
581
|
i0.ɵɵelement(3, "i", 47);
|
|
584
582
|
i0.ɵɵtext(4, " AI Agent Runs");
|
|
585
583
|
i0.ɵɵelementEnd();
|
|
586
|
-
i0.ɵɵelementStart(5, "span",
|
|
584
|
+
i0.ɵɵelementStart(5, "span", 164);
|
|
587
585
|
i0.ɵɵtext(6);
|
|
588
586
|
i0.ɵɵelementEnd()();
|
|
589
|
-
i0.ɵɵelementStart(7, "div",
|
|
590
|
-
i0.ɵɵrepeaterCreate(8, MJTestRunFormComponentExtended_Conditional_115_Conditional_2_For_9_Template, 11, 5, "div",
|
|
587
|
+
i0.ɵɵelementStart(7, "div", 165);
|
|
588
|
+
i0.ɵɵrepeaterCreate(8, MJTestRunFormComponentExtended_Conditional_115_Conditional_2_For_9_Template, 11, 5, "div", 166, i0.ɵɵrepeaterTrackByIdentity);
|
|
591
589
|
i0.ɵɵelementEnd()();
|
|
592
590
|
} if (rf & 2) {
|
|
593
591
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -597,7 +595,7 @@ function MJTestRunFormComponentExtended_Conditional_115_Conditional_2_Template(r
|
|
|
597
595
|
i0.ɵɵrepeater(ctx_r1.aiAgentRuns);
|
|
598
596
|
} }
|
|
599
597
|
function MJTestRunFormComponentExtended_Conditional_115_Conditional_3_For_9_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
600
|
-
i0.ɵɵelementStart(0, "span",
|
|
598
|
+
i0.ɵɵelementStart(0, "span", 173);
|
|
601
599
|
i0.ɵɵelement(1, "i", 36);
|
|
602
600
|
i0.ɵɵtext(2);
|
|
603
601
|
i0.ɵɵpipe(3, "number");
|
|
@@ -609,18 +607,18 @@ function MJTestRunFormComponentExtended_Conditional_115_Conditional_3_For_9_Cond
|
|
|
609
607
|
} }
|
|
610
608
|
function MJTestRunFormComponentExtended_Conditional_115_Conditional_3_For_9_Template(rf, ctx) { if (rf & 1) {
|
|
611
609
|
const _r17 = i0.ɵɵgetCurrentView();
|
|
612
|
-
i0.ɵɵelementStart(0, "div",
|
|
610
|
+
i0.ɵɵelementStart(0, "div", 167);
|
|
613
611
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_115_Conditional_3_For_9_Template_div_click_0_listener() { const run_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openAIPromptRun(run_r18.ID)); });
|
|
614
|
-
i0.ɵɵelementStart(1, "div",
|
|
615
|
-
i0.ɵɵelement(2, "i",
|
|
612
|
+
i0.ɵɵelementStart(1, "div", 176);
|
|
613
|
+
i0.ɵɵelement(2, "i", 175);
|
|
616
614
|
i0.ɵɵelementEnd();
|
|
617
|
-
i0.ɵɵelementStart(3, "div",
|
|
615
|
+
i0.ɵɵelementStart(3, "div", 169)(4, "div", 170);
|
|
618
616
|
i0.ɵɵtext(5);
|
|
619
617
|
i0.ɵɵelementEnd();
|
|
620
|
-
i0.ɵɵelementStart(6, "div",
|
|
621
|
-
i0.ɵɵconditionalCreate(7, MJTestRunFormComponentExtended_Conditional_115_Conditional_3_For_9_Conditional_7_Template, 4, 4, "span",
|
|
618
|
+
i0.ɵɵelementStart(6, "div", 171);
|
|
619
|
+
i0.ɵɵconditionalCreate(7, MJTestRunFormComponentExtended_Conditional_115_Conditional_3_For_9_Conditional_7_Template, 4, 4, "span", 173);
|
|
622
620
|
i0.ɵɵelementEnd()();
|
|
623
|
-
i0.ɵɵelement(8, "i",
|
|
621
|
+
i0.ɵɵelement(8, "i", 174);
|
|
624
622
|
i0.ɵɵelementEnd();
|
|
625
623
|
} if (rf & 2) {
|
|
626
624
|
const run_r18 = ctx.$implicit;
|
|
@@ -630,15 +628,15 @@ function MJTestRunFormComponentExtended_Conditional_115_Conditional_3_For_9_Temp
|
|
|
630
628
|
i0.ɵɵconditional(run_r18.TotalCost ? 7 : -1);
|
|
631
629
|
} }
|
|
632
630
|
function MJTestRunFormComponentExtended_Conditional_115_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
633
|
-
i0.ɵɵelementStart(0, "div",
|
|
634
|
-
i0.ɵɵelement(3, "i",
|
|
631
|
+
i0.ɵɵelementStart(0, "div", 156)(1, "div", 110)(2, "h3");
|
|
632
|
+
i0.ɵɵelement(3, "i", 175);
|
|
635
633
|
i0.ɵɵtext(4, " AI Prompt Runs");
|
|
636
634
|
i0.ɵɵelementEnd();
|
|
637
|
-
i0.ɵɵelementStart(5, "span",
|
|
635
|
+
i0.ɵɵelementStart(5, "span", 164);
|
|
638
636
|
i0.ɵɵtext(6);
|
|
639
637
|
i0.ɵɵelementEnd()();
|
|
640
|
-
i0.ɵɵelementStart(7, "div",
|
|
641
|
-
i0.ɵɵrepeaterCreate(8, MJTestRunFormComponentExtended_Conditional_115_Conditional_3_For_9_Template, 9, 2, "div",
|
|
638
|
+
i0.ɵɵelementStart(7, "div", 165);
|
|
639
|
+
i0.ɵɵrepeaterCreate(8, MJTestRunFormComponentExtended_Conditional_115_Conditional_3_For_9_Template, 9, 2, "div", 166, i0.ɵɵrepeaterTrackByIdentity);
|
|
642
640
|
i0.ɵɵelementEnd()();
|
|
643
641
|
} if (rf & 2) {
|
|
644
642
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -648,22 +646,14 @@ function MJTestRunFormComponentExtended_Conditional_115_Conditional_3_Template(r
|
|
|
648
646
|
i0.ɵɵrepeater(ctx_r1.aiPromptRuns);
|
|
649
647
|
} }
|
|
650
648
|
function MJTestRunFormComponentExtended_Conditional_115_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
651
|
-
i0.ɵɵ
|
|
652
|
-
i0.ɵɵelement(2, "i", 47);
|
|
653
|
-
i0.ɵɵelementEnd();
|
|
654
|
-
i0.ɵɵelementStart(3, "h3");
|
|
655
|
-
i0.ɵɵtext(4, "No AI Runs");
|
|
656
|
-
i0.ɵɵelementEnd();
|
|
657
|
-
i0.ɵɵelementStart(5, "p");
|
|
658
|
-
i0.ɵɵtext(6, "This test execution didn't involve any AI agent or prompt runs.");
|
|
659
|
-
i0.ɵɵelementEnd()();
|
|
649
|
+
i0.ɵɵelement(0, "mj-empty-state", 157);
|
|
660
650
|
} }
|
|
661
651
|
function MJTestRunFormComponentExtended_Conditional_115_Template(rf, ctx) { if (rf & 1) {
|
|
662
652
|
i0.ɵɵelementStart(0, "div", 57);
|
|
663
|
-
i0.ɵɵconditionalCreate(1, MJTestRunFormComponentExtended_Conditional_115_Conditional_1_Template, 4, 1, "div",
|
|
664
|
-
i0.ɵɵconditionalCreate(2, MJTestRunFormComponentExtended_Conditional_115_Conditional_2_Template, 10, 1, "div",
|
|
665
|
-
i0.ɵɵconditionalCreate(3, MJTestRunFormComponentExtended_Conditional_115_Conditional_3_Template, 10, 1, "div",
|
|
666
|
-
i0.ɵɵconditionalCreate(4, MJTestRunFormComponentExtended_Conditional_115_Conditional_4_Template,
|
|
653
|
+
i0.ɵɵconditionalCreate(1, MJTestRunFormComponentExtended_Conditional_115_Conditional_1_Template, 4, 1, "div", 155);
|
|
654
|
+
i0.ɵɵconditionalCreate(2, MJTestRunFormComponentExtended_Conditional_115_Conditional_2_Template, 10, 1, "div", 156);
|
|
655
|
+
i0.ɵɵconditionalCreate(3, MJTestRunFormComponentExtended_Conditional_115_Conditional_3_Template, 10, 1, "div", 156);
|
|
656
|
+
i0.ɵɵconditionalCreate(4, MJTestRunFormComponentExtended_Conditional_115_Conditional_4_Template, 1, 0, "mj-empty-state", 157);
|
|
667
657
|
i0.ɵɵelementEnd();
|
|
668
658
|
} if (rf & 2) {
|
|
669
659
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -678,15 +668,15 @@ function MJTestRunFormComponentExtended_Conditional_115_Template(rf, ctx) { if (
|
|
|
678
668
|
i0.ɵɵconditional(ctx_r1.aiRunsLoaded && ctx_r1.aiAgentRuns.length === 0 && ctx_r1.aiPromptRuns.length === 0 ? 4 : -1);
|
|
679
669
|
} }
|
|
680
670
|
function MJTestRunFormComponentExtended_Conditional_116_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
681
|
-
i0.ɵɵelementStart(0, "div",
|
|
682
|
-
i0.ɵɵelement(1, "div",
|
|
683
|
-
i0.ɵɵelementStart(2, "div",
|
|
684
|
-
i0.ɵɵelement(3, "div",
|
|
671
|
+
i0.ɵɵelementStart(0, "div", 159);
|
|
672
|
+
i0.ɵɵelement(1, "div", 179);
|
|
673
|
+
i0.ɵɵelementStart(2, "div", 161);
|
|
674
|
+
i0.ɵɵelement(3, "div", 162)(4, "div", 163)(5, "div", 180);
|
|
685
675
|
i0.ɵɵelementEnd()();
|
|
686
676
|
} }
|
|
687
677
|
function MJTestRunFormComponentExtended_Conditional_116_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
688
|
-
i0.ɵɵelementStart(0, "div",
|
|
689
|
-
i0.ɵɵrepeaterCreate(2, MJTestRunFormComponentExtended_Conditional_116_Conditional_1_For_3_Template, 6, 0, "div",
|
|
678
|
+
i0.ɵɵelementStart(0, "div", 155)(1, "div", 158);
|
|
679
|
+
i0.ɵɵrepeaterCreate(2, MJTestRunFormComponentExtended_Conditional_116_Conditional_1_For_3_Template, 6, 0, "div", 159, i0.ɵɵrepeaterTrackByIdentity);
|
|
690
680
|
i0.ɵɵelementEnd()();
|
|
691
681
|
} if (rf & 2) {
|
|
692
682
|
i0.ɵɵadvance(2);
|
|
@@ -700,8 +690,8 @@ function MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_For_
|
|
|
700
690
|
i0.ɵɵclassProp("filled", s_r19 <= (feedback_r20.Rating || 0));
|
|
701
691
|
} }
|
|
702
692
|
function MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
703
|
-
i0.ɵɵelementStart(0, "div",
|
|
704
|
-
i0.ɵɵelement(2, "i",
|
|
693
|
+
i0.ɵɵelementStart(0, "div", 192)(1, "span", 194);
|
|
694
|
+
i0.ɵɵelement(2, "i", 125);
|
|
705
695
|
i0.ɵɵtext(3);
|
|
706
696
|
i0.ɵɵelementEnd()();
|
|
707
697
|
} if (rf & 2) {
|
|
@@ -714,7 +704,7 @@ function MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Cond
|
|
|
714
704
|
i0.ɵɵtextInterpolate1(" ", feedback_r20.IsCorrect ? "Marked Correct" : "Marked Incorrect", " ");
|
|
715
705
|
} }
|
|
716
706
|
function MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
717
|
-
i0.ɵɵelementStart(0, "div",
|
|
707
|
+
i0.ɵɵelementStart(0, "div", 193)(1, "p");
|
|
718
708
|
i0.ɵɵtext(2);
|
|
719
709
|
i0.ɵɵelementEnd()();
|
|
720
710
|
} if (rf & 2) {
|
|
@@ -723,23 +713,23 @@ function MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Cond
|
|
|
723
713
|
i0.ɵɵtextInterpolate(feedback_r20.CorrectionSummary);
|
|
724
714
|
} }
|
|
725
715
|
function MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
726
|
-
i0.ɵɵelementStart(0, "div",
|
|
727
|
-
i0.ɵɵelement(4, "i",
|
|
716
|
+
i0.ɵɵelementStart(0, "div", 181)(1, "div", 182)(2, "div", 183)(3, "div", 184);
|
|
717
|
+
i0.ɵɵelement(4, "i", 71);
|
|
728
718
|
i0.ɵɵelementEnd();
|
|
729
|
-
i0.ɵɵelementStart(5, "span",
|
|
719
|
+
i0.ɵɵelementStart(5, "span", 185);
|
|
730
720
|
i0.ɵɵtext(6);
|
|
731
721
|
i0.ɵɵelementEnd()();
|
|
732
|
-
i0.ɵɵelementStart(7, "div",
|
|
722
|
+
i0.ɵɵelementStart(7, "div", 186);
|
|
733
723
|
i0.ɵɵtext(8);
|
|
734
724
|
i0.ɵɵelementEnd()();
|
|
735
|
-
i0.ɵɵelementStart(9, "div",
|
|
736
|
-
i0.ɵɵrepeaterCreate(12, MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_For_13_Template, 1, 2, "i",
|
|
725
|
+
i0.ɵɵelementStart(9, "div", 187)(10, "div", 188)(11, "div", 189);
|
|
726
|
+
i0.ɵɵrepeaterCreate(12, MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_For_13_Template, 1, 2, "i", 190, i0.ɵɵrepeaterTrackByIdentity);
|
|
737
727
|
i0.ɵɵelementEnd();
|
|
738
|
-
i0.ɵɵelementStart(14, "span",
|
|
728
|
+
i0.ɵɵelementStart(14, "span", 191);
|
|
739
729
|
i0.ɵɵtext(15);
|
|
740
730
|
i0.ɵɵelementEnd()();
|
|
741
|
-
i0.ɵɵconditionalCreate(16, MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Conditional_16_Template, 4, 9, "div",
|
|
742
|
-
i0.ɵɵconditionalCreate(17, MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Conditional_17_Template, 3, 1, "div",
|
|
731
|
+
i0.ɵɵconditionalCreate(16, MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Conditional_16_Template, 4, 9, "div", 192);
|
|
732
|
+
i0.ɵɵconditionalCreate(17, MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Conditional_17_Template, 3, 1, "div", 193);
|
|
743
733
|
i0.ɵɵelementEnd()();
|
|
744
734
|
} if (rf & 2) {
|
|
745
735
|
const feedback_r20 = ctx.$implicit;
|
|
@@ -758,8 +748,8 @@ function MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Temp
|
|
|
758
748
|
i0.ɵɵconditional(feedback_r20.CorrectionSummary ? 17 : -1);
|
|
759
749
|
} }
|
|
760
750
|
function MJTestRunFormComponentExtended_Conditional_116_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
761
|
-
i0.ɵɵelementStart(0, "div",
|
|
762
|
-
i0.ɵɵrepeaterCreate(1, MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Template, 18, 6, "div",
|
|
751
|
+
i0.ɵɵelementStart(0, "div", 177);
|
|
752
|
+
i0.ɵɵrepeaterCreate(1, MJTestRunFormComponentExtended_Conditional_116_Conditional_2_For_2_Template, 18, 6, "div", 181, i0.ɵɵrepeaterTrackByIdentity);
|
|
763
753
|
i0.ɵɵelementEnd();
|
|
764
754
|
} if (rf & 2) {
|
|
765
755
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -767,21 +757,13 @@ function MJTestRunFormComponentExtended_Conditional_116_Conditional_2_Template(r
|
|
|
767
757
|
i0.ɵɵrepeater(ctx_r1.feedbacks);
|
|
768
758
|
} }
|
|
769
759
|
function MJTestRunFormComponentExtended_Conditional_116_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
770
|
-
i0.ɵɵ
|
|
771
|
-
i0.ɵɵelement(2, "i", 50);
|
|
772
|
-
i0.ɵɵelementEnd();
|
|
773
|
-
i0.ɵɵelementStart(3, "h3");
|
|
774
|
-
i0.ɵɵtext(4, "No Feedback Yet");
|
|
775
|
-
i0.ɵɵelementEnd();
|
|
776
|
-
i0.ɵɵelementStart(5, "p");
|
|
777
|
-
i0.ɵɵtext(6, "No one has reviewed this test run yet. Be the first to provide feedback!");
|
|
778
|
-
i0.ɵɵelementEnd()();
|
|
760
|
+
i0.ɵɵelement(0, "mj-empty-state", 178);
|
|
779
761
|
} }
|
|
780
762
|
function MJTestRunFormComponentExtended_Conditional_116_Template(rf, ctx) { if (rf & 1) {
|
|
781
763
|
i0.ɵɵelementStart(0, "div", 58);
|
|
782
|
-
i0.ɵɵconditionalCreate(1, MJTestRunFormComponentExtended_Conditional_116_Conditional_1_Template, 4, 1, "div",
|
|
783
|
-
i0.ɵɵconditionalCreate(2, MJTestRunFormComponentExtended_Conditional_116_Conditional_2_Template, 3, 0, "div",
|
|
784
|
-
i0.ɵɵconditionalCreate(3, MJTestRunFormComponentExtended_Conditional_116_Conditional_3_Template,
|
|
764
|
+
i0.ɵɵconditionalCreate(1, MJTestRunFormComponentExtended_Conditional_116_Conditional_1_Template, 4, 1, "div", 155);
|
|
765
|
+
i0.ɵɵconditionalCreate(2, MJTestRunFormComponentExtended_Conditional_116_Conditional_2_Template, 3, 0, "div", 177);
|
|
766
|
+
i0.ɵɵconditionalCreate(3, MJTestRunFormComponentExtended_Conditional_116_Conditional_3_Template, 1, 0, "mj-empty-state", 178);
|
|
785
767
|
i0.ɵɵelementEnd();
|
|
786
768
|
} if (rf & 2) {
|
|
787
769
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -795,7 +777,7 @@ function MJTestRunFormComponentExtended_Conditional_116_Template(rf, ctx) { if (
|
|
|
795
777
|
} }
|
|
796
778
|
function MJTestRunFormComponentExtended_Conditional_117_Template(rf, ctx) { if (rf & 1) {
|
|
797
779
|
i0.ɵɵelementStart(0, "div", 59);
|
|
798
|
-
i0.ɵɵelement(1, "mj-execution-context",
|
|
780
|
+
i0.ɵɵelement(1, "mj-execution-context", 195);
|
|
799
781
|
i0.ɵɵelementEnd();
|
|
800
782
|
} if (rf & 2) {
|
|
801
783
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -805,19 +787,19 @@ function MJTestRunFormComponentExtended_Conditional_117_Template(rf, ctx) { if (
|
|
|
805
787
|
} }
|
|
806
788
|
function MJTestRunFormComponentExtended_Conditional_118_Template(rf, ctx) { if (rf & 1) {
|
|
807
789
|
const _r21 = i0.ɵɵgetCurrentView();
|
|
808
|
-
i0.ɵɵelementStart(0, "div", 60)(1, "div",
|
|
809
|
-
i0.ɵɵelement(3, "i",
|
|
790
|
+
i0.ɵɵelementStart(0, "div", 60)(1, "div", 196)(2, "div", 197);
|
|
791
|
+
i0.ɵɵelement(3, "i", 98);
|
|
810
792
|
i0.ɵɵelementStart(4, "h3");
|
|
811
793
|
i0.ɵɵtext(5, "Execution Log");
|
|
812
794
|
i0.ɵɵelementEnd()();
|
|
813
|
-
i0.ɵɵelementStart(6, "div",
|
|
795
|
+
i0.ɵɵelementStart(6, "div", 198)(7, "button", 94);
|
|
814
796
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Conditional_118_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.copyLogToClipboard()); });
|
|
815
|
-
i0.ɵɵelement(8, "i",
|
|
797
|
+
i0.ɵɵelement(8, "i", 199);
|
|
816
798
|
i0.ɵɵelementStart(9, "span", 21);
|
|
817
799
|
i0.ɵɵtext(10, "Copy");
|
|
818
800
|
i0.ɵɵelementEnd()()()();
|
|
819
|
-
i0.ɵɵelementStart(11, "div",
|
|
820
|
-
i0.ɵɵelement(12, "mj-code-editor",
|
|
801
|
+
i0.ɵɵelementStart(11, "div", 200);
|
|
802
|
+
i0.ɵɵelement(12, "mj-code-editor", 152);
|
|
821
803
|
i0.ɵɵelementEnd()();
|
|
822
804
|
} if (rf & 2) {
|
|
823
805
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -1322,9 +1304,9 @@ let MJTestRunFormComponentExtended = class MJTestRunFormComponentExtended extend
|
|
|
1322
1304
|
static { this.ɵfac = /*@__PURE__*/ (() => { let ɵMJTestRunFormComponentExtended_BaseFactory; return function MJTestRunFormComponentExtended_Factory(__ngFactoryType__) { return (ɵMJTestRunFormComponentExtended_BaseFactory || (ɵMJTestRunFormComponentExtended_BaseFactory = i0.ɵɵgetInheritedFactory(MJTestRunFormComponentExtended)))(__ngFactoryType__ || MJTestRunFormComponentExtended); }; })(); }
|
|
1323
1305
|
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJTestRunFormComponentExtended, selectors: [["mj-test-run-form"]], hostBindings: function MJTestRunFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
|
|
1324
1306
|
i0.ɵɵlistener("keydown", function MJTestRunFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, i0.ɵɵresolveDocument);
|
|
1325
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 137, vars: 59, consts: [[1, "test-run-form"], [
|
|
1307
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 137, vars: 59, consts: [[1, "test-run-form"], ["Variant", "error"], [1, "test-run-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "header-content"], [1, "header-left"], [1, "status-indicator"], [1, "fas", 3, "ngClass"], [1, "test-run-info"], [1, "run-id"], [1, "test-run-meta"], [1, "status-badge"], [1, "meta-item"], [1, "header-actions"], ["mjButton", "", "title", "Re-run this test (Cmd+Shift+R)", 3, "click", "disabled"], [1, "fas", "fa-redo"], [1, "btn-text"], ["mjButton", "", "title", "Refresh (Cmd+R)", 3, "click", "disabled"], [1, "fas", "fa-sync-alt"], [1, "metrics-bar"], [1, "metric-card"], [1, "metric-icon"], [1, "fas", "fa-clock"], [1, "metric-content"], [1, "metric-label"], [1, "metric-value"], [1, "metric-detail"], [1, "fas", "fa-stopwatch"], [1, "fas", "fa-star"], [1, "metric-progress"], [1, "fas", "fa-check-double"], [1, "fas", "fa-dollar-sign"], [1, "secondary-info"], [1, "tags-bar"], [1, "tags-editor-panel"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", "title", "Press 1", 1, "tab", 3, "click"], [1, "fas", "fa-chart-pie"], ["role", "tab", "title", "Press 2", 1, "tab", 3, "click"], [1, "fas", "fa-info-circle"], ["role", "tab", "title", "Press 3", 1, "tab", 3, "click"], [1, "fas", "fa-robot"], [1, "tab-badge"], ["role", "tab", "title", "Press 4", 1, "tab", 3, "click"], [1, "fas", "fa-comments"], ["role", "tab", "title", "Press 5", 1, "tab", 3, "click"], [1, "fas", "fa-microchip"], ["role", "tab", "title", "Press 6", 1, "tab", 3, "active"], [1, "tab-content"], [1, "overview-tab"], [1, "details-tab"], [1, "ai-runs-tab"], [1, "feedback-tab"], [1, "execution-tab"], [1, "log-tab"], ["title", "Keyboard Shortcuts", 1, "shortcuts-hint"], [1, "fas", "fa-keyboard"], [1, "shortcuts-popup"], ["actions", "", "mjButton", "", "variant", "secondary", "size", "sm", 3, "click"], [1, "fas", "fa-flask"], [1, "fas", "fa-sync-alt", "fa-spin"], [1, "progress-bar"], [1, "info-chip"], [1, "info-chip", "clickable"], [3, "entityName", "recordId"], [1, "fas", "fa-user"], [1, "info-chip", "clickable", 3, "click"], [1, "fas", "fa-layer-group"], [1, "tags-bar-content"], [1, "tags-bar-label"], [1, "fas", "fa-tags"], [1, "tags-bar-chips"], [1, "tags-bar-empty"], ["title", "Edit tags", 1, "tags-bar-edit", 3, "click"], [1, "fas", "fa-plus"], [1, "tag-inline"], [1, "tags-editor-header"], [1, "tags-editor-title"], [1, "tags-editor-body"], [1, "tags-editor-chips"], [1, "tag-editable"], [1, "tags-empty-hint"], [1, "tags-editor-input"], ["type", "text", "placeholder", "Type a tag and press Enter...", 1, "tag-text-input", 3, "ngModelChange", "keyup.enter", "ngModel"], ["mjButton", "", "variant", "flat", 3, "click", "disabled"], [1, "tags-editor-footer"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fas", "fa-spinner", "fa-spin"], ["mjButton", "", "variant", "flat", 3, "click"], ["title", "Remove tag", 1, "tag-remove-btn", 3, "click"], [1, "fas", "fa-times"], ["role", "tab", "title", "Press 6", 1, "tab", 3, "click"], [1, "fas", "fa-terminal"], [1, "result-hero"], [1, "result-icon-wrapper"], [1, "result-icon"], [1, "result-pulse"], [1, "result-text"], [1, "result-details"], [1, "result-score"], [1, "result-divider"], [1, "result-checks"], [1, "check-results"], [1, "comparison-section"], [1, "section-header"], [1, "fas", "fa-exchange-alt"], [1, "comparison-tabs"], [1, "comparison-tab", 3, "click"], [1, "fas", "fa-sign-in-alt"], [1, "fas", "fa-bullseye"], [1, "fas", "fa-check-square"], [1, "comparison-content"], ["language", "json", 3, "value", "readonly", "toolbar", "lineWrapping"], [1, "fas", "fa-tasks"], [1, "check-summary"], [1, "check-list"], [1, "check-item", 3, "passed", "failed", "animation-delay"], [1, "check-item"], [1, "check-status"], [1, "fas"], [1, "check-content"], [1, "check-name"], [1, "check-message"], [1, "check-weight"], [1, "weight-label"], [1, "details-grid"], [1, "detail-card"], [1, "detail-icon"], [1, "fas", "fa-fingerprint"], [1, "detail-content"], [1, "detail-label"], [1, "detail-value", "monospace"], [1, "detail-card", "clickable"], [1, "fas", "fa-tag"], [1, "detail-value"], [1, "fas", "fa-play-circle"], [1, "fas", "fa-stop-circle"], [1, "fas", "fa-hourglass-half"], [1, "error-section"], [1, "result-details-section"], [1, "detail-card", "clickable", 3, "click"], [1, "detail-value", "link"], [1, "fas", "fa-external-link-alt", "detail-action"], [1, "section-header", "error"], [1, "fas", "fa-exclamation-triangle"], [1, "error-content"], [3, "value", "readonly", "toolbar", "lineWrapping"], [1, "fas", "fa-file-code"], [1, "result-details-content"], [1, "loading-state"], [1, "ai-section"], ["Icon", "fa-solid fa-robot", "Title", "No AI Runs", "Message", "This test execution didn't involve any AI agent or prompt runs."], [1, "skeleton-list"], [1, "skeleton-card"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], [1, "count-badge"], [1, "ai-run-list"], [1, "ai-run-card"], [1, "ai-run-card", 3, "click"], [1, "ai-run-icon", "agent"], [1, "ai-run-content"], [1, "ai-run-name"], [1, "ai-run-meta"], [1, "status-chip"], [1, "cost-chip"], [1, "fas", "fa-chevron-right", "ai-run-arrow"], [1, "fas", "fa-comment-dots"], [1, "ai-run-icon", "prompt"], [1, "feedback-list"], ["Icon", "fa-solid fa-comments", "Title", "No Feedback Yet", "Message", "No one has reviewed this test run yet. Be the first to provide feedback!"], [1, "skeleton-avatar"], [1, "skeleton-line", "medium"], [1, "feedback-item"], [1, "feedback-header"], [1, "feedback-user"], [1, "user-avatar"], [1, "user-name"], [1, "feedback-date"], [1, "feedback-body"], [1, "feedback-rating"], [1, "rating-stars"], [1, "fas", "fa-star", 3, "filled"], [1, "rating-value"], [1, "feedback-verdict"], [1, "feedback-comments"], [1, "verdict-badge"], [3, "machineName", "machineId", "runByUserName", "runByUserEmail", "runContextDetailsJson"], [1, "log-header"], [1, "log-title"], [1, "log-actions"], [1, "fas", "fa-copy"], [1, "log-container"]], template: function MJTestRunFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
|
|
1326
1308
|
i0.ɵɵelementStart(0, "div", 0);
|
|
1327
|
-
i0.ɵɵconditionalCreate(1, MJTestRunFormComponentExtended_Conditional_1_Template,
|
|
1309
|
+
i0.ɵɵconditionalCreate(1, MJTestRunFormComponentExtended_Conditional_1_Template, 6, 1, "mj-alert", 1);
|
|
1328
1310
|
i0.ɵɵelementStart(2, "div", 2)(3, "nav", 3)(4, "ol")(5, "li")(6, "a", 4);
|
|
1329
1311
|
i0.ɵɵlistener("click", function MJTestRunFormComponentExtended_Template_a_click_6_listener() { return ctx.navigateToTestingDashboard(); });
|
|
1330
1312
|
i0.ɵɵelement(7, "i", 5);
|
|
@@ -1569,7 +1551,7 @@ let MJTestRunFormComponentExtended = class MJTestRunFormComponentExtended extend
|
|
|
1569
1551
|
i0.ɵɵconditional(ctx.activeTab === "execution" ? 117 : -1);
|
|
1570
1552
|
i0.ɵɵadvance();
|
|
1571
1553
|
i0.ɵɵconditional(ctx.activeTab === "log" ? 118 : -1);
|
|
1572
|
-
} }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJButtonDirective, i4.CodeEditorComponent, i5.ExecutionContextComponent, i6.EntityLinkPillComponent, i1.DecimalPipe, i1.DatePipe], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-primary-dark: var(--mj-brand-primary-hover);\n --test-success: var(--mj-status-success);\n --test-success-light: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n --test-error: var(--mj-status-error);\n --test-error-light: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n --test-warning: var(--mj-status-warning);\n --test-warning-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-timeout: var(--mj-status-warning);\n --test-timeout-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-running: var(--mj-brand-primary);\n --test-pending: var(--mj-brand-primary);\n --test-skipped: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-muted);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n\n\n.test-run-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n\n\n\n\n.error-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 12px 20px;\n background: var(--test-error);\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n.error-banner[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n}\n\n.error-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.retry-btn[_ngcontent-%COMP%] {\n background: rgba(255, 255, 255, 0.2);\n border: 1px solid rgba(255, 255, 255, 0.3);\n color: var(--mj-text-inverse);\n padding: 6px 12px;\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.retry-btn[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n transform: translateY(-100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n\n\n\n\n.test-run-header[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n position: relative;\n}\n\n\n\n.breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n flex-wrap: wrap;\n}\n\n.breadcrumb[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text[_ngcontent-%COMP%] {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n\n\n.status-indicator[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.status-indicator[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.test-run-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] .run-id[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.test-run-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n\n\n.meta-item[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n}\n\n.meta-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n white-space: nowrap;\n}\n\n.btn-text[_ngcontent-%COMP%] {\n margin-left: 6px;\n}\n\n\n\n\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.metric-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n transition: var(--test-transition);\n}\n\n.metric-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-sm);\n color: var(--test-primary);\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.metric-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.metric-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.metric-detail[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 2px;\n}\n\n\n\n.metric-progress[_ngcontent-%COMP%] {\n margin-top: 6px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.progress-bar[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n\n\n.secondary-info[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding-top: 16px;\n border-top: 1px solid var(--test-border);\n flex-wrap: wrap;\n}\n\n.info-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--test-text-secondary);\n padding: 6px 12px;\n background: var(--test-bg);\n border-radius: 20px;\n transition: var(--test-transition);\n}\n\n.info-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.info-chip.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.info-chip.clickable[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n}\n\n\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.shortcut-hint[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n\n.result-hero[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 32px;\n text-align: center;\n border: 2px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.result-hero.passed[_ngcontent-%COMP%] {\n background: var(--test-success-light);\n border-color: var(--test-success);\n}\n\n.result-hero.failed[_ngcontent-%COMP%] {\n background: var(--test-error-light);\n border-color: var(--test-error);\n}\n\n.result-hero.error[_ngcontent-%COMP%] {\n background: var(--test-warning-light);\n border-color: var(--test-warning);\n}\n\n.result-hero.timeout[_ngcontent-%COMP%] {\n background: var(--test-timeout-light);\n border-color: var(--test-timeout);\n}\n\n.result-hero.running[_ngcontent-%COMP%], \n.result-hero.pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--test-primary-light);\n}\n\n.result-icon-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: inline-block;\n margin-bottom: 16px;\n}\n\n.result-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: 50%;\n font-size: 40px;\n margin: 0 auto;\n box-shadow: var(--test-shadow-md);\n}\n\n.result-hero.passed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-success); }\n.result-hero.failed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-error); }\n.result-hero.error[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-warning); }\n.result-hero.timeout[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-timeout); }\n.result-hero.running[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-hero.pending[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-primary); }\n\n.result-pulse[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 100px;\n height: 100px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.5; }\n 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0; }\n}\n\n.result-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: clamp(24px, 5vw, 32px);\n font-weight: 800;\n color: var(--test-text);\n}\n\n.result-details[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.result-score[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.result-divider[_ngcontent-%COMP%] {\n color: var(--test-border);\n}\n\n.result-checks[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--test-text-muted);\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n gap: 12px;\n}\n\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.section-header.error[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n.check-summary[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n\n\n.check-results[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.check-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.check-item[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n transition: var(--test-transition);\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out backwards;\n}\n\n.check-item[_ngcontent-%COMP%]:hover {\n transform: translateX(4px);\n}\n\n.check-item.passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-success) 40%, var(--mj-bg-surface));\n}\n\n.check-item.failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-bg-surface));\n}\n\n.check-status[_ngcontent-%COMP%] {\n font-size: 20px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.check-item.passed[_ngcontent-%COMP%] .check-status[_ngcontent-%COMP%] { color: var(--test-success); }\n.check-item.failed[_ngcontent-%COMP%] .check-status[_ngcontent-%COMP%] { color: var(--test-error); }\n\n.check-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.check-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.check-message[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--test-text-secondary);\n line-height: 1.5;\n word-wrap: break-word;\n}\n\n.check-weight[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n flex-shrink: 0;\n text-align: right;\n}\n\n.weight-label[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n\n.comparison-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.comparison-tab[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 16px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.comparison-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: var(--mj-bg-overlay);\n}\n\n.comparison-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-content[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n\n\n\n\n.details-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.detail-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n transition: var(--test-transition);\n}\n\n.detail-card.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.detail-card.clickable[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.detail-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.detail-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n.detail-value.monospace[_ngcontent-%COMP%] {\n font-family: 'SF Mono', Monaco, 'Courier New', monospace;\n font-size: 12px;\n}\n\n.detail-value.link[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.detail-action[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 12px;\n transition: var(--test-transition);\n}\n\n.detail-card.clickable[_ngcontent-%COMP%]:hover .detail-action[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n.error-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.error-content[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-bg-surface));\n}\n\n\n\n.result-details-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.result-details-content[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n\n\n\n\n.ai-runs-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.ai-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.count-badge[_ngcontent-%COMP%] {\n background: var(--test-bg);\n color: var(--test-text-secondary);\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.ai-run-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.ai-run-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.ai-run-card[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-primary);\n color: var(--mj-text-inverse);\n border-radius: var(--test-radius-md);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon.agent[_ngcontent-%COMP%] {\n background: var(--test-primary);\n}\n\n.ai-run-icon.prompt[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.ai-run-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.ai-run-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ai-run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.status-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.complete[_ngcontent-%COMP%], \n.status-chip.completed[_ngcontent-%COMP%], \n.status-chip.passed[_ngcontent-%COMP%] {\n background: var(--test-success-light);\n color: var(--mj-status-success);\n}\n\n.status-chip.failed[_ngcontent-%COMP%], \n.status-chip.error[_ngcontent-%COMP%] {\n background: var(--test-error-light);\n color: var(--mj-status-error);\n}\n\n.status-chip.running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n}\n\n.cost-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n color: var(--test-text-muted);\n}\n\n.ai-run-arrow[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.ai-run-card[_ngcontent-%COMP%]:hover .ai-run-arrow[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n\n\n.feedback-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.feedback-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-item[_ngcontent-%COMP%] {\n padding: 20px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.feedback-item[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary-light);\n}\n\n.feedback-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.feedback-user[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.user-avatar[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-primary);\n font-size: 14px;\n}\n\n.user-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-date[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.feedback-body[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.feedback-rating[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.rating-stars[_ngcontent-%COMP%] {\n display: flex;\n gap: 2px;\n}\n\n.rating-stars[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-border);\n}\n\n.rating-stars[_ngcontent-%COMP%] i.filled[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.rating-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-verdict[_ngcontent-%COMP%] {\n display: flex;\n}\n\n.verdict-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.verdict-badge.correct[_ngcontent-%COMP%] {\n background: var(--test-success-light);\n color: var(--mj-status-success);\n}\n\n.verdict-badge.incorrect[_ngcontent-%COMP%] {\n background: var(--test-error-light);\n color: var(--mj-status-error);\n}\n\n.feedback-comments[_ngcontent-%COMP%] {\n padding: 14px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n border-left: 3px solid var(--test-primary);\n}\n\n.feedback-comments[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.6;\n color: var(--test-text);\n}\n\n\n\n\n\n.log-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0;\n height: 100%;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.log-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: var(--test-surface);\n padding: 16px 20px;\n border-radius: var(--test-radius-lg) var(--test-radius-lg) 0 0;\n border: 1px solid var(--test-border);\n border-bottom: none;\n}\n\n.log-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.log-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-size: 16px;\n}\n\n.log-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.log-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.log-container[_ngcontent-%COMP%] {\n flex: 1;\n border-radius: 0 0 var(--test-radius-lg) var(--test-radius-lg);\n overflow: hidden;\n min-height: 300px;\n border: 1px solid var(--test-border);\n border-top: none;\n}\n\n\n\n\n\n.loading-state[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.skeleton-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon[_ngcontent-%COMP%], \n.skeleton-avatar[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-avatar[_ngcontent-%COMP%] {\n border-radius: 50%;\n}\n\n.skeleton-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line[_ngcontent-%COMP%] {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] { width: 70%; }\n.skeleton-line.medium[_ngcontent-%COMP%] { width: 55%; }\n.skeleton-line.narrow[_ngcontent-%COMP%] { width: 40%; }\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n\n\n\n\n.shortcuts-hint[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 100;\n}\n\n.shortcuts-hint[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n cursor: pointer;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.shortcuts-hint[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-color: var(--test-primary-light);\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] {\n display: none;\n position: absolute;\n bottom: 50px;\n right: 0;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 16px;\n box-shadow: var(--test-shadow-lg);\n min-width: 200px;\n}\n\n.shortcuts-hint[_ngcontent-%COMP%]:hover .shortcuts-popup[_ngcontent-%COMP%] {\n display: block;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-out;\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 6px 0;\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .details-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .shortcuts-hint[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .test-run-form[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n }\n\n .test-run-header[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n }\n\n .breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .status-indicator[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .test-run-meta[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .status-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 12px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .shortcut-hint[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 24px 20px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n font-size: 32px;\n }\n\n .result-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 24px;\n }\n\n .result-score[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .check-results[_ngcontent-%COMP%], \n .comparison-section[_ngcontent-%COMP%], \n .ai-section[_ngcontent-%COMP%], \n .feedback-item[_ngcontent-%COMP%] {\n padding: 18px;\n }\n\n .check-item[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .comparison-tabs[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 4px;\n }\n\n .comparison-tab[_ngcontent-%COMP%] {\n text-align: center;\n }\n\n .details-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .detail-card[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .ai-run-card[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .ai-run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .ai-run-meta[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 4px;\n }\n\n .feedback-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .log-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n\n .log-actions[_ngcontent-%COMP%] {\n justify-content: stretch;\n }\n\n .log-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 40px 20px;\n }\n\n .empty-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n }\n}\n\n\n\n\n\n@media (max-width: 480px) {\n .test-run-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n gap: 12px;\n }\n\n .status-indicator[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 10px;\n flex-direction: column;\n text-align: center;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n }\n\n .metric-label[_ngcontent-%COMP%] {\n font-size: 9px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 8px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 20px 16px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n font-size: 28px;\n }\n\n .result-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .result-score[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .result-checks[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .check-item[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 8px;\n }\n\n .check-weight[_ngcontent-%COMP%] {\n text-align: left;\n }\n}\n\n\n\n\n\n@media (hover: none) and (pointer: coarse) {\n .tab[_ngcontent-%COMP%], \n .comparison-tab[_ngcontent-%COMP%], \n .ai-run-card[_ngcontent-%COMP%], \n .check-item[_ngcontent-%COMP%], \n .feedback-item[_ngcontent-%COMP%], \n .detail-card.clickable[_ngcontent-%COMP%] {\n -webkit-tap-highlight-color: transparent;\n }\n\n .ai-run-card[_ngcontent-%COMP%]:active, \n .detail-card.clickable[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n \n\n .tab[_ngcontent-%COMP%] {\n min-height: 48px;\n }\n\n .ai-run-card[_ngcontent-%COMP%], \n .detail-card[_ngcontent-%COMP%] {\n min-height: 64px;\n }\n}\n\n\n\n\n\n@media (prefers-contrast: high) {\n .status-badge[_ngcontent-%COMP%] {\n border: 2px solid currentColor;\n }\n\n .check-item[_ngcontent-%COMP%] {\n border-width: 2px;\n }\n\n .tab.active[_ngcontent-%COMP%] {\n border-bottom-width: 4px;\n }\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon[_ngcontent-%COMP%], \n .skeleton-avatar[_ngcontent-%COMP%], \n .skeleton-line[_ngcontent-%COMP%] {\n animation: none;\n background: var(--mj-border-default);\n }\n\n .result-pulse[_ngcontent-%COMP%] {\n animation: none;\n display: none;\n }\n}\n\n\n\n\n\n@media print {\n .test-run-form[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n height: auto;\n }\n\n .header-actions[_ngcontent-%COMP%], \n .tabs-container[_ngcontent-%COMP%], \n .shortcuts-hint[_ngcontent-%COMP%], \n .log-actions[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n overflow: visible;\n padding: 0;\n }\n\n .result-hero[_ngcontent-%COMP%], \n .check-results[_ngcontent-%COMP%], \n .details-grid[_ngcontent-%COMP%], \n .ai-section[_ngcontent-%COMP%], \n .feedback-item[_ngcontent-%COMP%] {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid var(--mj-border-default);\n }\n\n .comparison-content[_ngcontent-%COMP%], \n .log-container[_ngcontent-%COMP%] {\n max-height: none;\n overflow: visible;\n }\n}\n\n\n\n\n\n.tags-bar[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 8px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n border-radius: 8px;\n max-width: 600px;\n}\n\n.tags-bar-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.tags-bar-label[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-size: 14px;\n}\n\n.tags-bar-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n opacity: 0.6;\n}\n\n.tags-bar-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1;\n}\n\n.tag-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.01em;\n}\n\n.tags-bar-empty[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n opacity: 0.7;\n flex: 1;\n}\n\n.tags-bar-edit[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: transparent;\n border: 1px dashed var(--test-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--test-text-secondary);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n\n\n.tags-editor-panel[_ngcontent-%COMP%] {\n margin-top: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n border-radius: var(--test-radius-md);\n overflow: hidden;\n box-shadow: var(--mj-shadow-md);\n max-width: 600px;\n}\n\n.tags-editor-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.tags-editor-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tags-editor-body[_ngcontent-%COMP%] {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.tags-editor-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.tag-editable[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n color: var(--test-primary);\n border-radius: 14px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n background: transparent;\n border: none;\n color: var(--test-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--test-transition);\n}\n\n.tag-remove-btn[_ngcontent-%COMP%]:hover {\n opacity: 1;\n background: var(--test-error-light);\n color: var(--test-error);\n}\n\n.tags-empty-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-style: italic;\n padding: 4px 0;\n}\n\n.tags-editor-input[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.tag-text-input[_ngcontent-%COMP%] {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--test-bg);\n}\n\n.tag-text-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--test-primary);\n background: var(--test-surface);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.tag-text-input[_ngcontent-%COMP%]::placeholder {\n color: var(--test-text-secondary);\n opacity: 0.6;\n}\n\n.tags-editor-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 8px;\n padding: 12px 16px;\n background: var(--test-bg);\n border-top: 1px solid var(--test-border);\n}\n\n\n\n@media (max-width: 768px) {\n .tags-bar[_ngcontent-%COMP%] {\n padding: 8px 12px;\n }\n\n .tags-bar-content[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .tag-inline[_ngcontent-%COMP%] {\n padding: 3px 8px;\n font-size: 10px;\n }\n\n .tags-editor-panel[_ngcontent-%COMP%] {\n margin-top: 12px;\n }\n\n .tags-editor-body[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .tags-editor-footer[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n}"], changeDetection: 0 }); }
|
|
1554
|
+
} }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJEmptyStateComponent, i3.MJAlertComponent, i3.MJButtonDirective, i4.CodeEditorComponent, i5.ExecutionContextComponent, i6.EntityLinkPillComponent, i1.DecimalPipe, i1.DatePipe], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-primary-dark: var(--mj-brand-primary-hover);\n --test-success: var(--mj-status-success);\n --test-success-light: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n --test-error: var(--mj-status-error);\n --test-error-light: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n --test-warning: var(--mj-status-warning);\n --test-warning-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-timeout: var(--mj-status-warning);\n --test-timeout-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-running: var(--mj-brand-primary);\n --test-pending: var(--mj-brand-primary);\n --test-skipped: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-muted);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n\n\n.test-run-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n transform: translateY(-100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n\n\n\n\n.test-run-header[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n position: relative;\n}\n\n\n\n.breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n flex-wrap: wrap;\n}\n\n.breadcrumb[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text[_ngcontent-%COMP%] {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n\n\n.status-indicator[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.status-indicator[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.test-run-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] .run-id[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.test-run-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n\n\n.meta-item[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n}\n\n.meta-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n white-space: nowrap;\n}\n\n.btn-text[_ngcontent-%COMP%] {\n margin-left: 6px;\n}\n\n\n\n\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.metric-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n transition: var(--test-transition);\n}\n\n.metric-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-sm);\n color: var(--test-primary);\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.metric-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.metric-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.metric-detail[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 2px;\n}\n\n\n\n.metric-progress[_ngcontent-%COMP%] {\n margin-top: 6px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.progress-bar[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n\n\n.secondary-info[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding-top: 16px;\n border-top: 1px solid var(--test-border);\n flex-wrap: wrap;\n}\n\n.info-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--test-text-secondary);\n padding: 6px 12px;\n background: var(--test-bg);\n border-radius: 20px;\n transition: var(--test-transition);\n}\n\n.info-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.info-chip.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.info-chip.clickable[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n}\n\n\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.shortcut-hint[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n\n.result-hero[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 32px;\n text-align: center;\n border: 2px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.result-hero.passed[_ngcontent-%COMP%] {\n background: var(--test-success-light);\n border-color: var(--test-success);\n}\n\n.result-hero.failed[_ngcontent-%COMP%] {\n background: var(--test-error-light);\n border-color: var(--test-error);\n}\n\n.result-hero.error[_ngcontent-%COMP%] {\n background: var(--test-warning-light);\n border-color: var(--test-warning);\n}\n\n.result-hero.timeout[_ngcontent-%COMP%] {\n background: var(--test-timeout-light);\n border-color: var(--test-timeout);\n}\n\n.result-hero.running[_ngcontent-%COMP%], \n.result-hero.pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--test-primary-light);\n}\n\n.result-icon-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: inline-block;\n margin-bottom: 16px;\n}\n\n.result-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: 50%;\n font-size: 40px;\n margin: 0 auto;\n box-shadow: var(--test-shadow-md);\n}\n\n.result-hero.passed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-success); }\n.result-hero.failed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-error); }\n.result-hero.error[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-warning); }\n.result-hero.timeout[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-timeout); }\n.result-hero.running[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-hero.pending[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-primary); }\n\n.result-pulse[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 100px;\n height: 100px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.5; }\n 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0; }\n}\n\n.result-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: clamp(24px, 5vw, 32px);\n font-weight: 800;\n color: var(--test-text);\n}\n\n.result-details[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.result-score[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.result-divider[_ngcontent-%COMP%] {\n color: var(--test-border);\n}\n\n.result-checks[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--test-text-muted);\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n gap: 12px;\n}\n\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.section-header.error[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n.check-summary[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n\n\n.check-results[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.check-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.check-item[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n transition: var(--test-transition);\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out backwards;\n}\n\n.check-item[_ngcontent-%COMP%]:hover {\n transform: translateX(4px);\n}\n\n.check-item.passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-success) 40%, var(--mj-bg-surface));\n}\n\n.check-item.failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-bg-surface));\n}\n\n.check-status[_ngcontent-%COMP%] {\n font-size: 20px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.check-item.passed[_ngcontent-%COMP%] .check-status[_ngcontent-%COMP%] { color: var(--test-success); }\n.check-item.failed[_ngcontent-%COMP%] .check-status[_ngcontent-%COMP%] { color: var(--test-error); }\n\n.check-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.check-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.check-message[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--test-text-secondary);\n line-height: 1.5;\n word-wrap: break-word;\n}\n\n.check-weight[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n flex-shrink: 0;\n text-align: right;\n}\n\n.weight-label[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n\n.comparison-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.comparison-tab[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 16px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.comparison-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: var(--mj-bg-overlay);\n}\n\n.comparison-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-content[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n\n\n\n\n.details-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.detail-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n transition: var(--test-transition);\n}\n\n.detail-card.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.detail-card.clickable[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.detail-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.detail-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n.detail-value.monospace[_ngcontent-%COMP%] {\n font-family: 'SF Mono', Monaco, 'Courier New', monospace;\n font-size: 12px;\n}\n\n.detail-value.link[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.detail-action[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 12px;\n transition: var(--test-transition);\n}\n\n.detail-card.clickable[_ngcontent-%COMP%]:hover .detail-action[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n.error-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.error-content[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-bg-surface));\n}\n\n\n\n.result-details-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.result-details-content[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n\n\n\n\n.ai-runs-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.ai-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.count-badge[_ngcontent-%COMP%] {\n background: var(--test-bg);\n color: var(--test-text-secondary);\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.ai-run-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.ai-run-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.ai-run-card[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-primary);\n color: var(--mj-text-inverse);\n border-radius: var(--test-radius-md);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon.agent[_ngcontent-%COMP%] {\n background: var(--test-primary);\n}\n\n.ai-run-icon.prompt[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.ai-run-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.ai-run-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ai-run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.status-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.complete[_ngcontent-%COMP%], \n.status-chip.completed[_ngcontent-%COMP%], \n.status-chip.passed[_ngcontent-%COMP%] {\n background: var(--test-success-light);\n color: var(--mj-status-success);\n}\n\n.status-chip.failed[_ngcontent-%COMP%], \n.status-chip.error[_ngcontent-%COMP%] {\n background: var(--test-error-light);\n color: var(--mj-status-error);\n}\n\n.status-chip.running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n}\n\n.cost-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n color: var(--test-text-muted);\n}\n\n.ai-run-arrow[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.ai-run-card[_ngcontent-%COMP%]:hover .ai-run-arrow[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n\n\n.feedback-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.feedback-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-item[_ngcontent-%COMP%] {\n padding: 20px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.feedback-item[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary-light);\n}\n\n.feedback-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.feedback-user[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.user-avatar[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-primary);\n font-size: 14px;\n}\n\n.user-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-date[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.feedback-body[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.feedback-rating[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.rating-stars[_ngcontent-%COMP%] {\n display: flex;\n gap: 2px;\n}\n\n.rating-stars[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-border);\n}\n\n.rating-stars[_ngcontent-%COMP%] i.filled[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.rating-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-verdict[_ngcontent-%COMP%] {\n display: flex;\n}\n\n.verdict-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.verdict-badge.correct[_ngcontent-%COMP%] {\n background: var(--test-success-light);\n color: var(--mj-status-success);\n}\n\n.verdict-badge.incorrect[_ngcontent-%COMP%] {\n background: var(--test-error-light);\n color: var(--mj-status-error);\n}\n\n.feedback-comments[_ngcontent-%COMP%] {\n padding: 14px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n border-left: 3px solid var(--test-primary);\n}\n\n.feedback-comments[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.6;\n color: var(--test-text);\n}\n\n\n\n\n\n.log-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0;\n height: 100%;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.log-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: var(--test-surface);\n padding: 16px 20px;\n border-radius: var(--test-radius-lg) var(--test-radius-lg) 0 0;\n border: 1px solid var(--test-border);\n border-bottom: none;\n}\n\n.log-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.log-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-size: 16px;\n}\n\n.log-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.log-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.log-container[_ngcontent-%COMP%] {\n flex: 1;\n border-radius: 0 0 var(--test-radius-lg) var(--test-radius-lg);\n overflow: hidden;\n min-height: 300px;\n border: 1px solid var(--test-border);\n border-top: none;\n}\n\n\n\n\n\n.loading-state[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.skeleton-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon[_ngcontent-%COMP%], \n.skeleton-avatar[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-avatar[_ngcontent-%COMP%] {\n border-radius: 50%;\n}\n\n.skeleton-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line[_ngcontent-%COMP%] {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] { width: 70%; }\n.skeleton-line.medium[_ngcontent-%COMP%] { width: 55%; }\n.skeleton-line.narrow[_ngcontent-%COMP%] { width: 40%; }\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n\n\n\n\n.shortcuts-hint[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 100;\n}\n\n.shortcuts-hint[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n cursor: pointer;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.shortcuts-hint[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-color: var(--test-primary-light);\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] {\n display: none;\n position: absolute;\n bottom: 50px;\n right: 0;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 16px;\n box-shadow: var(--test-shadow-lg);\n min-width: 200px;\n}\n\n.shortcuts-hint[_ngcontent-%COMP%]:hover .shortcuts-popup[_ngcontent-%COMP%] {\n display: block;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-out;\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 6px 0;\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .details-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .shortcuts-hint[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .test-run-form[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n }\n\n .test-run-header[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n }\n\n .breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .status-indicator[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .test-run-meta[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .status-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 12px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .shortcut-hint[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 24px 20px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n font-size: 32px;\n }\n\n .result-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 24px;\n }\n\n .result-score[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .check-results[_ngcontent-%COMP%], \n .comparison-section[_ngcontent-%COMP%], \n .ai-section[_ngcontent-%COMP%], \n .feedback-item[_ngcontent-%COMP%] {\n padding: 18px;\n }\n\n .check-item[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .comparison-tabs[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 4px;\n }\n\n .comparison-tab[_ngcontent-%COMP%] {\n text-align: center;\n }\n\n .details-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .detail-card[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .ai-run-card[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .ai-run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .ai-run-meta[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 4px;\n }\n\n .feedback-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .log-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n\n .log-actions[_ngcontent-%COMP%] {\n justify-content: stretch;\n }\n\n .log-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n}\n\n\n\n\n\n@media (max-width: 480px) {\n .test-run-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n gap: 12px;\n }\n\n .status-indicator[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 10px;\n flex-direction: column;\n text-align: center;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n }\n\n .metric-label[_ngcontent-%COMP%] {\n font-size: 9px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 8px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 20px 16px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n font-size: 28px;\n }\n\n .result-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .result-score[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .result-checks[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .check-item[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 8px;\n }\n\n .check-weight[_ngcontent-%COMP%] {\n text-align: left;\n }\n}\n\n\n\n\n\n@media (hover: none) and (pointer: coarse) {\n .tab[_ngcontent-%COMP%], \n .comparison-tab[_ngcontent-%COMP%], \n .ai-run-card[_ngcontent-%COMP%], \n .check-item[_ngcontent-%COMP%], \n .feedback-item[_ngcontent-%COMP%], \n .detail-card.clickable[_ngcontent-%COMP%] {\n -webkit-tap-highlight-color: transparent;\n }\n\n .ai-run-card[_ngcontent-%COMP%]:active, \n .detail-card.clickable[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n \n\n .tab[_ngcontent-%COMP%] {\n min-height: 48px;\n }\n\n .ai-run-card[_ngcontent-%COMP%], \n .detail-card[_ngcontent-%COMP%] {\n min-height: 64px;\n }\n}\n\n\n\n\n\n@media (prefers-contrast: high) {\n .status-badge[_ngcontent-%COMP%] {\n border: 2px solid currentColor;\n }\n\n .check-item[_ngcontent-%COMP%] {\n border-width: 2px;\n }\n\n .tab.active[_ngcontent-%COMP%] {\n border-bottom-width: 4px;\n }\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon[_ngcontent-%COMP%], \n .skeleton-avatar[_ngcontent-%COMP%], \n .skeleton-line[_ngcontent-%COMP%] {\n animation: none;\n background: var(--mj-border-default);\n }\n\n .result-pulse[_ngcontent-%COMP%] {\n animation: none;\n display: none;\n }\n}\n\n\n\n\n\n@media print {\n .test-run-form[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n height: auto;\n }\n\n .header-actions[_ngcontent-%COMP%], \n .tabs-container[_ngcontent-%COMP%], \n .shortcuts-hint[_ngcontent-%COMP%], \n .log-actions[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n overflow: visible;\n padding: 0;\n }\n\n .result-hero[_ngcontent-%COMP%], \n .check-results[_ngcontent-%COMP%], \n .details-grid[_ngcontent-%COMP%], \n .ai-section[_ngcontent-%COMP%], \n .feedback-item[_ngcontent-%COMP%] {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid var(--mj-border-default);\n }\n\n .comparison-content[_ngcontent-%COMP%], \n .log-container[_ngcontent-%COMP%] {\n max-height: none;\n overflow: visible;\n }\n}\n\n\n\n\n\n.tags-bar[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 8px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n border-radius: 8px;\n max-width: 600px;\n}\n\n.tags-bar-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.tags-bar-label[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-size: 14px;\n}\n\n.tags-bar-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n opacity: 0.6;\n}\n\n.tags-bar-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1;\n}\n\n.tag-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.01em;\n}\n\n.tags-bar-empty[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n opacity: 0.7;\n flex: 1;\n}\n\n.tags-bar-edit[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: transparent;\n border: 1px dashed var(--test-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--test-text-secondary);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n\n\n.tags-editor-panel[_ngcontent-%COMP%] {\n margin-top: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n border-radius: var(--test-radius-md);\n overflow: hidden;\n box-shadow: var(--mj-shadow-md);\n max-width: 600px;\n}\n\n.tags-editor-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.tags-editor-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tags-editor-body[_ngcontent-%COMP%] {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.tags-editor-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.tag-editable[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n color: var(--test-primary);\n border-radius: 14px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n background: transparent;\n border: none;\n color: var(--test-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--test-transition);\n}\n\n.tag-remove-btn[_ngcontent-%COMP%]:hover {\n opacity: 1;\n background: var(--test-error-light);\n color: var(--test-error);\n}\n\n.tags-empty-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-style: italic;\n padding: 4px 0;\n}\n\n.tags-editor-input[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.tag-text-input[_ngcontent-%COMP%] {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--test-bg);\n}\n\n.tag-text-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--test-primary);\n background: var(--test-surface);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.tag-text-input[_ngcontent-%COMP%]::placeholder {\n color: var(--test-text-secondary);\n opacity: 0.6;\n}\n\n.tags-editor-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 8px;\n padding: 12px 16px;\n background: var(--test-bg);\n border-top: 1px solid var(--test-border);\n}\n\n\n\n@media (max-width: 768px) {\n .tags-bar[_ngcontent-%COMP%] {\n padding: 8px 12px;\n }\n\n .tags-bar-content[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .tag-inline[_ngcontent-%COMP%] {\n padding: 3px 8px;\n font-size: 10px;\n }\n\n .tags-editor-panel[_ngcontent-%COMP%] {\n margin-top: 12px;\n }\n\n .tags-editor-body[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .tags-editor-footer[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n}"], changeDetection: 0 }); }
|
|
1573
1555
|
};
|
|
1574
1556
|
MJTestRunFormComponentExtended = __decorate([
|
|
1575
1557
|
RegisterClass(BaseFormComponent, 'MJ: Test Runs')
|
|
@@ -1577,7 +1559,7 @@ MJTestRunFormComponentExtended = __decorate([
|
|
|
1577
1559
|
export { MJTestRunFormComponentExtended };
|
|
1578
1560
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJTestRunFormComponentExtended, [{
|
|
1579
1561
|
type: Component,
|
|
1580
|
-
args: [{ standalone: false, selector: 'mj-test-run-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-run-form\" [class.is-mobile]=\"false\">\n <!-- Error State -->\n @if (error) {\n <div class=\"error-banner\" (click)=\"retryLoad()\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <span>{{ error }}</span>\n <button class=\"retry-btn\">\n <i class=\"fas fa-redo\"></i> Retry\n </button>\n </div>\n }\n\n <!-- Header Section -->\n <div class=\"test-run-header\" [class]=\"getStatusClass()\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n @if (test) {\n <li>\n <i class=\"fas fa-chevron-right separator\"></i>\n <a href=\"javascript:void(0)\" (click)=\"openTest()\">\n <i class=\"fas fa-flask\"></i>\n <span class=\"breadcrumb-text\">{{ test.Name }}</span>\n </a>\n </li>\n }\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <span>Run #{{ record.ID.substring(0, 8) }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <!-- Status Indicator -->\n <div class=\"status-indicator\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n\n <div class=\"test-run-info\">\n <h1>\n Test Run\n <span class=\"run-id\">#{{ record.ID.substring(0, 8) }}</span>\n </h1>\n <div class=\"test-run-meta\">\n <span class=\"status-badge\" [style.background-color]=\"getStatusColor()\">\n {{ record.Status }}\n </span>\n @if (test) {\n <span class=\"meta-item\">\n <i class=\"fas fa-flask\"></i>\n {{ test.Type }}\n </span>\n }\n @if (autoRefreshEnabled) {\n <span class=\"meta-item\">\n <i class=\"fas fa-sync-alt fa-spin\"></i>\n Auto-refreshing\n </span>\n }\n </div>\n </div>\n </div>\n\n <div class=\"header-actions\">\n <button mjButton (click)=\"reRunTest()\" [disabled]=\"!record.TestID\" title=\"Re-run this test (Cmd+Shift+R)\">\n <i class=\"fas fa-redo\"></i>\n <span class=\"btn-text\">Re-run</span>\n </button>\n <button mjButton (click)=\"refresh()\" [disabled]=\"isRefreshing\" title=\"Refresh (Cmd+R)\">\n <i class=\"fas fa-sync-alt\" [class.fa-spin]=\"isRefreshing\"></i>\n <span class=\"btn-text\">Refresh</span>\n </button>\n </div>\n </div>\n\n <!-- Metrics Bar -->\n <div class=\"metrics-bar\">\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Started</div>\n <div class=\"metric-value\">{{ getRelativeTime(record.StartedAt) }}</div>\n <div class=\"metric-detail\">{{ record.StartedAt | date:'short' }}</div>\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-stopwatch\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Duration</div>\n <div class=\"metric-value\">{{ calculateDuration() }}</div>\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-star\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Score</div>\n <div class=\"metric-value\">{{ formatScore(record.Score) }}</div>\n @if (record.Score != null) {\n <div class=\"metric-progress\">\n <div class=\"progress-bar\" [style.width.%]=\"getScorePercentage()\" [style.background-color]=\"getStatusColor()\"></div>\n </div>\n }\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-check-double\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Checks</div>\n <div class=\"metric-value\">{{ record.PassedChecks }}/{{ record.TotalChecks }}</div>\n @if (record.TotalChecks) {\n <div class=\"metric-progress\">\n <div class=\"progress-bar\" [style.width.%]=\"getPassRatePercentage()\" [style.background-color]=\"getStatusColor()\"></div>\n </div>\n }\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Cost</div>\n <div class=\"metric-value\">{{ formatCost(record.CostUSD) }}</div>\n </div>\n </div>\n </div>\n\n <!-- Secondary Info -->\n @if (record.RunByUser || testSuiteRun || record.TargetLogEntityID) {\n <div class=\"secondary-info\">\n @if (record.RunByUser) {\n <span class=\"info-chip\">\n <i class=\"fas fa-user\"></i>\n {{ record.RunByUser }}\n </span>\n }\n @if (testSuiteRun) {\n <span class=\"info-chip clickable\" (click)=\"openTestSuiteRun()\">\n <i class=\"fas fa-layer-group\"></i>\n Part of Suite Run (Seq: {{ record.Sequence }})\n </span>\n }\n <!-- Target Entity Link Pill -->\n @if (record.TargetLogEntityID && record.TargetLogID) {\n <mj-entity-link-pill\n [entityName]=\"record.TargetLogEntity\"\n [recordId]=\"record.TargetLogID\">\n </mj-entity-link-pill>\n }\n </div>\n }\n\n <!-- Tags Section - Sleek inline design -->\n @if (!editingTags) {\n <div class=\"tags-bar\">\n <div class=\"tags-bar-content\">\n <span class=\"tags-bar-label\"><i class=\"fas fa-tags\"></i></span>\n @if (tags.length > 0) {\n <div class=\"tags-bar-chips\">\n @for (tag of tags; track tag) {\n <span class=\"tag-inline\">{{ tag }}</span>\n }\n </div>\n }\n @if (tags.length === 0) {\n <span class=\"tags-bar-empty\">No tags</span>\n }\n <button class=\"tags-bar-edit\" (click)=\"startEditingTags()\" title=\"Edit tags\">\n <i class=\"fas fa-plus\"></i> Add\n </button>\n </div>\n </div>\n }\n\n <!-- Tags Editor - Expanded when editing -->\n @if (editingTags) {\n <div class=\"tags-editor-panel\">\n <div class=\"tags-editor-header\">\n <span class=\"tags-editor-title\"><i class=\"fas fa-tags\"></i> Edit Tags</span>\n </div>\n <div class=\"tags-editor-body\">\n <div class=\"tags-editor-chips\">\n @for (tag of tags; track tag) {\n <span class=\"tag-editable\">\n {{ tag }}\n <button class=\"tag-remove-btn\" (click)=\"removeTag(tag)\" title=\"Remove tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n @if (tags.length === 0) {\n <span class=\"tags-empty-hint\">No tags yet</span>\n }\n </div>\n <div class=\"tags-editor-input\">\n <input type=\"text\"\n [(ngModel)]=\"newTag\"\n placeholder=\"Type a tag and press Enter...\"\n (keyup.enter)=\"addTag()\"\n class=\"tag-text-input\" />\n <button mjButton (click)=\"addTag()\" [disabled]=\"!newTag.trim()\" variant=\"flat\">\n <i class=\"fas fa-plus\"></i>\n </button>\n </div>\n </div>\n <div class=\"tags-editor-footer\">\n <button mjButton (click)=\"saveTags()\" variant=\"primary\" [disabled]=\"savingTags\">\n @if (savingTags) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n {{ savingTags ? 'Saving...' : 'Save' }}\n </button>\n <button mjButton (click)=\"cancelEditingTags()\" variant=\"flat\">Cancel</button>\n </div>\n </div>\n }\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\" [class.active]=\"activeTab === 'overview'\" (click)=\"changeTab('overview')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'overview'\" title=\"Press 1\">\n <i class=\"fas fa-chart-pie\"></i>\n <span>Overview</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'details'\" (click)=\"changeTab('details')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'details'\" title=\"Press 2\">\n <i class=\"fas fa-info-circle\"></i>\n <span>Details</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'ai-runs'\" (click)=\"changeTab('ai-runs')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'ai-runs'\" title=\"Press 3\">\n <i class=\"fas fa-robot\"></i>\n <span>AI Runs</span>\n @if (aiRunsLoaded) {\n <span class=\"tab-badge\">{{ aiAgentRuns.length + aiPromptRuns.length }}</span>\n }\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'feedback'\" (click)=\"changeTab('feedback')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'feedback'\" title=\"Press 4\">\n <i class=\"fas fa-comments\"></i>\n <span>Feedback</span>\n @if (feedbackLoaded) {\n <span class=\"tab-badge\">{{ feedbacks.length }}</span>\n }\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'execution'\" (click)=\"changeTab('execution')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'execution'\" title=\"Press 5\">\n <i class=\"fas fa-microchip\"></i>\n <span>Execution</span>\n </button>\n @if (record.Log) {\n <button class=\"tab\" [class.active]=\"activeTab === 'log'\" (click)=\"changeTab('log')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'log'\" title=\"Press 6\">\n <i class=\"fas fa-terminal\"></i>\n <span>Log</span>\n </button>\n }\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Overview Tab -->\n @if (activeTab === 'overview') {\n <div class=\"overview-tab\" [@fadeIn]>\n <!-- Result Hero -->\n <div class=\"result-hero\" [class]=\"getStatusClass()\">\n <div class=\"result-icon-wrapper\">\n <div class=\"result-icon\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n @if (record.Status === 'Running') {\n <div class=\"result-pulse\"></div>\n }\n </div>\n <div class=\"result-text\">\n <h2>TEST {{ record.Status.toUpperCase() }}</h2>\n <div class=\"result-details\">\n <span class=\"result-score\">Score: {{ formatScore(record.Score) }}</span>\n <span class=\"result-divider\">|</span>\n <span class=\"result-checks\">{{ record.PassedChecks }} of {{ record.TotalChecks }} checks passed</span>\n </div>\n </div>\n </div>\n <!-- Check Results -->\n @if (getCheckResults().length > 0) {\n <div class=\"check-results\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-tasks\"></i> Check Results</h3>\n <span class=\"check-summary\">{{ record.PassedChecks }} passed, {{ record.FailedChecks }} failed</span>\n </div>\n <div class=\"check-list\">\n @for (check of getCheckResults(); track check; let i = $index) {\n <div class=\"check-item\"\n [class.passed]=\"check.passed\" [class.failed]=\"!check.passed\"\n [style.animation-delay.ms]=\"i * 50\">\n <div class=\"check-status\">\n <i class=\"fas\" [class.fa-check-circle]=\"check.passed\" [class.fa-times-circle]=\"!check.passed\"></i>\n </div>\n <div class=\"check-content\">\n <div class=\"check-name\">{{ check.name }}</div>\n @if (check.message) {\n <div class=\"check-message\">{{ check.message }}</div>\n }\n </div>\n @if (check.weight) {\n <div class=\"check-weight\">\n <span class=\"weight-label\">Weight:</span> {{ check.weight }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n <!-- Data Comparison -->\n <div class=\"comparison-section\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-exchange-alt\"></i> Data Comparison</h3>\n </div>\n <div class=\"comparison-tabs\">\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'input'\" (click)=\"setComparisonView('input')\">\n <i class=\"fas fa-sign-in-alt\"></i> Input\n </button>\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'expected'\" (click)=\"setComparisonView('expected')\">\n <i class=\"fas fa-bullseye\"></i> Expected\n </button>\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'actual'\" (click)=\"setComparisonView('actual')\">\n <i class=\"fas fa-check-square\"></i> Actual\n </button>\n </div>\n <div class=\"comparison-content\">\n <mj-code-editor\n [value]=\"getComparisonData()\"\n language=\"json\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n }\n\n <!-- Details Tab -->\n @if (activeTab === 'details') {\n <div class=\"details-tab\" [@fadeIn]>\n <div class=\"details-grid\">\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-fingerprint\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Test Run ID</div>\n <div class=\"detail-value monospace\">{{ record.ID }}</div>\n </div>\n </div>\n @if (test) {\n <div class=\"detail-card clickable\" (click)=\"openTest()\">\n <div class=\"detail-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Test</div>\n <div class=\"detail-value link\">{{ test.Name }}</div>\n </div>\n <i class=\"fas fa-external-link-alt detail-action\"></i>\n </div>\n }\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-tag\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Target Type</div>\n <div class=\"detail-value\">{{ record.TargetType || 'N/A' }}</div>\n </div>\n </div>\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-play-circle\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Started At</div>\n <div class=\"detail-value\">{{ record.StartedAt | date:'medium' }}</div>\n </div>\n </div>\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-stop-circle\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Completed At</div>\n <div class=\"detail-value\">{{ record.CompletedAt | date:'medium' }}</div>\n </div>\n </div>\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-hourglass-half\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Duration</div>\n <div class=\"detail-value\">{{ calculateDuration() }}</div>\n </div>\n </div>\n </div>\n <!-- Error Message -->\n @if (record.ErrorMessage) {\n <div class=\"error-section\">\n <div class=\"section-header error\">\n <h3><i class=\"fas fa-exclamation-triangle\"></i> Error Message</h3>\n </div>\n <div class=\"error-content\">\n <mj-code-editor\n [value]=\"record.ErrorMessage\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n }\n <!-- Result Details -->\n @if (parsedData.resultDetails) {\n <div class=\"result-details-section\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-file-code\"></i> Result Details</h3>\n </div>\n <div class=\"result-details-content\">\n <mj-code-editor\n [value]=\"getFormattedResultDetails()\"\n language=\"json\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- AI Runs Tab -->\n @if (activeTab === 'ai-runs') {\n <div class=\"ai-runs-tab\" [@fadeIn]>\n <!-- Loading State -->\n @if (loadingAIRuns) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- AI Agent Runs -->\n @if (!loadingAIRuns && aiAgentRuns.length > 0) {\n <div class=\"ai-section\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-robot\"></i> AI Agent Runs</h3>\n <span class=\"count-badge\">{{ aiAgentRuns.length }}</span>\n </div>\n <div class=\"ai-run-list\">\n @for (run of aiAgentRuns; track run) {\n <div class=\"ai-run-card\" (click)=\"openAIAgentRun(run.ID)\">\n <div class=\"ai-run-icon agent\">\n <i class=\"fas fa-robot\"></i>\n </div>\n <div class=\"ai-run-content\">\n <div class=\"ai-run-name\">{{ run.Agent }}</div>\n <div class=\"ai-run-meta\">\n <span class=\"status-chip\" [class]=\"run.Status.toLowerCase()\">{{ run.Status }}</span>\n @if (run.TotalCost) {\n <span class=\"cost-chip\">\n <i class=\"fas fa-dollar-sign\"></i> {{ run.TotalCost | number:'1.4-4' }}\n </span>\n }\n </div>\n </div>\n <i class=\"fas fa-chevron-right ai-run-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n <!-- AI Prompt Runs -->\n @if (!loadingAIRuns && aiPromptRuns.length > 0) {\n <div class=\"ai-section\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-comment-dots\"></i> AI Prompt Runs</h3>\n <span class=\"count-badge\">{{ aiPromptRuns.length }}</span>\n </div>\n <div class=\"ai-run-list\">\n @for (run of aiPromptRuns; track run) {\n <div class=\"ai-run-card\" (click)=\"openAIPromptRun(run.ID)\">\n <div class=\"ai-run-icon prompt\">\n <i class=\"fas fa-comment-dots\"></i>\n </div>\n <div class=\"ai-run-content\">\n <div class=\"ai-run-name\">{{ run.Prompt || run.Model }}</div>\n <div class=\"ai-run-meta\">\n @if (run.TotalCost) {\n <span class=\"cost-chip\">\n <i class=\"fas fa-dollar-sign\"></i> {{ run.TotalCost | number:'1.4-4' }}\n </span>\n }\n </div>\n </div>\n <i class=\"fas fa-chevron-right ai-run-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n <!-- Empty State -->\n @if (aiRunsLoaded && aiAgentRuns.length === 0 && aiPromptRuns.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-robot\"></i>\n </div>\n <h3>No AI Runs</h3>\n <p>This test execution didn't involve any AI agent or prompt runs.</p>\n </div>\n }\n </div>\n }\n\n <!-- Feedback Tab -->\n @if (activeTab === 'feedback') {\n <div class=\"feedback-tab\" [@fadeIn]>\n <!-- Loading State -->\n @if (loadingFeedback) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-avatar\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n <div class=\"skeleton-line medium\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Feedback List -->\n @if (!loadingFeedback && feedbacks.length > 0) {\n <div class=\"feedback-list\">\n @for (feedback of feedbacks; track feedback) {\n <div class=\"feedback-item\">\n <div class=\"feedback-header\">\n <div class=\"feedback-user\">\n <div class=\"user-avatar\">\n <i class=\"fas fa-user\"></i>\n </div>\n <span class=\"user-name\">{{ feedback.ReviewerUser }}</span>\n </div>\n <div class=\"feedback-date\">\n {{ getRelativeTime(feedback.__mj_CreatedAt) }}\n </div>\n </div>\n <div class=\"feedback-body\">\n <div class=\"feedback-rating\">\n <div class=\"rating-stars\">\n @for (s of [1,2,3,4,5,6,7,8,9,10]; track s) {\n <i class=\"fas fa-star\"\n [class.filled]=\"s <= (feedback.Rating || 0)\"></i>\n }\n </div>\n <span class=\"rating-value\">{{ feedback.Rating }}/10</span>\n </div>\n @if (feedback.IsCorrect !== null) {\n <div class=\"feedback-verdict\">\n <span class=\"verdict-badge\" [class.correct]=\"feedback.IsCorrect\" [class.incorrect]=\"!feedback.IsCorrect\">\n <i class=\"fas\" [class.fa-check]=\"feedback.IsCorrect\" [class.fa-times]=\"!feedback.IsCorrect\"></i>\n {{ feedback.IsCorrect ? 'Marked Correct' : 'Marked Incorrect' }}\n </span>\n </div>\n }\n @if (feedback.CorrectionSummary) {\n <div class=\"feedback-comments\">\n <p>{{ feedback.CorrectionSummary }}</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (feedbackLoaded && feedbacks.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-comments\"></i>\n </div>\n <h3>No Feedback Yet</h3>\n <p>No one has reviewed this test run yet. Be the first to provide feedback!</p>\n </div>\n }\n </div>\n }\n\n <!-- Execution Context Tab -->\n @if (activeTab === 'execution') {\n <div class=\"execution-tab\" [@fadeIn]>\n <mj-execution-context\n [machineName]=\"record.MachineName\"\n [machineId]=\"record.MachineID\"\n [runByUserName]=\"record.RunByUserName\"\n [runByUserEmail]=\"record.RunByUserEmail\"\n [runContextDetailsJson]=\"record.RunContextDetails\">\n </mj-execution-context>\n </div>\n }\n\n <!-- Execution Log Tab -->\n @if (activeTab === 'log') {\n <div class=\"log-tab\" [@fadeIn]>\n <div class=\"log-header\">\n <div class=\"log-title\">\n <i class=\"fas fa-terminal\"></i>\n <h3>Execution Log</h3>\n </div>\n <div class=\"log-actions\">\n <button mjButton (click)=\"copyLogToClipboard()\" variant=\"flat\">\n <i class=\"fas fa-copy\"></i>\n <span class=\"btn-text\">Copy</span>\n </button>\n </div>\n </div>\n <div class=\"log-container\">\n <mj-code-editor\n [value]=\"record.Log || ''\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n }\n </div>\n\n <!-- Keyboard Shortcuts Help (shown on hover of ? icon) -->\n <div class=\"shortcuts-hint\" title=\"Keyboard Shortcuts\">\n <i class=\"fas fa-keyboard\"></i>\n <div class=\"shortcuts-popup\">\n <h4>Keyboard Shortcuts</h4>\n <ul>\n <li><kbd>1-6</kbd> Switch tabs</li>\n <li><kbd>Cmd+R</kbd> Refresh</li>\n <li><kbd>Cmd+Shift+R</kbd> Re-run test</li>\n </ul>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n Test Run Form - World-Class UX\n Premium Testing Dashboard Styles\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-primary-dark: var(--mj-brand-primary-hover);\n --test-success: var(--mj-status-success);\n --test-success-light: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n --test-error: var(--mj-status-error);\n --test-error-light: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n --test-warning: var(--mj-status-warning);\n --test-warning-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-timeout: var(--mj-status-warning);\n --test-timeout-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-running: var(--mj-brand-primary);\n --test-pending: var(--mj-brand-primary);\n --test-skipped: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-muted);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n/* Base Container */\n.test-run-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* ===========================\n Error Banner\n =========================== */\n.error-banner {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 12px 20px;\n background: var(--test-error);\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n animation: slideDown 0.3s ease-out;\n}\n\n.error-banner:hover {\n background: var(--mj-status-error);\n}\n\n.error-banner i {\n font-size: 16px;\n}\n\n.retry-btn {\n background: rgba(255, 255, 255, 0.2);\n border: 1px solid rgba(255, 255, 255, 0.3);\n color: var(--mj-text-inverse);\n padding: 6px 12px;\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.retry-btn:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n\n@keyframes slideDown {\n from {\n transform: translateY(-100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n/* ===========================\n Header Section\n =========================== */\n.test-run-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n position: relative;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n flex-wrap: wrap;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.breadcrumb a:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header Content */\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n/* Status Indicator */\n.status-indicator {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.status-indicator:hover {\n transform: scale(1.05);\n}\n\n/* Test Run Info */\n.test-run-info {\n flex: 1;\n min-width: 0;\n}\n\n.test-run-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-run-info h1 .run-id {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.test-run-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n/* Meta Item */\n.meta-item {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n}\n\n.meta-item i {\n font-size: 12px;\n}\n\n/* Header Actions */\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions button {\n white-space: nowrap;\n}\n\n.btn-text {\n margin-left: 6px;\n}\n\n/* ===========================\n Metrics Bar\n =========================== */\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.metric-card {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n transition: var(--test-transition);\n}\n\n.metric-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-sm);\n color: var(--test-primary);\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.metric-content {\n flex: 1;\n min-width: 0;\n}\n\n.metric-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.metric-value {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.metric-detail {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 2px;\n}\n\n/* Progress bar in metric card */\n.metric-progress {\n margin-top: 6px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.progress-bar {\n height: 100%;\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n/* Secondary Info */\n.secondary-info {\n display: flex;\n gap: 12px;\n padding-top: 16px;\n border-top: 1px solid var(--test-border);\n flex-wrap: wrap;\n}\n\n.info-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--test-text-secondary);\n padding: 6px 12px;\n background: var(--test-bg);\n border-radius: 20px;\n transition: var(--test-transition);\n}\n\n.info-chip i {\n font-size: 12px;\n}\n\n.info-chip.clickable {\n cursor: pointer;\n}\n\n.info-chip.clickable:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n}\n\n/* ===========================\n Tabs Navigation\n =========================== */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs::-webkit-scrollbar {\n display: none;\n}\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab i {\n font-size: 15px;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.shortcut-hint {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n/* ===========================\n Tab Content Area\n =========================== */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n/* ===========================\n Overview Tab\n =========================== */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Result Hero Card */\n.result-hero {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 32px;\n text-align: center;\n border: 2px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.result-hero.passed {\n background: var(--test-success-light);\n border-color: var(--test-success);\n}\n\n.result-hero.failed {\n background: var(--test-error-light);\n border-color: var(--test-error);\n}\n\n.result-hero.error {\n background: var(--test-warning-light);\n border-color: var(--test-warning);\n}\n\n.result-hero.timeout {\n background: var(--test-timeout-light);\n border-color: var(--test-timeout);\n}\n\n.result-hero.running,\n.result-hero.pending {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--test-primary-light);\n}\n\n.result-icon-wrapper {\n position: relative;\n display: inline-block;\n margin-bottom: 16px;\n}\n\n.result-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: 50%;\n font-size: 40px;\n margin: 0 auto;\n box-shadow: var(--test-shadow-md);\n}\n\n.result-hero.passed .result-icon { color: var(--test-success); }\n.result-hero.failed .result-icon { color: var(--test-error); }\n.result-hero.error .result-icon { color: var(--test-warning); }\n.result-hero.timeout .result-icon { color: var(--test-timeout); }\n.result-hero.running .result-icon,\n.result-hero.pending .result-icon { color: var(--test-primary); }\n\n.result-pulse {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 100px;\n height: 100px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n animation: pulse 2s ease-in-out infinite;\n}\n\n@keyframes pulse {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.5; }\n 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0; }\n}\n\n.result-text h2 {\n margin: 0 0 12px 0;\n font-size: clamp(24px, 5vw, 32px);\n font-weight: 800;\n color: var(--test-text);\n}\n\n.result-details {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.result-score {\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.result-divider {\n color: var(--test-border);\n}\n\n.result-checks {\n font-size: 16px;\n color: var(--test-text-muted);\n}\n\n/* Section Headers */\n.section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n gap: 12px;\n}\n\n.section-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-header h3 i {\n color: var(--test-primary);\n}\n\n.section-header.error h3 i {\n color: var(--test-error);\n}\n\n.check-summary {\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n/* Check Results Section */\n.check-results {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.check-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.check-item {\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n transition: var(--test-transition);\n animation: fadeIn 0.3s ease-out backwards;\n}\n\n.check-item:hover {\n transform: translateX(4px);\n}\n\n.check-item.passed {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-success) 40%, var(--mj-bg-surface));\n}\n\n.check-item.failed {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-bg-surface));\n}\n\n.check-status {\n font-size: 20px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.check-item.passed .check-status { color: var(--test-success); }\n.check-item.failed .check-status { color: var(--test-error); }\n\n.check-content {\n flex: 1;\n min-width: 0;\n}\n\n.check-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.check-message {\n font-size: 13px;\n color: var(--test-text-secondary);\n line-height: 1.5;\n word-wrap: break-word;\n}\n\n.check-weight {\n font-size: 12px;\n color: var(--test-text-muted);\n flex-shrink: 0;\n text-align: right;\n}\n\n.weight-label {\n font-weight: 500;\n}\n\n/* Comparison Section */\n.comparison-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-tabs {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.comparison-tab {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 16px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.comparison-tab:hover {\n color: var(--test-text);\n background: var(--mj-bg-overlay);\n}\n\n.comparison-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-content {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n/* ===========================\n Details Tab\n =========================== */\n.details-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.detail-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n transition: var(--test-transition);\n}\n\n.detail-card.clickable {\n cursor: pointer;\n}\n\n.detail-card.clickable:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.detail-icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.detail-content {\n flex: 1;\n min-width: 0;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.detail-value {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n.detail-value.monospace {\n font-family: 'SF Mono', Monaco, 'Courier New', monospace;\n font-size: 12px;\n}\n\n.detail-value.link {\n color: var(--test-primary);\n}\n\n.detail-action {\n color: var(--test-text-muted);\n font-size: 12px;\n transition: var(--test-transition);\n}\n\n.detail-card.clickable:hover .detail-action {\n color: var(--test-primary);\n}\n\n/* Error Section */\n.error-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.error-content {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-bg-surface));\n}\n\n/* Result Details Section */\n.result-details-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.result-details-content {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n/* ===========================\n AI Runs Tab\n =========================== */\n.ai-runs-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n.ai-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.count-badge {\n background: var(--test-bg);\n color: var(--test-text-secondary);\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.ai-run-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.ai-run-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.ai-run-card:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-primary);\n color: var(--mj-text-inverse);\n border-radius: var(--test-radius-md);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon.agent {\n background: var(--test-primary);\n}\n\n.ai-run-icon.prompt {\n background: var(--mj-brand-primary);\n}\n\n.ai-run-content {\n flex: 1;\n min-width: 0;\n}\n\n.ai-run-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ai-run-meta {\n display: flex;\n gap: 10px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.complete,\n.status-chip.completed,\n.status-chip.passed {\n background: var(--test-success-light);\n color: var(--mj-status-success);\n}\n\n.status-chip.failed,\n.status-chip.error {\n background: var(--test-error-light);\n color: var(--mj-status-error);\n}\n\n.status-chip.running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n}\n\n.cost-chip {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n color: var(--test-text-muted);\n}\n\n.ai-run-arrow {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.ai-run-card:hover .ai-run-arrow {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* ===========================\n Feedback Tab\n =========================== */\n.feedback-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.feedback-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-item {\n padding: 20px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.feedback-item:hover {\n border-color: var(--test-primary-light);\n}\n\n.feedback-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.feedback-user {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.user-avatar {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-primary);\n font-size: 14px;\n}\n\n.user-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-date {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.feedback-body {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.feedback-rating {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.rating-stars {\n display: flex;\n gap: 2px;\n}\n\n.rating-stars i {\n font-size: 14px;\n color: var(--test-border);\n}\n\n.rating-stars i.filled {\n color: var(--mj-status-warning);\n}\n\n.rating-value {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-verdict {\n display: flex;\n}\n\n.verdict-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.verdict-badge.correct {\n background: var(--test-success-light);\n color: var(--mj-status-success);\n}\n\n.verdict-badge.incorrect {\n background: var(--test-error-light);\n color: var(--mj-status-error);\n}\n\n.feedback-comments {\n padding: 14px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n border-left: 3px solid var(--test-primary);\n}\n\n.feedback-comments p {\n margin: 0;\n font-size: 14px;\n line-height: 1.6;\n color: var(--test-text);\n}\n\n/* ===========================\n Log Tab\n =========================== */\n.log-tab {\n display: flex;\n flex-direction: column;\n gap: 0;\n height: 100%;\n animation: fadeIn 0.3s ease-out;\n}\n\n.log-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: var(--test-surface);\n padding: 16px 20px;\n border-radius: var(--test-radius-lg) var(--test-radius-lg) 0 0;\n border: 1px solid var(--test-border);\n border-bottom: none;\n}\n\n.log-title {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.log-title i {\n color: var(--test-text-secondary);\n font-size: 16px;\n}\n\n.log-title h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.log-actions {\n display: flex;\n gap: 8px;\n}\n\n.log-container {\n flex: 1;\n border-radius: 0 0 var(--test-radius-lg) var(--test-radius-lg);\n overflow: hidden;\n min-height: 300px;\n border: 1px solid var(--test-border);\n border-top: none;\n}\n\n/* ===========================\n Loading States & Skeletons\n =========================== */\n.loading-state {\n padding: 20px;\n}\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon,\n.skeleton-avatar {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-avatar {\n border-radius: 50%;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.medium { width: 55%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* ===========================\n Empty States\n =========================== */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n/* ===========================\n Keyboard Shortcuts Help\n =========================== */\n.shortcuts-hint {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 100;\n}\n\n.shortcuts-hint > i {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n cursor: pointer;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.shortcuts-hint:hover > i {\n color: var(--test-primary);\n border-color: var(--test-primary-light);\n}\n\n.shortcuts-popup {\n display: none;\n position: absolute;\n bottom: 50px;\n right: 0;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 16px;\n box-shadow: var(--test-shadow-lg);\n min-width: 200px;\n}\n\n.shortcuts-hint:hover .shortcuts-popup {\n display: block;\n animation: fadeIn 0.2s ease-out;\n}\n\n.shortcuts-popup h4 {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.shortcuts-popup ul {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.shortcuts-popup li {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 6px 0;\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n.shortcuts-popup kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* ===========================\n Responsive Design - Tablet\n =========================== */\n@media (max-width: 1024px) {\n .metrics-bar {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .details-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .shortcuts-hint {\n display: none;\n }\n}\n\n/* ===========================\n Responsive Design - Mobile\n =========================== */\n@media (max-width: 768px) {\n .test-run-form {\n height: auto;\n min-height: 100%;\n }\n\n .test-run-header {\n padding: 16px;\n }\n\n .breadcrumb {\n margin-bottom: 12px;\n }\n\n .breadcrumb ol {\n font-size: 12px;\n }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left {\n width: 100%;\n }\n\n .status-indicator {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-run-info h1 {\n font-size: 18px;\n }\n\n .test-run-meta {\n gap: 8px;\n }\n\n .status-badge {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button {\n flex: 1;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card {\n padding: 12px;\n }\n\n .metric-icon {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .metric-value {\n font-size: 14px;\n }\n\n .tabs {\n padding: 0 12px;\n }\n\n .tab {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab i {\n font-size: 14px;\n }\n\n .shortcut-hint {\n display: none;\n }\n\n .tab-content {\n padding: 16px;\n }\n\n .result-hero {\n padding: 24px 20px;\n }\n\n .result-icon {\n width: 64px;\n height: 64px;\n font-size: 32px;\n }\n\n .result-text h2 {\n font-size: 24px;\n }\n\n .result-score {\n font-size: 16px;\n }\n\n .check-results,\n .comparison-section,\n .ai-section,\n .feedback-item {\n padding: 18px;\n }\n\n .check-item {\n padding: 12px;\n }\n\n .comparison-tabs {\n flex-direction: column;\n gap: 4px;\n }\n\n .comparison-tab {\n text-align: center;\n }\n\n .details-grid {\n grid-template-columns: 1fr;\n }\n\n .detail-card {\n padding: 14px;\n }\n\n .ai-run-card {\n padding: 14px;\n }\n\n .ai-run-icon {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .ai-run-meta {\n flex-direction: column;\n gap: 4px;\n }\n\n .feedback-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .log-header {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n\n .log-actions {\n justify-content: stretch;\n }\n\n .log-actions button {\n flex: 1;\n }\n\n .empty-state {\n padding: 40px 20px;\n }\n\n .empty-icon {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon i {\n font-size: 28px;\n }\n}\n\n/* ===========================\n Responsive Design - Small Mobile\n =========================== */\n@media (max-width: 480px) {\n .test-run-header {\n padding: 12px;\n }\n\n .header-left {\n gap: 12px;\n }\n\n .status-indicator {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-run-info h1 {\n font-size: 16px;\n }\n\n .metrics-bar {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card {\n padding: 10px;\n flex-direction: column;\n text-align: center;\n }\n\n .metric-icon {\n margin-bottom: 8px;\n }\n\n .metric-label {\n font-size: 9px;\n }\n\n .metric-value {\n font-size: 14px;\n }\n\n .tabs {\n padding: 0 8px;\n }\n\n .tab {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge {\n display: none;\n }\n\n .tab-content {\n padding: 12px;\n }\n\n .result-hero {\n padding: 20px 16px;\n }\n\n .result-icon {\n width: 56px;\n height: 56px;\n font-size: 28px;\n }\n\n .result-text h2 {\n font-size: 20px;\n }\n\n .result-score {\n font-size: 14px;\n }\n\n .result-checks {\n font-size: 12px;\n }\n\n .section-header h3 {\n font-size: 16px;\n }\n\n .check-item {\n flex-direction: column;\n gap: 8px;\n }\n\n .check-weight {\n text-align: left;\n }\n}\n\n/* ===========================\n Touch Device Optimizations\n =========================== */\n@media (hover: none) and (pointer: coarse) {\n .tab,\n .comparison-tab,\n .ai-run-card,\n .check-item,\n .feedback-item,\n .detail-card.clickable {\n -webkit-tap-highlight-color: transparent;\n }\n\n .ai-run-card:active,\n .detail-card.clickable:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n transform: scale(0.98);\n }\n\n .tab:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n /* Larger touch targets */\n .tab {\n min-height: 48px;\n }\n\n .ai-run-card,\n .detail-card {\n min-height: 64px;\n }\n}\n\n/* ===========================\n High Contrast Mode\n =========================== */\n@media (prefers-contrast: high) {\n .status-badge {\n border: 2px solid currentColor;\n }\n\n .check-item {\n border-width: 2px;\n }\n\n .tab.active {\n border-bottom-width: 4px;\n }\n}\n\n/* ===========================\n Reduced Motion\n =========================== */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon,\n .skeleton-avatar,\n .skeleton-line {\n animation: none;\n background: var(--mj-border-default);\n }\n\n .result-pulse {\n animation: none;\n display: none;\n }\n}\n\n/* ===========================\n Print Styles\n =========================== */\n@media print {\n .test-run-form {\n background: var(--mj-bg-surface);\n height: auto;\n }\n\n .header-actions,\n .tabs-container,\n .shortcuts-hint,\n .log-actions {\n display: none !important;\n }\n\n .tab-content {\n overflow: visible;\n padding: 0;\n }\n\n .result-hero,\n .check-results,\n .details-grid,\n .ai-section,\n .feedback-item {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid var(--mj-border-default);\n }\n\n .comparison-content,\n .log-container {\n max-height: none;\n overflow: visible;\n }\n}\n\n/* ===========================\n Tags Bar - Sleek Inline Display\n =========================== */\n.tags-bar {\n margin-top: 16px;\n padding: 8px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n border-radius: 8px;\n max-width: 600px;\n}\n\n.tags-bar-content {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.tags-bar-label {\n color: var(--test-text-secondary);\n font-size: 14px;\n}\n\n.tags-bar-label i {\n opacity: 0.6;\n}\n\n.tags-bar-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1;\n}\n\n.tag-inline {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.01em;\n}\n\n.tags-bar-empty {\n font-size: 12px;\n color: var(--test-text-secondary);\n opacity: 0.7;\n flex: 1;\n}\n\n.tags-bar-edit {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: transparent;\n border: 1px dashed var(--test-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--test-text-secondary);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.tags-bar-edit:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tags-bar-edit i {\n font-size: 10px;\n}\n\n/* ===========================\n Tags Editor Panel - Expanded Edit Mode\n =========================== */\n.tags-editor-panel {\n margin-top: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n border-radius: var(--test-radius-md);\n overflow: hidden;\n box-shadow: var(--mj-shadow-md);\n max-width: 600px;\n}\n\n.tags-editor-header {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.tags-editor-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tags-editor-body {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.tags-editor-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.tag-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n color: var(--test-primary);\n border-radius: 14px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n background: transparent;\n border: none;\n color: var(--test-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--test-transition);\n}\n\n.tag-remove-btn:hover {\n opacity: 1;\n background: var(--test-error-light);\n color: var(--test-error);\n}\n\n.tags-empty-hint {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-style: italic;\n padding: 4px 0;\n}\n\n.tags-editor-input {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.tag-text-input {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--test-bg);\n}\n\n.tag-text-input:focus {\n outline: none;\n border-color: var(--test-primary);\n background: var(--test-surface);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.tag-text-input::placeholder {\n color: var(--test-text-secondary);\n opacity: 0.6;\n}\n\n.tags-editor-footer {\n display: flex;\n justify-content: flex-start;\n gap: 8px;\n padding: 12px 16px;\n background: var(--test-bg);\n border-top: 1px solid var(--test-border);\n}\n\n/* Mobile Responsive for Tags */\n@media (max-width: 768px) {\n .tags-bar {\n padding: 8px 12px;\n }\n\n .tags-bar-content {\n gap: 8px;\n }\n\n .tag-inline {\n padding: 3px 8px;\n font-size: 10px;\n }\n\n .tags-editor-panel {\n margin-top: 12px;\n }\n\n .tags-editor-body {\n padding: 12px;\n }\n\n .tags-editor-footer {\n padding: 10px 12px;\n }\n}\n"] }]
|
|
1562
|
+
args: [{ standalone: false, selector: 'mj-test-run-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-run-form\" [class.is-mobile]=\"false\">\n <!-- Error State -->\n @if (error) {\n <mj-alert Variant=\"error\">\n <span>{{ error }}</span>\n <button actions mjButton variant=\"secondary\" size=\"sm\" (click)=\"retryLoad()\">\n <i class=\"fas fa-redo\"></i> Retry\n </button>\n </mj-alert>\n }\n\n <!-- Header Section -->\n <div class=\"test-run-header\" [class]=\"getStatusClass()\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n @if (test) {\n <li>\n <i class=\"fas fa-chevron-right separator\"></i>\n <a href=\"javascript:void(0)\" (click)=\"openTest()\">\n <i class=\"fas fa-flask\"></i>\n <span class=\"breadcrumb-text\">{{ test.Name }}</span>\n </a>\n </li>\n }\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <span>Run #{{ record.ID.substring(0, 8) }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <!-- Status Indicator -->\n <div class=\"status-indicator\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n\n <div class=\"test-run-info\">\n <h1>\n Test Run\n <span class=\"run-id\">#{{ record.ID.substring(0, 8) }}</span>\n </h1>\n <div class=\"test-run-meta\">\n <span class=\"status-badge\" [style.background-color]=\"getStatusColor()\">\n {{ record.Status }}\n </span>\n @if (test) {\n <span class=\"meta-item\">\n <i class=\"fas fa-flask\"></i>\n {{ test.Type }}\n </span>\n }\n @if (autoRefreshEnabled) {\n <span class=\"meta-item\">\n <i class=\"fas fa-sync-alt fa-spin\"></i>\n Auto-refreshing\n </span>\n }\n </div>\n </div>\n </div>\n\n <div class=\"header-actions\">\n <button mjButton (click)=\"reRunTest()\" [disabled]=\"!record.TestID\" title=\"Re-run this test (Cmd+Shift+R)\">\n <i class=\"fas fa-redo\"></i>\n <span class=\"btn-text\">Re-run</span>\n </button>\n <button mjButton (click)=\"refresh()\" [disabled]=\"isRefreshing\" title=\"Refresh (Cmd+R)\">\n <i class=\"fas fa-sync-alt\" [class.fa-spin]=\"isRefreshing\"></i>\n <span class=\"btn-text\">Refresh</span>\n </button>\n </div>\n </div>\n\n <!-- Metrics Bar -->\n <div class=\"metrics-bar\">\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Started</div>\n <div class=\"metric-value\">{{ getRelativeTime(record.StartedAt) }}</div>\n <div class=\"metric-detail\">{{ record.StartedAt | date:'short' }}</div>\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-stopwatch\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Duration</div>\n <div class=\"metric-value\">{{ calculateDuration() }}</div>\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-star\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Score</div>\n <div class=\"metric-value\">{{ formatScore(record.Score) }}</div>\n @if (record.Score != null) {\n <div class=\"metric-progress\">\n <div class=\"progress-bar\" [style.width.%]=\"getScorePercentage()\" [style.background-color]=\"getStatusColor()\"></div>\n </div>\n }\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-check-double\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Checks</div>\n <div class=\"metric-value\">{{ record.PassedChecks }}/{{ record.TotalChecks }}</div>\n @if (record.TotalChecks) {\n <div class=\"metric-progress\">\n <div class=\"progress-bar\" [style.width.%]=\"getPassRatePercentage()\" [style.background-color]=\"getStatusColor()\"></div>\n </div>\n }\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Cost</div>\n <div class=\"metric-value\">{{ formatCost(record.CostUSD) }}</div>\n </div>\n </div>\n </div>\n\n <!-- Secondary Info -->\n @if (record.RunByUser || testSuiteRun || record.TargetLogEntityID) {\n <div class=\"secondary-info\">\n @if (record.RunByUser) {\n <span class=\"info-chip\">\n <i class=\"fas fa-user\"></i>\n {{ record.RunByUser }}\n </span>\n }\n @if (testSuiteRun) {\n <span class=\"info-chip clickable\" (click)=\"openTestSuiteRun()\">\n <i class=\"fas fa-layer-group\"></i>\n Part of Suite Run (Seq: {{ record.Sequence }})\n </span>\n }\n <!-- Target Entity Link Pill -->\n @if (record.TargetLogEntityID && record.TargetLogID) {\n <mj-entity-link-pill\n [entityName]=\"record.TargetLogEntity\"\n [recordId]=\"record.TargetLogID\">\n </mj-entity-link-pill>\n }\n </div>\n }\n\n <!-- Tags Section - Sleek inline design -->\n @if (!editingTags) {\n <div class=\"tags-bar\">\n <div class=\"tags-bar-content\">\n <span class=\"tags-bar-label\"><i class=\"fas fa-tags\"></i></span>\n @if (tags.length > 0) {\n <div class=\"tags-bar-chips\">\n @for (tag of tags; track tag) {\n <span class=\"tag-inline\">{{ tag }}</span>\n }\n </div>\n }\n @if (tags.length === 0) {\n <span class=\"tags-bar-empty\">No tags</span>\n }\n <button class=\"tags-bar-edit\" (click)=\"startEditingTags()\" title=\"Edit tags\">\n <i class=\"fas fa-plus\"></i> Add\n </button>\n </div>\n </div>\n }\n\n <!-- Tags Editor - Expanded when editing -->\n @if (editingTags) {\n <div class=\"tags-editor-panel\">\n <div class=\"tags-editor-header\">\n <span class=\"tags-editor-title\"><i class=\"fas fa-tags\"></i> Edit Tags</span>\n </div>\n <div class=\"tags-editor-body\">\n <div class=\"tags-editor-chips\">\n @for (tag of tags; track tag) {\n <span class=\"tag-editable\">\n {{ tag }}\n <button class=\"tag-remove-btn\" (click)=\"removeTag(tag)\" title=\"Remove tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n @if (tags.length === 0) {\n <span class=\"tags-empty-hint\">No tags yet</span>\n }\n </div>\n <div class=\"tags-editor-input\">\n <input type=\"text\"\n [(ngModel)]=\"newTag\"\n placeholder=\"Type a tag and press Enter...\"\n (keyup.enter)=\"addTag()\"\n class=\"tag-text-input\" />\n <button mjButton (click)=\"addTag()\" [disabled]=\"!newTag.trim()\" variant=\"flat\">\n <i class=\"fas fa-plus\"></i>\n </button>\n </div>\n </div>\n <div class=\"tags-editor-footer\">\n <button mjButton (click)=\"saveTags()\" variant=\"primary\" [disabled]=\"savingTags\">\n @if (savingTags) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n {{ savingTags ? 'Saving...' : 'Save' }}\n </button>\n <button mjButton (click)=\"cancelEditingTags()\" variant=\"flat\">Cancel</button>\n </div>\n </div>\n }\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\" [class.active]=\"activeTab === 'overview'\" (click)=\"changeTab('overview')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'overview'\" title=\"Press 1\">\n <i class=\"fas fa-chart-pie\"></i>\n <span>Overview</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'details'\" (click)=\"changeTab('details')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'details'\" title=\"Press 2\">\n <i class=\"fas fa-info-circle\"></i>\n <span>Details</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'ai-runs'\" (click)=\"changeTab('ai-runs')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'ai-runs'\" title=\"Press 3\">\n <i class=\"fas fa-robot\"></i>\n <span>AI Runs</span>\n @if (aiRunsLoaded) {\n <span class=\"tab-badge\">{{ aiAgentRuns.length + aiPromptRuns.length }}</span>\n }\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'feedback'\" (click)=\"changeTab('feedback')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'feedback'\" title=\"Press 4\">\n <i class=\"fas fa-comments\"></i>\n <span>Feedback</span>\n @if (feedbackLoaded) {\n <span class=\"tab-badge\">{{ feedbacks.length }}</span>\n }\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'execution'\" (click)=\"changeTab('execution')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'execution'\" title=\"Press 5\">\n <i class=\"fas fa-microchip\"></i>\n <span>Execution</span>\n </button>\n @if (record.Log) {\n <button class=\"tab\" [class.active]=\"activeTab === 'log'\" (click)=\"changeTab('log')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'log'\" title=\"Press 6\">\n <i class=\"fas fa-terminal\"></i>\n <span>Log</span>\n </button>\n }\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Overview Tab -->\n @if (activeTab === 'overview') {\n <div class=\"overview-tab\" [@fadeIn]>\n <!-- Result Hero -->\n <div class=\"result-hero\" [class]=\"getStatusClass()\">\n <div class=\"result-icon-wrapper\">\n <div class=\"result-icon\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n @if (record.Status === 'Running') {\n <div class=\"result-pulse\"></div>\n }\n </div>\n <div class=\"result-text\">\n <h2>TEST {{ record.Status.toUpperCase() }}</h2>\n <div class=\"result-details\">\n <span class=\"result-score\">Score: {{ formatScore(record.Score) }}</span>\n <span class=\"result-divider\">|</span>\n <span class=\"result-checks\">{{ record.PassedChecks }} of {{ record.TotalChecks }} checks passed</span>\n </div>\n </div>\n </div>\n <!-- Check Results -->\n @if (getCheckResults().length > 0) {\n <div class=\"check-results\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-tasks\"></i> Check Results</h3>\n <span class=\"check-summary\">{{ record.PassedChecks }} passed, {{ record.FailedChecks }} failed</span>\n </div>\n <div class=\"check-list\">\n @for (check of getCheckResults(); track check; let i = $index) {\n <div class=\"check-item\"\n [class.passed]=\"check.passed\" [class.failed]=\"!check.passed\"\n [style.animation-delay.ms]=\"i * 50\">\n <div class=\"check-status\">\n <i class=\"fas\" [class.fa-check-circle]=\"check.passed\" [class.fa-times-circle]=\"!check.passed\"></i>\n </div>\n <div class=\"check-content\">\n <div class=\"check-name\">{{ check.name }}</div>\n @if (check.message) {\n <div class=\"check-message\">{{ check.message }}</div>\n }\n </div>\n @if (check.weight) {\n <div class=\"check-weight\">\n <span class=\"weight-label\">Weight:</span> {{ check.weight }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n <!-- Data Comparison -->\n <div class=\"comparison-section\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-exchange-alt\"></i> Data Comparison</h3>\n </div>\n <div class=\"comparison-tabs\">\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'input'\" (click)=\"setComparisonView('input')\">\n <i class=\"fas fa-sign-in-alt\"></i> Input\n </button>\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'expected'\" (click)=\"setComparisonView('expected')\">\n <i class=\"fas fa-bullseye\"></i> Expected\n </button>\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'actual'\" (click)=\"setComparisonView('actual')\">\n <i class=\"fas fa-check-square\"></i> Actual\n </button>\n </div>\n <div class=\"comparison-content\">\n <mj-code-editor\n [value]=\"getComparisonData()\"\n language=\"json\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n }\n\n <!-- Details Tab -->\n @if (activeTab === 'details') {\n <div class=\"details-tab\" [@fadeIn]>\n <div class=\"details-grid\">\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-fingerprint\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Test Run ID</div>\n <div class=\"detail-value monospace\">{{ record.ID }}</div>\n </div>\n </div>\n @if (test) {\n <div class=\"detail-card clickable\" (click)=\"openTest()\">\n <div class=\"detail-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Test</div>\n <div class=\"detail-value link\">{{ test.Name }}</div>\n </div>\n <i class=\"fas fa-external-link-alt detail-action\"></i>\n </div>\n }\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-tag\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Target Type</div>\n <div class=\"detail-value\">{{ record.TargetType || 'N/A' }}</div>\n </div>\n </div>\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-play-circle\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Started At</div>\n <div class=\"detail-value\">{{ record.StartedAt | date:'medium' }}</div>\n </div>\n </div>\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-stop-circle\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Completed At</div>\n <div class=\"detail-value\">{{ record.CompletedAt | date:'medium' }}</div>\n </div>\n </div>\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-hourglass-half\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Duration</div>\n <div class=\"detail-value\">{{ calculateDuration() }}</div>\n </div>\n </div>\n </div>\n <!-- Error Message -->\n @if (record.ErrorMessage) {\n <div class=\"error-section\">\n <div class=\"section-header error\">\n <h3><i class=\"fas fa-exclamation-triangle\"></i> Error Message</h3>\n </div>\n <div class=\"error-content\">\n <mj-code-editor\n [value]=\"record.ErrorMessage\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n }\n <!-- Result Details -->\n @if (parsedData.resultDetails) {\n <div class=\"result-details-section\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-file-code\"></i> Result Details</h3>\n </div>\n <div class=\"result-details-content\">\n <mj-code-editor\n [value]=\"getFormattedResultDetails()\"\n language=\"json\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- AI Runs Tab -->\n @if (activeTab === 'ai-runs') {\n <div class=\"ai-runs-tab\" [@fadeIn]>\n <!-- Loading State -->\n @if (loadingAIRuns) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- AI Agent Runs -->\n @if (!loadingAIRuns && aiAgentRuns.length > 0) {\n <div class=\"ai-section\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-robot\"></i> AI Agent Runs</h3>\n <span class=\"count-badge\">{{ aiAgentRuns.length }}</span>\n </div>\n <div class=\"ai-run-list\">\n @for (run of aiAgentRuns; track run) {\n <div class=\"ai-run-card\" (click)=\"openAIAgentRun(run.ID)\">\n <div class=\"ai-run-icon agent\">\n <i class=\"fas fa-robot\"></i>\n </div>\n <div class=\"ai-run-content\">\n <div class=\"ai-run-name\">{{ run.Agent }}</div>\n <div class=\"ai-run-meta\">\n <span class=\"status-chip\" [class]=\"run.Status.toLowerCase()\">{{ run.Status }}</span>\n @if (run.TotalCost) {\n <span class=\"cost-chip\">\n <i class=\"fas fa-dollar-sign\"></i> {{ run.TotalCost | number:'1.4-4' }}\n </span>\n }\n </div>\n </div>\n <i class=\"fas fa-chevron-right ai-run-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n <!-- AI Prompt Runs -->\n @if (!loadingAIRuns && aiPromptRuns.length > 0) {\n <div class=\"ai-section\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-comment-dots\"></i> AI Prompt Runs</h3>\n <span class=\"count-badge\">{{ aiPromptRuns.length }}</span>\n </div>\n <div class=\"ai-run-list\">\n @for (run of aiPromptRuns; track run) {\n <div class=\"ai-run-card\" (click)=\"openAIPromptRun(run.ID)\">\n <div class=\"ai-run-icon prompt\">\n <i class=\"fas fa-comment-dots\"></i>\n </div>\n <div class=\"ai-run-content\">\n <div class=\"ai-run-name\">{{ run.Prompt || run.Model }}</div>\n <div class=\"ai-run-meta\">\n @if (run.TotalCost) {\n <span class=\"cost-chip\">\n <i class=\"fas fa-dollar-sign\"></i> {{ run.TotalCost | number:'1.4-4' }}\n </span>\n }\n </div>\n </div>\n <i class=\"fas fa-chevron-right ai-run-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n <!-- Empty State -->\n @if (aiRunsLoaded && aiAgentRuns.length === 0 && aiPromptRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-robot\"\n Title=\"No AI Runs\"\n Message=\"This test execution didn't involve any AI agent or prompt runs.\" />\n }\n </div>\n }\n\n <!-- Feedback Tab -->\n @if (activeTab === 'feedback') {\n <div class=\"feedback-tab\" [@fadeIn]>\n <!-- Loading State -->\n @if (loadingFeedback) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-avatar\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n <div class=\"skeleton-line medium\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Feedback List -->\n @if (!loadingFeedback && feedbacks.length > 0) {\n <div class=\"feedback-list\">\n @for (feedback of feedbacks; track feedback) {\n <div class=\"feedback-item\">\n <div class=\"feedback-header\">\n <div class=\"feedback-user\">\n <div class=\"user-avatar\">\n <i class=\"fas fa-user\"></i>\n </div>\n <span class=\"user-name\">{{ feedback.ReviewerUser }}</span>\n </div>\n <div class=\"feedback-date\">\n {{ getRelativeTime(feedback.__mj_CreatedAt) }}\n </div>\n </div>\n <div class=\"feedback-body\">\n <div class=\"feedback-rating\">\n <div class=\"rating-stars\">\n @for (s of [1,2,3,4,5,6,7,8,9,10]; track s) {\n <i class=\"fas fa-star\"\n [class.filled]=\"s <= (feedback.Rating || 0)\"></i>\n }\n </div>\n <span class=\"rating-value\">{{ feedback.Rating }}/10</span>\n </div>\n @if (feedback.IsCorrect !== null) {\n <div class=\"feedback-verdict\">\n <span class=\"verdict-badge\" [class.correct]=\"feedback.IsCorrect\" [class.incorrect]=\"!feedback.IsCorrect\">\n <i class=\"fas\" [class.fa-check]=\"feedback.IsCorrect\" [class.fa-times]=\"!feedback.IsCorrect\"></i>\n {{ feedback.IsCorrect ? 'Marked Correct' : 'Marked Incorrect' }}\n </span>\n </div>\n }\n @if (feedback.CorrectionSummary) {\n <div class=\"feedback-comments\">\n <p>{{ feedback.CorrectionSummary }}</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (feedbackLoaded && feedbacks.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-comments\"\n Title=\"No Feedback Yet\"\n Message=\"No one has reviewed this test run yet. Be the first to provide feedback!\" />\n }\n </div>\n }\n\n <!-- Execution Context Tab -->\n @if (activeTab === 'execution') {\n <div class=\"execution-tab\" [@fadeIn]>\n <mj-execution-context\n [machineName]=\"record.MachineName\"\n [machineId]=\"record.MachineID\"\n [runByUserName]=\"record.RunByUserName\"\n [runByUserEmail]=\"record.RunByUserEmail\"\n [runContextDetailsJson]=\"record.RunContextDetails\">\n </mj-execution-context>\n </div>\n }\n\n <!-- Execution Log Tab -->\n @if (activeTab === 'log') {\n <div class=\"log-tab\" [@fadeIn]>\n <div class=\"log-header\">\n <div class=\"log-title\">\n <i class=\"fas fa-terminal\"></i>\n <h3>Execution Log</h3>\n </div>\n <div class=\"log-actions\">\n <button mjButton (click)=\"copyLogToClipboard()\" variant=\"flat\">\n <i class=\"fas fa-copy\"></i>\n <span class=\"btn-text\">Copy</span>\n </button>\n </div>\n </div>\n <div class=\"log-container\">\n <mj-code-editor\n [value]=\"record.Log || ''\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n }\n </div>\n\n <!-- Keyboard Shortcuts Help (shown on hover of ? icon) -->\n <div class=\"shortcuts-hint\" title=\"Keyboard Shortcuts\">\n <i class=\"fas fa-keyboard\"></i>\n <div class=\"shortcuts-popup\">\n <h4>Keyboard Shortcuts</h4>\n <ul>\n <li><kbd>1-6</kbd> Switch tabs</li>\n <li><kbd>Cmd+R</kbd> Refresh</li>\n <li><kbd>Cmd+Shift+R</kbd> Re-run test</li>\n </ul>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n Test Run Form - World-Class UX\n Premium Testing Dashboard Styles\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-primary-dark: var(--mj-brand-primary-hover);\n --test-success: var(--mj-status-success);\n --test-success-light: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n --test-error: var(--mj-status-error);\n --test-error-light: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n --test-warning: var(--mj-status-warning);\n --test-warning-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-timeout: var(--mj-status-warning);\n --test-timeout-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-running: var(--mj-brand-primary);\n --test-pending: var(--mj-brand-primary);\n --test-skipped: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-muted);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n/* Base Container */\n.test-run-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* ===========================\n Error Banner\n =========================== */\n\n@keyframes slideDown {\n from {\n transform: translateY(-100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n/* ===========================\n Header Section\n =========================== */\n.test-run-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n position: relative;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n flex-wrap: wrap;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.breadcrumb a:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header Content */\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n/* Status Indicator */\n.status-indicator {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.status-indicator:hover {\n transform: scale(1.05);\n}\n\n/* Test Run Info */\n.test-run-info {\n flex: 1;\n min-width: 0;\n}\n\n.test-run-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-run-info h1 .run-id {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.test-run-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n/* Meta Item */\n.meta-item {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n}\n\n.meta-item i {\n font-size: 12px;\n}\n\n/* Header Actions */\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions button {\n white-space: nowrap;\n}\n\n.btn-text {\n margin-left: 6px;\n}\n\n/* ===========================\n Metrics Bar\n =========================== */\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.metric-card {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n transition: var(--test-transition);\n}\n\n.metric-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-sm);\n color: var(--test-primary);\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.metric-content {\n flex: 1;\n min-width: 0;\n}\n\n.metric-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.metric-value {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.metric-detail {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 2px;\n}\n\n/* Progress bar in metric card */\n.metric-progress {\n margin-top: 6px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.progress-bar {\n height: 100%;\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n/* Secondary Info */\n.secondary-info {\n display: flex;\n gap: 12px;\n padding-top: 16px;\n border-top: 1px solid var(--test-border);\n flex-wrap: wrap;\n}\n\n.info-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--test-text-secondary);\n padding: 6px 12px;\n background: var(--test-bg);\n border-radius: 20px;\n transition: var(--test-transition);\n}\n\n.info-chip i {\n font-size: 12px;\n}\n\n.info-chip.clickable {\n cursor: pointer;\n}\n\n.info-chip.clickable:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n}\n\n/* ===========================\n Tabs Navigation\n =========================== */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs::-webkit-scrollbar {\n display: none;\n}\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab i {\n font-size: 15px;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.shortcut-hint {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n/* ===========================\n Tab Content Area\n =========================== */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n/* ===========================\n Overview Tab\n =========================== */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Result Hero Card */\n.result-hero {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 32px;\n text-align: center;\n border: 2px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.result-hero.passed {\n background: var(--test-success-light);\n border-color: var(--test-success);\n}\n\n.result-hero.failed {\n background: var(--test-error-light);\n border-color: var(--test-error);\n}\n\n.result-hero.error {\n background: var(--test-warning-light);\n border-color: var(--test-warning);\n}\n\n.result-hero.timeout {\n background: var(--test-timeout-light);\n border-color: var(--test-timeout);\n}\n\n.result-hero.running,\n.result-hero.pending {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--test-primary-light);\n}\n\n.result-icon-wrapper {\n position: relative;\n display: inline-block;\n margin-bottom: 16px;\n}\n\n.result-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: 50%;\n font-size: 40px;\n margin: 0 auto;\n box-shadow: var(--test-shadow-md);\n}\n\n.result-hero.passed .result-icon { color: var(--test-success); }\n.result-hero.failed .result-icon { color: var(--test-error); }\n.result-hero.error .result-icon { color: var(--test-warning); }\n.result-hero.timeout .result-icon { color: var(--test-timeout); }\n.result-hero.running .result-icon,\n.result-hero.pending .result-icon { color: var(--test-primary); }\n\n.result-pulse {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 100px;\n height: 100px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n animation: pulse 2s ease-in-out infinite;\n}\n\n@keyframes pulse {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.5; }\n 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0; }\n}\n\n.result-text h2 {\n margin: 0 0 12px 0;\n font-size: clamp(24px, 5vw, 32px);\n font-weight: 800;\n color: var(--test-text);\n}\n\n.result-details {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.result-score {\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.result-divider {\n color: var(--test-border);\n}\n\n.result-checks {\n font-size: 16px;\n color: var(--test-text-muted);\n}\n\n/* Section Headers */\n.section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n gap: 12px;\n}\n\n.section-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-header h3 i {\n color: var(--test-primary);\n}\n\n.section-header.error h3 i {\n color: var(--test-error);\n}\n\n.check-summary {\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n/* Check Results Section */\n.check-results {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.check-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.check-item {\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n transition: var(--test-transition);\n animation: fadeIn 0.3s ease-out backwards;\n}\n\n.check-item:hover {\n transform: translateX(4px);\n}\n\n.check-item.passed {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-success) 40%, var(--mj-bg-surface));\n}\n\n.check-item.failed {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-bg-surface));\n}\n\n.check-status {\n font-size: 20px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.check-item.passed .check-status { color: var(--test-success); }\n.check-item.failed .check-status { color: var(--test-error); }\n\n.check-content {\n flex: 1;\n min-width: 0;\n}\n\n.check-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.check-message {\n font-size: 13px;\n color: var(--test-text-secondary);\n line-height: 1.5;\n word-wrap: break-word;\n}\n\n.check-weight {\n font-size: 12px;\n color: var(--test-text-muted);\n flex-shrink: 0;\n text-align: right;\n}\n\n.weight-label {\n font-weight: 500;\n}\n\n/* Comparison Section */\n.comparison-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-tabs {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.comparison-tab {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 16px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.comparison-tab:hover {\n color: var(--test-text);\n background: var(--mj-bg-overlay);\n}\n\n.comparison-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-content {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n/* ===========================\n Details Tab\n =========================== */\n.details-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.detail-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n transition: var(--test-transition);\n}\n\n.detail-card.clickable {\n cursor: pointer;\n}\n\n.detail-card.clickable:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.detail-icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.detail-content {\n flex: 1;\n min-width: 0;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.detail-value {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n.detail-value.monospace {\n font-family: 'SF Mono', Monaco, 'Courier New', monospace;\n font-size: 12px;\n}\n\n.detail-value.link {\n color: var(--test-primary);\n}\n\n.detail-action {\n color: var(--test-text-muted);\n font-size: 12px;\n transition: var(--test-transition);\n}\n\n.detail-card.clickable:hover .detail-action {\n color: var(--test-primary);\n}\n\n/* Error Section */\n.error-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.error-content {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-bg-surface));\n}\n\n/* Result Details Section */\n.result-details-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.result-details-content {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n/* ===========================\n AI Runs Tab\n =========================== */\n.ai-runs-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n.ai-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.count-badge {\n background: var(--test-bg);\n color: var(--test-text-secondary);\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.ai-run-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.ai-run-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.ai-run-card:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-primary);\n color: var(--mj-text-inverse);\n border-radius: var(--test-radius-md);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon.agent {\n background: var(--test-primary);\n}\n\n.ai-run-icon.prompt {\n background: var(--mj-brand-primary);\n}\n\n.ai-run-content {\n flex: 1;\n min-width: 0;\n}\n\n.ai-run-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ai-run-meta {\n display: flex;\n gap: 10px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.complete,\n.status-chip.completed,\n.status-chip.passed {\n background: var(--test-success-light);\n color: var(--mj-status-success);\n}\n\n.status-chip.failed,\n.status-chip.error {\n background: var(--test-error-light);\n color: var(--mj-status-error);\n}\n\n.status-chip.running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n}\n\n.cost-chip {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n color: var(--test-text-muted);\n}\n\n.ai-run-arrow {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.ai-run-card:hover .ai-run-arrow {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* ===========================\n Feedback Tab\n =========================== */\n.feedback-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.feedback-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-item {\n padding: 20px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.feedback-item:hover {\n border-color: var(--test-primary-light);\n}\n\n.feedback-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.feedback-user {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.user-avatar {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-primary);\n font-size: 14px;\n}\n\n.user-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-date {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.feedback-body {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.feedback-rating {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.rating-stars {\n display: flex;\n gap: 2px;\n}\n\n.rating-stars i {\n font-size: 14px;\n color: var(--test-border);\n}\n\n.rating-stars i.filled {\n color: var(--mj-status-warning);\n}\n\n.rating-value {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-verdict {\n display: flex;\n}\n\n.verdict-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.verdict-badge.correct {\n background: var(--test-success-light);\n color: var(--mj-status-success);\n}\n\n.verdict-badge.incorrect {\n background: var(--test-error-light);\n color: var(--mj-status-error);\n}\n\n.feedback-comments {\n padding: 14px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n border-left: 3px solid var(--test-primary);\n}\n\n.feedback-comments p {\n margin: 0;\n font-size: 14px;\n line-height: 1.6;\n color: var(--test-text);\n}\n\n/* ===========================\n Log Tab\n =========================== */\n.log-tab {\n display: flex;\n flex-direction: column;\n gap: 0;\n height: 100%;\n animation: fadeIn 0.3s ease-out;\n}\n\n.log-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: var(--test-surface);\n padding: 16px 20px;\n border-radius: var(--test-radius-lg) var(--test-radius-lg) 0 0;\n border: 1px solid var(--test-border);\n border-bottom: none;\n}\n\n.log-title {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.log-title i {\n color: var(--test-text-secondary);\n font-size: 16px;\n}\n\n.log-title h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.log-actions {\n display: flex;\n gap: 8px;\n}\n\n.log-container {\n flex: 1;\n border-radius: 0 0 var(--test-radius-lg) var(--test-radius-lg);\n overflow: hidden;\n min-height: 300px;\n border: 1px solid var(--test-border);\n border-top: none;\n}\n\n/* ===========================\n Loading States & Skeletons\n =========================== */\n.loading-state {\n padding: 20px;\n}\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon,\n.skeleton-avatar {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-avatar {\n border-radius: 50%;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.medium { width: 55%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* ===========================\n Keyboard Shortcuts Help\n =========================== */\n.shortcuts-hint {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 100;\n}\n\n.shortcuts-hint > i {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n cursor: pointer;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.shortcuts-hint:hover > i {\n color: var(--test-primary);\n border-color: var(--test-primary-light);\n}\n\n.shortcuts-popup {\n display: none;\n position: absolute;\n bottom: 50px;\n right: 0;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 16px;\n box-shadow: var(--test-shadow-lg);\n min-width: 200px;\n}\n\n.shortcuts-hint:hover .shortcuts-popup {\n display: block;\n animation: fadeIn 0.2s ease-out;\n}\n\n.shortcuts-popup h4 {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.shortcuts-popup ul {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.shortcuts-popup li {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 6px 0;\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n.shortcuts-popup kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* ===========================\n Responsive Design - Tablet\n =========================== */\n@media (max-width: 1024px) {\n .metrics-bar {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .details-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .shortcuts-hint {\n display: none;\n }\n}\n\n/* ===========================\n Responsive Design - Mobile\n =========================== */\n@media (max-width: 768px) {\n .test-run-form {\n height: auto;\n min-height: 100%;\n }\n\n .test-run-header {\n padding: 16px;\n }\n\n .breadcrumb {\n margin-bottom: 12px;\n }\n\n .breadcrumb ol {\n font-size: 12px;\n }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left {\n width: 100%;\n }\n\n .status-indicator {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-run-info h1 {\n font-size: 18px;\n }\n\n .test-run-meta {\n gap: 8px;\n }\n\n .status-badge {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button {\n flex: 1;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card {\n padding: 12px;\n }\n\n .metric-icon {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .metric-value {\n font-size: 14px;\n }\n\n .tabs {\n padding: 0 12px;\n }\n\n .tab {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab i {\n font-size: 14px;\n }\n\n .shortcut-hint {\n display: none;\n }\n\n .tab-content {\n padding: 16px;\n }\n\n .result-hero {\n padding: 24px 20px;\n }\n\n .result-icon {\n width: 64px;\n height: 64px;\n font-size: 32px;\n }\n\n .result-text h2 {\n font-size: 24px;\n }\n\n .result-score {\n font-size: 16px;\n }\n\n .check-results,\n .comparison-section,\n .ai-section,\n .feedback-item {\n padding: 18px;\n }\n\n .check-item {\n padding: 12px;\n }\n\n .comparison-tabs {\n flex-direction: column;\n gap: 4px;\n }\n\n .comparison-tab {\n text-align: center;\n }\n\n .details-grid {\n grid-template-columns: 1fr;\n }\n\n .detail-card {\n padding: 14px;\n }\n\n .ai-run-card {\n padding: 14px;\n }\n\n .ai-run-icon {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .ai-run-meta {\n flex-direction: column;\n gap: 4px;\n }\n\n .feedback-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .log-header {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n\n .log-actions {\n justify-content: stretch;\n }\n\n .log-actions button {\n flex: 1;\n }\n}\n\n/* ===========================\n Responsive Design - Small Mobile\n =========================== */\n@media (max-width: 480px) {\n .test-run-header {\n padding: 12px;\n }\n\n .header-left {\n gap: 12px;\n }\n\n .status-indicator {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-run-info h1 {\n font-size: 16px;\n }\n\n .metrics-bar {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card {\n padding: 10px;\n flex-direction: column;\n text-align: center;\n }\n\n .metric-icon {\n margin-bottom: 8px;\n }\n\n .metric-label {\n font-size: 9px;\n }\n\n .metric-value {\n font-size: 14px;\n }\n\n .tabs {\n padding: 0 8px;\n }\n\n .tab {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge {\n display: none;\n }\n\n .tab-content {\n padding: 12px;\n }\n\n .result-hero {\n padding: 20px 16px;\n }\n\n .result-icon {\n width: 56px;\n height: 56px;\n font-size: 28px;\n }\n\n .result-text h2 {\n font-size: 20px;\n }\n\n .result-score {\n font-size: 14px;\n }\n\n .result-checks {\n font-size: 12px;\n }\n\n .section-header h3 {\n font-size: 16px;\n }\n\n .check-item {\n flex-direction: column;\n gap: 8px;\n }\n\n .check-weight {\n text-align: left;\n }\n}\n\n/* ===========================\n Touch Device Optimizations\n =========================== */\n@media (hover: none) and (pointer: coarse) {\n .tab,\n .comparison-tab,\n .ai-run-card,\n .check-item,\n .feedback-item,\n .detail-card.clickable {\n -webkit-tap-highlight-color: transparent;\n }\n\n .ai-run-card:active,\n .detail-card.clickable:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n transform: scale(0.98);\n }\n\n .tab:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n /* Larger touch targets */\n .tab {\n min-height: 48px;\n }\n\n .ai-run-card,\n .detail-card {\n min-height: 64px;\n }\n}\n\n/* ===========================\n High Contrast Mode\n =========================== */\n@media (prefers-contrast: high) {\n .status-badge {\n border: 2px solid currentColor;\n }\n\n .check-item {\n border-width: 2px;\n }\n\n .tab.active {\n border-bottom-width: 4px;\n }\n}\n\n/* ===========================\n Reduced Motion\n =========================== */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon,\n .skeleton-avatar,\n .skeleton-line {\n animation: none;\n background: var(--mj-border-default);\n }\n\n .result-pulse {\n animation: none;\n display: none;\n }\n}\n\n/* ===========================\n Print Styles\n =========================== */\n@media print {\n .test-run-form {\n background: var(--mj-bg-surface);\n height: auto;\n }\n\n .header-actions,\n .tabs-container,\n .shortcuts-hint,\n .log-actions {\n display: none !important;\n }\n\n .tab-content {\n overflow: visible;\n padding: 0;\n }\n\n .result-hero,\n .check-results,\n .details-grid,\n .ai-section,\n .feedback-item {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid var(--mj-border-default);\n }\n\n .comparison-content,\n .log-container {\n max-height: none;\n overflow: visible;\n }\n}\n\n/* ===========================\n Tags Bar - Sleek Inline Display\n =========================== */\n.tags-bar {\n margin-top: 16px;\n padding: 8px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n border-radius: 8px;\n max-width: 600px;\n}\n\n.tags-bar-content {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.tags-bar-label {\n color: var(--test-text-secondary);\n font-size: 14px;\n}\n\n.tags-bar-label i {\n opacity: 0.6;\n}\n\n.tags-bar-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1;\n}\n\n.tag-inline {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.01em;\n}\n\n.tags-bar-empty {\n font-size: 12px;\n color: var(--test-text-secondary);\n opacity: 0.7;\n flex: 1;\n}\n\n.tags-bar-edit {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: transparent;\n border: 1px dashed var(--test-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--test-text-secondary);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.tags-bar-edit:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tags-bar-edit i {\n font-size: 10px;\n}\n\n/* ===========================\n Tags Editor Panel - Expanded Edit Mode\n =========================== */\n.tags-editor-panel {\n margin-top: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n border-radius: var(--test-radius-md);\n overflow: hidden;\n box-shadow: var(--mj-shadow-md);\n max-width: 600px;\n}\n\n.tags-editor-header {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.tags-editor-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tags-editor-body {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.tags-editor-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.tag-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n color: var(--test-primary);\n border-radius: 14px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n background: transparent;\n border: none;\n color: var(--test-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--test-transition);\n}\n\n.tag-remove-btn:hover {\n opacity: 1;\n background: var(--test-error-light);\n color: var(--test-error);\n}\n\n.tags-empty-hint {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-style: italic;\n padding: 4px 0;\n}\n\n.tags-editor-input {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.tag-text-input {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--test-bg);\n}\n\n.tag-text-input:focus {\n outline: none;\n border-color: var(--test-primary);\n background: var(--test-surface);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.tag-text-input::placeholder {\n color: var(--test-text-secondary);\n opacity: 0.6;\n}\n\n.tags-editor-footer {\n display: flex;\n justify-content: flex-start;\n gap: 8px;\n padding: 12px 16px;\n background: var(--test-bg);\n border-top: 1px solid var(--test-border);\n}\n\n/* Mobile Responsive for Tags */\n@media (max-width: 768px) {\n .tags-bar {\n padding: 8px 12px;\n }\n\n .tags-bar-content {\n gap: 8px;\n }\n\n .tag-inline {\n padding: 3px 8px;\n font-size: 10px;\n }\n\n .tags-editor-panel {\n margin-top: 12px;\n }\n\n .tags-editor-body {\n padding: 12px;\n }\n\n .tags-editor-footer {\n padding: 10px 12px;\n }\n}\n"] }]
|
|
1581
1563
|
}], null, { handleKeyboardShortcut: [{
|
|
1582
1564
|
type: HostListener,
|
|
1583
1565
|
args: ['document:keydown', ['$event']]
|