inspect-ai 0.3.62__py3-none-any.whl → 0.3.64__py3-none-any.whl
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.
- inspect_ai/_cli/cache.py +8 -7
- inspect_ai/_cli/common.py +0 -12
- inspect_ai/_cli/eval.py +32 -4
- inspect_ai/_cli/info.py +1 -0
- inspect_ai/_cli/list.py +1 -1
- inspect_ai/_cli/log.py +2 -0
- inspect_ai/_cli/main.py +1 -1
- inspect_ai/_cli/sandbox.py +4 -1
- inspect_ai/_cli/score.py +181 -32
- inspect_ai/_cli/trace.py +10 -0
- inspect_ai/_cli/view.py +4 -2
- inspect_ai/_display/core/active.py +2 -3
- inspect_ai/_display/core/config.py +7 -1
- inspect_ai/_display/textual/widgets/samples.py +4 -3
- inspect_ai/_display/textual/widgets/sandbox.py +6 -0
- inspect_ai/_eval/eval.py +104 -101
- inspect_ai/_eval/evalset.py +75 -75
- inspect_ai/_eval/loader.py +122 -12
- inspect_ai/_eval/registry.py +1 -1
- inspect_ai/_eval/run.py +14 -0
- inspect_ai/_eval/score.py +125 -36
- inspect_ai/_eval/task/log.py +105 -4
- inspect_ai/_eval/task/results.py +92 -38
- inspect_ai/_eval/task/run.py +9 -2
- inspect_ai/_eval/task/sandbox.py +35 -2
- inspect_ai/_eval/task/task.py +49 -46
- inspect_ai/_util/constants.py +1 -1
- inspect_ai/_util/content.py +8 -0
- inspect_ai/_util/error.py +2 -0
- inspect_ai/_util/file.py +15 -1
- inspect_ai/_util/hash.py +1 -1
- inspect_ai/_util/logger.py +4 -2
- inspect_ai/_util/registry.py +7 -1
- inspect_ai/_view/view.py +1 -2
- inspect_ai/_view/www/.vscode/extensions.json +3 -0
- inspect_ai/_view/www/.vscode/settings.json +8 -0
- inspect_ai/_view/www/App.css +97 -29
- inspect_ai/_view/www/README.md +1 -1
- inspect_ai/_view/www/dist/assets/index.css +16663 -14674
- inspect_ai/_view/www/dist/assets/index.js +58808 -51348
- inspect_ai/_view/www/dist/index.html +1 -1
- inspect_ai/_view/www/index.html +2 -2
- inspect_ai/_view/www/log-schema.json +87 -73
- inspect_ai/_view/www/package.json +22 -4
- inspect_ai/_view/www/postcss.config.cjs +8 -9
- inspect_ai/_view/www/src/{App.mjs → App.tsx} +356 -365
- inspect_ai/_view/www/src/AppErrorBoundary.tsx +47 -0
- inspect_ai/_view/www/src/api/api-browser.ts +2 -2
- inspect_ai/_view/www/src/api/api-http.ts +3 -5
- inspect_ai/_view/www/src/api/api-vscode.ts +6 -6
- inspect_ai/_view/www/src/api/client-api.ts +4 -4
- inspect_ai/_view/www/src/api/index.ts +4 -4
- inspect_ai/_view/www/src/api/{Types.ts → types.ts} +25 -9
- inspect_ai/_view/www/src/appearance/colors.ts +9 -0
- inspect_ai/_view/www/src/appearance/fonts.ts +39 -0
- inspect_ai/_view/www/src/appearance/icons.ts +100 -0
- inspect_ai/_view/www/src/appearance/{Styles.mjs → styles.ts} +2 -32
- inspect_ai/_view/www/src/components/AnsiDisplay.tsx +198 -0
- inspect_ai/_view/www/src/components/AsciinemaPlayer.tsx +86 -0
- inspect_ai/_view/www/src/components/Card.css +60 -0
- inspect_ai/_view/www/src/components/Card.tsx +109 -0
- inspect_ai/_view/www/src/components/CopyButton.module.css +11 -0
- inspect_ai/_view/www/src/components/CopyButton.tsx +58 -0
- inspect_ai/_view/www/src/components/DownloadButton.css +4 -0
- inspect_ai/_view/www/src/components/DownloadButton.tsx +25 -0
- inspect_ai/_view/www/src/components/DownloadPanel.css +10 -0
- inspect_ai/_view/www/src/components/DownloadPanel.tsx +30 -0
- inspect_ai/_view/www/src/components/EmptyPanel.css +12 -0
- inspect_ai/_view/www/src/components/EmptyPanel.tsx +15 -0
- inspect_ai/_view/www/src/components/ErrorPanel.css +37 -0
- inspect_ai/_view/www/src/components/ErrorPanel.tsx +39 -0
- inspect_ai/_view/www/src/components/ExpandablePanel.css +40 -0
- inspect_ai/_view/www/src/components/ExpandablePanel.tsx +115 -0
- inspect_ai/_view/www/src/components/FindBand.css +49 -0
- inspect_ai/_view/www/src/components/FindBand.tsx +130 -0
- inspect_ai/_view/www/src/components/HumanBaselineView.css +41 -0
- inspect_ai/_view/www/src/components/HumanBaselineView.tsx +162 -0
- inspect_ai/_view/www/src/components/JsonPanel.css +20 -0
- inspect_ai/_view/www/src/components/JsonPanel.tsx +82 -0
- inspect_ai/_view/www/src/components/LabeledValue.css +20 -0
- inspect_ai/_view/www/src/components/LabeledValue.tsx +41 -0
- inspect_ai/_view/www/src/components/LargeModal.module.css +54 -0
- inspect_ai/_view/www/src/components/LargeModal.tsx +189 -0
- inspect_ai/_view/www/src/components/LightboxCarousel.css +95 -0
- inspect_ai/_view/www/src/components/LightboxCarousel.tsx +132 -0
- inspect_ai/_view/www/src/components/MarkdownDiv.css +3 -0
- inspect_ai/_view/www/src/components/MarkdownDiv.tsx +133 -0
- inspect_ai/_view/www/src/components/MessageBand.css +43 -0
- inspect_ai/_view/www/src/components/MessageBand.tsx +39 -0
- inspect_ai/_view/www/src/components/MorePopOver.css +0 -0
- inspect_ai/_view/www/src/components/MorePopOver.tsx +67 -0
- inspect_ai/_view/www/src/components/NavPills.module.css +18 -0
- inspect_ai/_view/www/src/components/NavPills.tsx +101 -0
- inspect_ai/_view/www/src/components/ProgressBar.module.css +37 -0
- inspect_ai/_view/www/src/components/ProgressBar.tsx +22 -0
- inspect_ai/_view/www/src/components/TabSet.module.css +40 -0
- inspect_ai/_view/www/src/components/TabSet.tsx +215 -0
- inspect_ai/_view/www/src/components/ToolButton.css +3 -0
- inspect_ai/_view/www/src/components/ToolButton.tsx +27 -0
- inspect_ai/_view/www/src/components/VirtualList.module.css +19 -0
- inspect_ai/_view/www/src/components/VirtualList.tsx +292 -0
- inspect_ai/_view/www/src/{index.js → index.tsx} +45 -19
- inspect_ai/_view/www/src/{log → logfile}/remoteLogFile.ts +3 -8
- inspect_ai/_view/www/src/{utils/remoteZipFile.mjs → logfile/remoteZipFile.ts} +86 -80
- inspect_ai/_view/www/src/metadata/MetaDataGrid.tsx +83 -0
- inspect_ai/_view/www/src/metadata/MetaDataView.module.css +35 -0
- inspect_ai/_view/www/src/metadata/MetaDataView.tsx +95 -0
- inspect_ai/_view/www/src/metadata/MetadataGrid.module.css +15 -0
- inspect_ai/_view/www/src/metadata/RenderedContent.module.css +12 -0
- inspect_ai/_view/www/src/{components/RenderedContent/RenderedContent.mjs → metadata/RenderedContent.tsx} +92 -73
- inspect_ai/_view/www/src/metadata/types.ts +18 -0
- inspect_ai/_view/www/src/plan/DatasetDetailView.module.css +3 -0
- inspect_ai/_view/www/src/plan/DatasetDetailView.tsx +37 -0
- inspect_ai/_view/www/src/plan/DetailStep.module.css +9 -0
- inspect_ai/_view/www/src/plan/DetailStep.tsx +31 -0
- inspect_ai/_view/www/src/plan/PlanCard.tsx +28 -0
- inspect_ai/_view/www/src/plan/PlanDetailView.module.css +48 -0
- inspect_ai/_view/www/src/plan/PlanDetailView.tsx +324 -0
- inspect_ai/_view/www/src/plan/ScorerDetailView.module.css +3 -0
- inspect_ai/_view/www/src/plan/ScorerDetailView.tsx +30 -0
- inspect_ai/_view/www/src/plan/SolverDetailView.module.css +15 -0
- inspect_ai/_view/www/src/plan/SolverDetailView.tsx +32 -0
- inspect_ai/_view/www/src/samples/InlineSampleDisplay.module.css +8 -0
- inspect_ai/_view/www/src/samples/InlineSampleDisplay.tsx +53 -0
- inspect_ai/_view/www/src/samples/SampleDialog.tsx +122 -0
- inspect_ai/_view/www/src/samples/SampleDisplay.module.css +29 -0
- inspect_ai/_view/www/src/samples/SampleDisplay.tsx +331 -0
- inspect_ai/_view/www/src/samples/SampleSummaryView.module.css +24 -0
- inspect_ai/_view/www/src/samples/SampleSummaryView.tsx +177 -0
- inspect_ai/_view/www/src/samples/SamplesTools.tsx +52 -0
- inspect_ai/_view/www/src/samples/chat/ChatMessage.module.css +29 -0
- inspect_ai/_view/www/src/samples/chat/ChatMessage.tsx +76 -0
- inspect_ai/_view/www/src/samples/chat/ChatMessageRenderer.tsx +60 -0
- inspect_ai/_view/www/src/samples/chat/ChatMessageRow.module.css +9 -0
- inspect_ai/_view/www/src/samples/chat/ChatMessageRow.tsx +57 -0
- inspect_ai/_view/www/src/samples/chat/ChatView.tsx +47 -0
- inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.module.css +4 -0
- inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.tsx +58 -0
- inspect_ai/_view/www/src/samples/chat/MessageContent.module.css +4 -0
- inspect_ai/_view/www/src/samples/chat/MessageContent.tsx +157 -0
- inspect_ai/_view/www/src/samples/chat/MessageContents.module.css +3 -0
- inspect_ai/_view/www/src/samples/chat/MessageContents.tsx +133 -0
- inspect_ai/_view/www/src/samples/chat/messages.ts +112 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx +147 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolInput.module.css +14 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx +76 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolOutput.module.css +19 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolOutput.tsx +60 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolTitle.module.css +4 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolTitle.tsx +18 -0
- inspect_ai/_view/www/src/samples/chat/tools/tool.ts +92 -0
- inspect_ai/_view/www/src/samples/descriptor/samplesDescriptor.tsx +365 -0
- inspect_ai/_view/www/src/samples/descriptor/score/BooleanScoreDescriptor.module.css +22 -0
- inspect_ai/_view/www/src/samples/descriptor/score/BooleanScoreDescriptor.tsx +26 -0
- inspect_ai/_view/www/src/samples/descriptor/score/CategoricalScoreDescriptor.tsx +18 -0
- inspect_ai/_view/www/src/samples/descriptor/score/NumericScoreDescriptor.tsx +27 -0
- inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.module.css +18 -0
- inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.tsx +71 -0
- inspect_ai/_view/www/src/samples/descriptor/score/OtherScoreDescriptor.tsx +20 -0
- inspect_ai/_view/www/src/samples/descriptor/score/PassFailScoreDescriptor.module.css +28 -0
- inspect_ai/_view/www/src/samples/descriptor/score/PassFailScoreDescriptor.tsx +81 -0
- inspect_ai/_view/www/src/samples/descriptor/score/ScoreDescriptor.tsx +99 -0
- inspect_ai/_view/www/src/samples/descriptor/types.ts +55 -0
- inspect_ai/_view/www/src/samples/error/FlatSampleErrorView.module.css +19 -0
- inspect_ai/_view/www/src/samples/error/FlatSampleErrorView.tsx +22 -0
- inspect_ai/_view/www/src/samples/error/SampleErrorView.module.css +17 -0
- inspect_ai/_view/www/src/samples/error/SampleErrorView.tsx +31 -0
- inspect_ai/_view/www/src/samples/error/error.ts +15 -0
- inspect_ai/_view/www/src/samples/list/SampleFooter.module.css +9 -0
- inspect_ai/_view/www/src/samples/list/SampleFooter.tsx +14 -0
- inspect_ai/_view/www/src/samples/list/SampleHeader.module.css +13 -0
- inspect_ai/_view/www/src/samples/list/SampleHeader.tsx +36 -0
- inspect_ai/_view/www/src/samples/list/SampleList.module.css +11 -0
- inspect_ai/_view/www/src/samples/list/SampleList.tsx +247 -0
- inspect_ai/_view/www/src/samples/list/SampleRow.module.css +33 -0
- inspect_ai/_view/www/src/samples/list/SampleRow.tsx +98 -0
- inspect_ai/_view/www/src/samples/list/SampleSeparator.module.css +6 -0
- inspect_ai/_view/www/src/samples/list/SampleSeparator.tsx +24 -0
- inspect_ai/_view/www/src/samples/sample-tools/EpochFilter.module.css +9 -0
- inspect_ai/_view/www/src/samples/sample-tools/EpochFilter.tsx +51 -0
- inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.module.css +16 -0
- inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.tsx +175 -0
- inspect_ai/_view/www/src/samples/sample-tools/SortFilter.module.css +9 -0
- inspect_ai/_view/www/src/samples/sample-tools/SortFilter.tsx +186 -0
- inspect_ai/_view/www/src/samples/{tools/filters.mjs → sample-tools/filters.ts} +86 -81
- inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.module.css +16 -0
- inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.tsx +288 -0
- inspect_ai/_view/www/src/samples/sample-tools/sample-filter/completions.ts +346 -0
- inspect_ai/_view/www/src/samples/sample-tools/sample-filter/language.ts +19 -0
- inspect_ai/_view/www/src/samples/sample-tools/sample-filter/tokenize.ts +97 -0
- inspect_ai/_view/www/src/samples/{SampleLimit.mjs → sampleLimit.ts} +3 -6
- inspect_ai/_view/www/src/samples/scores/SampleScoreView.module.css +53 -0
- inspect_ai/_view/www/src/samples/scores/SampleScoreView.tsx +168 -0
- inspect_ai/_view/www/src/samples/scores/SampleScores.module.css +5 -0
- inspect_ai/_view/www/src/samples/scores/SampleScores.tsx +37 -0
- inspect_ai/_view/www/src/samples/transcript/ApprovalEventView.tsx +66 -0
- inspect_ai/_view/www/src/samples/transcript/ErrorEventView.tsx +51 -0
- inspect_ai/_view/www/src/samples/transcript/InfoEventView.module.css +3 -0
- inspect_ai/_view/www/src/samples/transcript/InfoEventView.tsx +54 -0
- inspect_ai/_view/www/src/samples/transcript/InputEventView.tsx +48 -0
- inspect_ai/_view/www/src/samples/transcript/LoggerEventView.module.css +6 -0
- inspect_ai/_view/www/src/samples/transcript/LoggerEventView.tsx +36 -0
- inspect_ai/_view/www/src/samples/transcript/ModelEventView.module.css +43 -0
- inspect_ai/_view/www/src/samples/transcript/ModelEventView.tsx +223 -0
- inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.module.css +23 -0
- inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.tsx +112 -0
- inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.tsx +75 -0
- inspect_ai/_view/www/src/samples/transcript/SampleTranscript.tsx +22 -0
- inspect_ai/_view/www/src/samples/transcript/ScoreEventView.module.css +15 -0
- inspect_ai/_view/www/src/samples/transcript/ScoreEventView.tsx +100 -0
- inspect_ai/_view/www/src/samples/transcript/StepEventView.tsx +171 -0
- inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.module.css +19 -0
- inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.tsx +133 -0
- inspect_ai/_view/www/src/samples/transcript/ToolEventView.module.css +10 -0
- inspect_ai/_view/www/src/samples/transcript/ToolEventView.tsx +92 -0
- inspect_ai/_view/www/src/samples/transcript/TranscriptView.module.css +49 -0
- inspect_ai/_view/www/src/samples/transcript/TranscriptView.tsx +449 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventNav.module.css +5 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventNav.tsx +43 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventNavs.module.css +3 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventNavs.tsx +39 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventPanel.module.css +25 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventPanel.tsx +191 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventRow.module.css +13 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventRow.tsx +32 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventSection.module.css +8 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventSection.tsx +29 -0
- inspect_ai/_view/www/src/samples/transcript/state/StateDiffView.tsx +67 -0
- inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.tsx +285 -0
- inspect_ai/_view/www/src/samples/transcript/state/StateEventRenders.module.css +10 -0
- inspect_ai/_view/www/src/samples/transcript/state/StateEventView.module.css +9 -0
- inspect_ai/_view/www/src/samples/transcript/state/StateEventView.tsx +346 -0
- inspect_ai/_view/www/src/samples/transcript/types.ts +58 -0
- inspect_ai/_view/www/src/types/log.d.ts +108 -19
- inspect_ai/_view/www/src/types/prism.d.ts +11 -0
- inspect_ai/_view/www/src/types.ts +71 -0
- inspect_ai/_view/www/src/usage/ModelTokenTable.tsx +28 -0
- inspect_ai/_view/www/src/usage/ModelUsagePanel.module.css +24 -0
- inspect_ai/_view/www/src/usage/ModelUsagePanel.tsx +97 -0
- inspect_ai/_view/www/src/usage/TokenTable.module.css +17 -0
- inspect_ai/_view/www/src/usage/TokenTable.tsx +91 -0
- inspect_ai/_view/www/src/usage/UsageCard.module.css +15 -0
- inspect_ai/_view/www/src/usage/UsageCard.tsx +67 -0
- inspect_ai/_view/www/src/utils/attachments.ts +42 -0
- inspect_ai/_view/www/src/utils/{Base64.mjs → base64.ts} +1 -6
- inspect_ai/_view/www/src/{components/Browser.mjs → utils/browser.ts} +0 -1
- inspect_ai/_view/www/src/utils/debugging.ts +28 -0
- inspect_ai/_view/www/src/utils/dom.ts +30 -0
- inspect_ai/_view/www/src/utils/format.ts +194 -0
- inspect_ai/_view/www/src/utils/git.ts +7 -0
- inspect_ai/_view/www/src/utils/html.ts +6 -0
- inspect_ai/_view/www/src/utils/http.ts +14 -0
- inspect_ai/_view/www/src/utils/{Path.mjs → path.ts} +2 -9
- inspect_ai/_view/www/src/utils/{Print.mjs → print.ts} +34 -26
- inspect_ai/_view/www/src/utils/queue.ts +51 -0
- inspect_ai/_view/www/src/utils/sync.ts +114 -0
- inspect_ai/_view/www/src/utils/{Type.mjs → type.ts} +3 -6
- inspect_ai/_view/www/src/utils/vscode.ts +13 -0
- inspect_ai/_view/www/src/workspace/WorkSpace.tsx +324 -0
- inspect_ai/_view/www/src/workspace/WorkSpaceView.module.css +33 -0
- inspect_ai/_view/www/src/workspace/WorkSpaceView.tsx +158 -0
- inspect_ai/_view/www/src/workspace/error/TaskErrorPanel.module.css +3 -0
- inspect_ai/_view/www/src/workspace/error/TaskErrorPanel.tsx +28 -0
- inspect_ai/_view/www/src/workspace/navbar/Navbar.module.css +54 -0
- inspect_ai/_view/www/src/workspace/navbar/Navbar.tsx +68 -0
- inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.module.css +52 -0
- inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.tsx +114 -0
- inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.module.css +90 -0
- inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.tsx +180 -0
- inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.module.css +28 -0
- inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.tsx +226 -0
- inspect_ai/_view/www/src/workspace/navbar/StatusPanel.module.css +14 -0
- inspect_ai/_view/www/src/workspace/navbar/StatusPanel.tsx +61 -0
- inspect_ai/_view/www/src/workspace/sidebar/EvalStatus.module.css +15 -0
- inspect_ai/_view/www/src/workspace/sidebar/EvalStatus.tsx +71 -0
- inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.module.css +5 -0
- inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.tsx +56 -0
- inspect_ai/_view/www/src/workspace/sidebar/Sidebar.module.css +68 -0
- inspect_ai/_view/www/src/workspace/sidebar/Sidebar.tsx +85 -0
- inspect_ai/_view/www/src/workspace/sidebar/SidebarLogEntry.module.css +29 -0
- inspect_ai/_view/www/src/workspace/sidebar/SidebarLogEntry.tsx +95 -0
- inspect_ai/_view/www/src/workspace/sidebar/SidebarScoreView.module.css +23 -0
- inspect_ai/_view/www/src/workspace/sidebar/SidebarScoreView.tsx +43 -0
- inspect_ai/_view/www/src/workspace/sidebar/SidebarScoresView.module.css +35 -0
- inspect_ai/_view/www/src/workspace/sidebar/SidebarScoresView.tsx +63 -0
- inspect_ai/_view/www/src/workspace/tabs/InfoTab.module.css +0 -0
- inspect_ai/_view/www/src/workspace/tabs/InfoTab.tsx +70 -0
- inspect_ai/_view/www/src/workspace/tabs/JsonTab.module.css +5 -0
- inspect_ai/_view/www/src/workspace/tabs/JsonTab.tsx +46 -0
- inspect_ai/_view/www/src/workspace/tabs/SamplesTab.tsx +204 -0
- inspect_ai/_view/www/src/workspace/tabs/grouping.ts +195 -0
- inspect_ai/_view/www/src/workspace/tabs/types.ts +19 -0
- inspect_ai/_view/www/src/workspace/types.ts +10 -0
- inspect_ai/_view/www/src/workspace/utils.ts +34 -0
- inspect_ai/_view/www/tsconfig.json +23 -9
- inspect_ai/_view/www/vite.config.js +8 -17
- inspect_ai/_view/www/yarn.lock +627 -556
- inspect_ai/approval/_approval.py +2 -0
- inspect_ai/approval/_approver.py +4 -4
- inspect_ai/approval/_auto.py +1 -1
- inspect_ai/approval/_human/approver.py +3 -0
- inspect_ai/approval/_policy.py +5 -0
- inspect_ai/approval/_registry.py +2 -2
- inspect_ai/dataset/_dataset.py +64 -37
- inspect_ai/dataset/_sources/__init__.py +0 -0
- inspect_ai/dataset/_sources/csv.py +20 -12
- inspect_ai/dataset/_sources/file.py +4 -0
- inspect_ai/dataset/_sources/hf.py +39 -29
- inspect_ai/dataset/_sources/json.py +17 -9
- inspect_ai/log/__init__.py +2 -0
- inspect_ai/log/_convert.py +3 -3
- inspect_ai/log/_file.py +24 -9
- inspect_ai/log/_log.py +101 -13
- inspect_ai/log/_message.py +4 -2
- inspect_ai/log/_recorders/file.py +4 -0
- inspect_ai/log/_recorders/json.py +5 -7
- inspect_ai/log/_recorders/recorder.py +3 -0
- inspect_ai/log/_transcript.py +19 -8
- inspect_ai/model/__init__.py +2 -0
- inspect_ai/model/_cache.py +39 -21
- inspect_ai/model/_call_tools.py +4 -3
- inspect_ai/model/_chat_message.py +14 -4
- inspect_ai/model/_generate_config.py +1 -1
- inspect_ai/model/_model.py +31 -24
- inspect_ai/model/_model_output.py +14 -1
- inspect_ai/model/_openai.py +10 -18
- inspect_ai/model/_providers/anthropic.py +3 -3
- inspect_ai/model/_providers/google.py +9 -5
- inspect_ai/model/_providers/openai.py +5 -9
- inspect_ai/model/_providers/openai_o1.py +3 -5
- inspect_ai/model/_providers/openrouter.py +86 -0
- inspect_ai/model/_providers/providers.py +11 -0
- inspect_ai/scorer/__init__.py +6 -1
- inspect_ai/scorer/_answer.py +7 -7
- inspect_ai/scorer/_classification.py +38 -18
- inspect_ai/scorer/_common.py +2 -8
- inspect_ai/scorer/_match.py +4 -5
- inspect_ai/scorer/_metric.py +87 -28
- inspect_ai/scorer/_metrics/__init__.py +3 -3
- inspect_ai/scorer/_metrics/accuracy.py +8 -10
- inspect_ai/scorer/_metrics/mean.py +3 -17
- inspect_ai/scorer/_metrics/std.py +111 -30
- inspect_ai/scorer/_model.py +12 -12
- inspect_ai/scorer/_pattern.py +3 -3
- inspect_ai/scorer/_reducer/reducer.py +36 -21
- inspect_ai/scorer/_reducer/registry.py +2 -2
- inspect_ai/scorer/_reducer/types.py +7 -1
- inspect_ai/scorer/_score.py +11 -1
- inspect_ai/scorer/_scorer.py +110 -16
- inspect_ai/solver/__init__.py +1 -1
- inspect_ai/solver/_basic_agent.py +19 -22
- inspect_ai/solver/_bridge/__init__.py +0 -3
- inspect_ai/solver/_bridge/bridge.py +3 -3
- inspect_ai/solver/_chain.py +1 -2
- inspect_ai/solver/_critique.py +3 -3
- inspect_ai/solver/_fork.py +2 -2
- inspect_ai/solver/_human_agent/__init__.py +0 -0
- inspect_ai/solver/_human_agent/agent.py +5 -8
- inspect_ai/solver/_human_agent/commands/clock.py +14 -10
- inspect_ai/solver/_human_agent/commands/note.py +1 -1
- inspect_ai/solver/_human_agent/commands/score.py +0 -11
- inspect_ai/solver/_multiple_choice.py +38 -26
- inspect_ai/solver/_prompt.py +7 -7
- inspect_ai/solver/_solver.py +53 -52
- inspect_ai/solver/_task_state.py +80 -69
- inspect_ai/solver/_use_tools.py +9 -9
- inspect_ai/tool/__init__.py +4 -1
- inspect_ai/tool/_tool.py +43 -14
- inspect_ai/tool/_tool_call.py +6 -2
- inspect_ai/tool/_tool_choice.py +3 -1
- inspect_ai/tool/_tool_def.py +10 -8
- inspect_ai/tool/_tool_params.py +24 -0
- inspect_ai/tool/_tool_with.py +7 -7
- inspect_ai/tool/_tools/__init__.py +0 -0
- inspect_ai/tool/{beta → _tools}/_computer/_common.py +2 -2
- inspect_ai/tool/{beta → _tools}/_computer/_computer.py +13 -5
- inspect_ai/tool/_tools/_computer/_resources/tool/__init__.py +0 -0
- inspect_ai/tool/{beta → _tools}/_computer/_resources/tool/_x11_client.py +1 -1
- inspect_ai/tool/_tools/_computer/_resources/tool/requirements.txt +0 -0
- inspect_ai/tool/_tools/_execute.py +23 -11
- inspect_ai/tool/_tools/_web_browser/_resources/README.md +2 -2
- inspect_ai/tool/_tools/_web_browser/_web_browser.py +5 -3
- inspect_ai/tool/_tools/_web_search.py +7 -5
- inspect_ai/tool/beta.py +3 -0
- inspect_ai/util/_concurrency.py +3 -3
- inspect_ai/util/_panel.py +2 -0
- inspect_ai/util/_resource.py +12 -12
- inspect_ai/util/_sandbox/docker/compose.py +23 -20
- inspect_ai/util/_sandbox/docker/config.py +2 -1
- inspect_ai/util/_sandbox/docker/docker.py +42 -86
- inspect_ai/util/_sandbox/docker/service.py +100 -0
- inspect_ai/util/_sandbox/environment.py +99 -96
- inspect_ai/util/_sandbox/self_check.py +124 -16
- inspect_ai/util/_subprocess.py +5 -3
- inspect_ai/util/_subtask.py +15 -16
- {inspect_ai-0.3.62.dist-info → inspect_ai-0.3.64.dist-info}/LICENSE +1 -1
- {inspect_ai-0.3.62.dist-info → inspect_ai-0.3.64.dist-info}/METADATA +11 -6
- inspect_ai-0.3.64.dist-info/RECORD +625 -0
- inspect_ai/_view/www/src/Register.mjs +0 -3
- inspect_ai/_view/www/src/Types.mjs +0 -38
- inspect_ai/_view/www/src/appearance/Colors.mjs +0 -27
- inspect_ai/_view/www/src/appearance/Fonts.mjs +0 -66
- inspect_ai/_view/www/src/appearance/Icons.mjs +0 -240
- inspect_ai/_view/www/src/components/AnsiDisplay.mjs +0 -184
- inspect_ai/_view/www/src/components/AppErrorBoundary.mjs +0 -34
- inspect_ai/_view/www/src/components/AsciiCinemaPlayer.mjs +0 -74
- inspect_ai/_view/www/src/components/Card.mjs +0 -126
- inspect_ai/_view/www/src/components/ChatView.mjs +0 -441
- inspect_ai/_view/www/src/components/CopyButton.mjs +0 -48
- inspect_ai/_view/www/src/components/Dialog.mjs +0 -61
- inspect_ai/_view/www/src/components/DownloadButton.mjs +0 -15
- inspect_ai/_view/www/src/components/DownloadPanel.mjs +0 -29
- inspect_ai/_view/www/src/components/EmptyPanel.mjs +0 -23
- inspect_ai/_view/www/src/components/ErrorPanel.mjs +0 -66
- inspect_ai/_view/www/src/components/ExpandablePanel.mjs +0 -136
- inspect_ai/_view/www/src/components/FindBand.mjs +0 -157
- inspect_ai/_view/www/src/components/HumanBaselineView.mjs +0 -168
- inspect_ai/_view/www/src/components/JsonPanel.mjs +0 -61
- inspect_ai/_view/www/src/components/LabeledValue.mjs +0 -32
- inspect_ai/_view/www/src/components/LargeModal.mjs +0 -190
- inspect_ai/_view/www/src/components/LightboxCarousel.mjs +0 -217
- inspect_ai/_view/www/src/components/MarkdownDiv.mjs +0 -118
- inspect_ai/_view/www/src/components/MessageBand.mjs +0 -48
- inspect_ai/_view/www/src/components/MessageContent.mjs +0 -111
- inspect_ai/_view/www/src/components/MetaDataGrid.mjs +0 -92
- inspect_ai/_view/www/src/components/MetaDataView.mjs +0 -109
- inspect_ai/_view/www/src/components/MorePopOver.mjs +0 -50
- inspect_ai/_view/www/src/components/NavPills.mjs +0 -63
- inspect_ai/_view/www/src/components/ProgressBar.mjs +0 -51
- inspect_ai/_view/www/src/components/RenderedContent/ChatMessageRenderer.mjs +0 -54
- inspect_ai/_view/www/src/components/RenderedContent/Types.mjs +0 -19
- inspect_ai/_view/www/src/components/TabSet.mjs +0 -184
- inspect_ai/_view/www/src/components/ToolButton.mjs +0 -16
- inspect_ai/_view/www/src/components/Tools.mjs +0 -376
- inspect_ai/_view/www/src/components/VirtualList.mjs +0 -280
- inspect_ai/_view/www/src/components/ansi-output.js +0 -932
- inspect_ai/_view/www/src/json/JsonTab.mjs +0 -48
- inspect_ai/_view/www/src/log-reader/Log-Reader.mjs +0 -25
- inspect_ai/_view/www/src/log-reader/Native-Log-Reader.mjs +0 -13
- inspect_ai/_view/www/src/log-reader/Open-AI-Log-Reader.mjs +0 -263
- inspect_ai/_view/www/src/navbar/Navbar.mjs +0 -418
- inspect_ai/_view/www/src/navbar/SecondaryBar.mjs +0 -175
- inspect_ai/_view/www/src/plan/PlanCard.mjs +0 -418
- inspect_ai/_view/www/src/samples/SampleDialog.mjs +0 -123
- inspect_ai/_view/www/src/samples/SampleDisplay.mjs +0 -516
- inspect_ai/_view/www/src/samples/SampleError.mjs +0 -99
- inspect_ai/_view/www/src/samples/SampleList.mjs +0 -427
- inspect_ai/_view/www/src/samples/SampleScoreView.mjs +0 -172
- inspect_ai/_view/www/src/samples/SampleScores.mjs +0 -34
- inspect_ai/_view/www/src/samples/SampleTranscript.mjs +0 -20
- inspect_ai/_view/www/src/samples/SamplesDescriptor.mjs +0 -771
- inspect_ai/_view/www/src/samples/SamplesTab.mjs +0 -399
- inspect_ai/_view/www/src/samples/SamplesTools.mjs +0 -64
- inspect_ai/_view/www/src/samples/tools/EpochFilter.mjs +0 -38
- inspect_ai/_view/www/src/samples/tools/SampleFilter.mjs +0 -756
- inspect_ai/_view/www/src/samples/tools/SelectScorer.mjs +0 -141
- inspect_ai/_view/www/src/samples/tools/SortFilter.mjs +0 -151
- inspect_ai/_view/www/src/samples/transcript/ApprovalEventView.mjs +0 -71
- inspect_ai/_view/www/src/samples/transcript/ErrorEventView.mjs +0 -44
- inspect_ai/_view/www/src/samples/transcript/EventPanel.mjs +0 -271
- inspect_ai/_view/www/src/samples/transcript/EventRow.mjs +0 -46
- inspect_ai/_view/www/src/samples/transcript/EventSection.mjs +0 -33
- inspect_ai/_view/www/src/samples/transcript/InfoEventView.mjs +0 -59
- inspect_ai/_view/www/src/samples/transcript/InputEventView.mjs +0 -44
- inspect_ai/_view/www/src/samples/transcript/LoggerEventView.mjs +0 -32
- inspect_ai/_view/www/src/samples/transcript/ModelEventView.mjs +0 -216
- inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.mjs +0 -107
- inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.mjs +0 -74
- inspect_ai/_view/www/src/samples/transcript/ScoreEventView.mjs +0 -100
- inspect_ai/_view/www/src/samples/transcript/StepEventView.mjs +0 -187
- inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.mjs +0 -133
- inspect_ai/_view/www/src/samples/transcript/ToolEventView.mjs +0 -88
- inspect_ai/_view/www/src/samples/transcript/TranscriptView.mjs +0 -459
- inspect_ai/_view/www/src/samples/transcript/Types.mjs +0 -44
- inspect_ai/_view/www/src/samples/transcript/state/StateDiffView.mjs +0 -53
- inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.mjs +0 -254
- inspect_ai/_view/www/src/samples/transcript/state/StateEventView.mjs +0 -313
- inspect_ai/_view/www/src/sidebar/Sidebar.mjs +0 -418
- inspect_ai/_view/www/src/usage/ModelTokenTable.mjs +0 -72
- inspect_ai/_view/www/src/usage/UsageCard.mjs +0 -159
- inspect_ai/_view/www/src/utils/Format.mjs +0 -260
- inspect_ai/_view/www/src/utils/Git.mjs +0 -12
- inspect_ai/_view/www/src/utils/Html.mjs +0 -21
- inspect_ai/_view/www/src/utils/attachments.mjs +0 -31
- inspect_ai/_view/www/src/utils/debugging.mjs +0 -23
- inspect_ai/_view/www/src/utils/http.mjs +0 -18
- inspect_ai/_view/www/src/utils/queue.mjs +0 -67
- inspect_ai/_view/www/src/utils/sync.mjs +0 -101
- inspect_ai/_view/www/src/workspace/TaskErrorPanel.mjs +0 -17
- inspect_ai/_view/www/src/workspace/WorkSpace.mjs +0 -516
- inspect_ai/tool/beta/__init__.py +0 -5
- inspect_ai-0.3.62.dist-info/RECORD +0 -481
- /inspect_ai/{tool/beta/_computer/_resources/tool → _eval}/__init__.py +0 -0
- /inspect_ai/{tool/beta/_computer/_resources/tool/requirements.txt → _util/__init__.py} +0 -0
- /inspect_ai/_view/www/src/{constants.mjs → constants.ts} +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/__init__.py +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_computer_split.py +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/Dockerfile +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/README.md +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/entrypoint/entrypoint.sh +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/entrypoint/novnc_startup.sh +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/entrypoint/x11vnc_startup.sh +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/entrypoint/xfce_startup.sh +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/entrypoint/xvfb_startup.sh +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/.config/Code/User/globalStorage/state.vscdb +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/.config/Code/User/settings.json +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/Desktop/Firefox Web Browser.desktop +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/Desktop/Terminal.desktop +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/Desktop/Visual Studio Code.desktop +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/tool/_logger.py +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/tool/_run.py +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/tool/_tool_result.py +0 -0
- /inspect_ai/tool/{beta → _tools}/_computer/_resources/tool/computer_tool.py +0 -0
- {inspect_ai-0.3.62.dist-info → inspect_ai-0.3.64.dist-info}/WHEEL +0 -0
- {inspect_ai-0.3.62.dist-info → inspect_ai-0.3.64.dist-info}/entry_points.txt +0 -0
- {inspect_ai-0.3.62.dist-info → inspect_ai-0.3.64.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,292 @@
|
|
1
|
+
import clsx from "clsx";
|
2
|
+
import React, {
|
3
|
+
forwardRef,
|
4
|
+
useEffect,
|
5
|
+
useImperativeHandle,
|
6
|
+
useMemo,
|
7
|
+
useRef,
|
8
|
+
useState,
|
9
|
+
} from "react";
|
10
|
+
import styles from "./VirtualList.module.css";
|
11
|
+
|
12
|
+
export interface VirtualListRef {
|
13
|
+
focus: () => void;
|
14
|
+
scrollToIndex: (index: number, direction?: "up" | "down") => void;
|
15
|
+
}
|
16
|
+
|
17
|
+
interface VirtualListProps<T> {
|
18
|
+
data: T[];
|
19
|
+
renderRow: (item: T, index: number) => React.ReactNode;
|
20
|
+
overscanCount?: number;
|
21
|
+
initialEstimatedRowHeight?: number;
|
22
|
+
sync?: boolean;
|
23
|
+
scrollRef?: React.RefObject<HTMLElement | null>;
|
24
|
+
className?: string;
|
25
|
+
style?: React.CSSProperties;
|
26
|
+
tabIndex?: number;
|
27
|
+
onKeyDown?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
|
28
|
+
}
|
29
|
+
|
30
|
+
interface ListMetrics {
|
31
|
+
rowHeights: Map<number, number>;
|
32
|
+
totalHeight: number;
|
33
|
+
estimatedRowHeight: number;
|
34
|
+
}
|
35
|
+
|
36
|
+
export const VirtualList = forwardRef(function VirtualList<T>(
|
37
|
+
{
|
38
|
+
data,
|
39
|
+
renderRow,
|
40
|
+
overscanCount = 15,
|
41
|
+
initialEstimatedRowHeight = 50,
|
42
|
+
sync = false,
|
43
|
+
scrollRef,
|
44
|
+
onKeyDown,
|
45
|
+
...props
|
46
|
+
}: VirtualListProps<T>,
|
47
|
+
ref: React.Ref<VirtualListRef>,
|
48
|
+
) {
|
49
|
+
const [height, setHeight] = useState(0);
|
50
|
+
const [offset, setOffset] = useState(0);
|
51
|
+
const [listMetrics, setListMetrics] = useState<ListMetrics>({
|
52
|
+
rowHeights: new Map(),
|
53
|
+
totalHeight: data.length * initialEstimatedRowHeight,
|
54
|
+
estimatedRowHeight: initialEstimatedRowHeight,
|
55
|
+
});
|
56
|
+
|
57
|
+
const baseRef = useRef<HTMLDivElement>(null);
|
58
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
59
|
+
const rowRefs = useRef<Map<number, HTMLElement>>(new Map());
|
60
|
+
|
61
|
+
const getRowHeight = (index: number): number => {
|
62
|
+
return listMetrics.rowHeights.get(index) || listMetrics.estimatedRowHeight;
|
63
|
+
};
|
64
|
+
|
65
|
+
// Calculate new estimated height based on measured rows
|
66
|
+
const calculateEstimatedHeight = (heights: Map<number, number>): number => {
|
67
|
+
if (heights.size === 0) return listMetrics.estimatedRowHeight;
|
68
|
+
|
69
|
+
// Calculate average of measured heights
|
70
|
+
let sum = 0;
|
71
|
+
heights.forEach((height) => {
|
72
|
+
sum += height;
|
73
|
+
});
|
74
|
+
|
75
|
+
// Use exponential moving average to smooth transitions
|
76
|
+
const alpha = 0.2; // Smoothing factor
|
77
|
+
const newEstimate = sum / heights.size;
|
78
|
+
return Math.round(
|
79
|
+
alpha * newEstimate + (1 - alpha) * listMetrics.estimatedRowHeight,
|
80
|
+
);
|
81
|
+
};
|
82
|
+
|
83
|
+
const rowPositions = useMemo(() => {
|
84
|
+
let currentPosition = 0;
|
85
|
+
const positions = new Map<number, number>();
|
86
|
+
|
87
|
+
for (let i = 0; i < data.length; i++) {
|
88
|
+
positions.set(i, currentPosition);
|
89
|
+
currentPosition += getRowHeight(i);
|
90
|
+
}
|
91
|
+
|
92
|
+
return positions;
|
93
|
+
}, [listMetrics.rowHeights, listMetrics.estimatedRowHeight, data.length]);
|
94
|
+
|
95
|
+
// Measure rendered rows and update heights if needed
|
96
|
+
const measureRows = () => {
|
97
|
+
let updates: [number, number][] = [];
|
98
|
+
|
99
|
+
rowRefs.current.forEach((element, index) => {
|
100
|
+
if (element) {
|
101
|
+
const measuredHeight = element.offsetHeight;
|
102
|
+
if (
|
103
|
+
measuredHeight &&
|
104
|
+
measuredHeight !== listMetrics.rowHeights.get(index)
|
105
|
+
) {
|
106
|
+
updates.push([index, measuredHeight]);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
});
|
110
|
+
|
111
|
+
if (updates.length === 0) return;
|
112
|
+
|
113
|
+
const newHeights = new Map(listMetrics.rowHeights);
|
114
|
+
updates.forEach(([index, height]) => {
|
115
|
+
newHeights.set(index, height);
|
116
|
+
});
|
117
|
+
|
118
|
+
// Calculate new estimated height
|
119
|
+
const newEstimatedHeight = calculateEstimatedHeight(newHeights);
|
120
|
+
|
121
|
+
let newTotalHeight = 0;
|
122
|
+
for (let i = 0; i < data.length; i++) {
|
123
|
+
newTotalHeight += newHeights.get(i) || newEstimatedHeight;
|
124
|
+
}
|
125
|
+
|
126
|
+
setListMetrics({
|
127
|
+
rowHeights: newHeights,
|
128
|
+
totalHeight: newTotalHeight,
|
129
|
+
estimatedRowHeight: newEstimatedHeight,
|
130
|
+
});
|
131
|
+
};
|
132
|
+
|
133
|
+
useImperativeHandle(
|
134
|
+
ref,
|
135
|
+
() => ({
|
136
|
+
focus: () => {
|
137
|
+
baseRef.current?.focus();
|
138
|
+
},
|
139
|
+
scrollToIndex: (index: number, direction?: "up" | "down") => {
|
140
|
+
const scrollElement = scrollRef?.current || baseRef.current;
|
141
|
+
if (!scrollElement || index < 0 || index >= data.length) return;
|
142
|
+
|
143
|
+
const currentScrollTop = scrollElement.scrollTop;
|
144
|
+
const viewportHeight = scrollElement.offsetHeight;
|
145
|
+
|
146
|
+
const rowTop = rowPositions.get(index) || 0;
|
147
|
+
const rowHeight = getRowHeight(index);
|
148
|
+
const rowBottom = rowTop + rowHeight;
|
149
|
+
|
150
|
+
const isVisible =
|
151
|
+
rowTop >= currentScrollTop &&
|
152
|
+
rowBottom <= currentScrollTop + viewportHeight;
|
153
|
+
if (isVisible) return;
|
154
|
+
|
155
|
+
let newScrollTop: number;
|
156
|
+
if (direction === "up") {
|
157
|
+
newScrollTop = rowTop;
|
158
|
+
} else {
|
159
|
+
newScrollTop = rowBottom - viewportHeight;
|
160
|
+
}
|
161
|
+
|
162
|
+
newScrollTop = Math.max(
|
163
|
+
0,
|
164
|
+
Math.min(newScrollTop, listMetrics.totalHeight - viewportHeight),
|
165
|
+
);
|
166
|
+
scrollElement.scrollTop = newScrollTop;
|
167
|
+
},
|
168
|
+
}),
|
169
|
+
[rowPositions, data.length],
|
170
|
+
);
|
171
|
+
|
172
|
+
const resize = () => {
|
173
|
+
const scrollElement = scrollRef?.current || baseRef.current;
|
174
|
+
if (scrollElement && height !== scrollElement.offsetHeight) {
|
175
|
+
setHeight(scrollElement.offsetHeight);
|
176
|
+
}
|
177
|
+
};
|
178
|
+
|
179
|
+
const handleScroll = throttle(() => {
|
180
|
+
const scrollElement = scrollRef?.current || baseRef.current;
|
181
|
+
if (scrollElement) {
|
182
|
+
setOffset(scrollElement.scrollTop);
|
183
|
+
}
|
184
|
+
if (sync) {
|
185
|
+
setOffset((prev) => prev);
|
186
|
+
}
|
187
|
+
}, 100);
|
188
|
+
|
189
|
+
useEffect(() => {
|
190
|
+
resize();
|
191
|
+
const scrollElement = scrollRef?.current || baseRef.current;
|
192
|
+
|
193
|
+
if (scrollElement) {
|
194
|
+
scrollElement.addEventListener("scroll", handleScroll);
|
195
|
+
window.addEventListener("resize", resize);
|
196
|
+
|
197
|
+
return () => {
|
198
|
+
scrollElement.removeEventListener("scroll", handleScroll);
|
199
|
+
window.removeEventListener("resize", resize);
|
200
|
+
};
|
201
|
+
}
|
202
|
+
}, [scrollRef?.current]);
|
203
|
+
|
204
|
+
useEffect(() => {
|
205
|
+
measureRows();
|
206
|
+
});
|
207
|
+
|
208
|
+
const findRowAtOffset = (targetOffset: number): number => {
|
209
|
+
if (targetOffset <= 0) return 0;
|
210
|
+
if (targetOffset >= listMetrics.totalHeight) return data.length - 1;
|
211
|
+
|
212
|
+
let low = 0;
|
213
|
+
let high = data.length - 1;
|
214
|
+
let lastValid = 0;
|
215
|
+
|
216
|
+
while (low <= high) {
|
217
|
+
const mid = Math.floor((low + high) / 2);
|
218
|
+
const rowStart = rowPositions.get(mid) || 0;
|
219
|
+
|
220
|
+
if (rowStart <= targetOffset) {
|
221
|
+
lastValid = mid;
|
222
|
+
low = mid + 1;
|
223
|
+
} else {
|
224
|
+
high = mid - 1;
|
225
|
+
}
|
226
|
+
}
|
227
|
+
return lastValid;
|
228
|
+
};
|
229
|
+
|
230
|
+
const firstVisibleIdx = findRowAtOffset(offset);
|
231
|
+
const lastVisibleIdx = findRowAtOffset(offset + height);
|
232
|
+
|
233
|
+
const start = Math.max(0, firstVisibleIdx - overscanCount);
|
234
|
+
const end = Math.min(data.length, lastVisibleIdx + overscanCount);
|
235
|
+
|
236
|
+
const renderedRows = useMemo(() => {
|
237
|
+
const selection = data.slice(start, end);
|
238
|
+
return selection.map((item, index) => {
|
239
|
+
const actualIndex = start + index;
|
240
|
+
return (
|
241
|
+
<div
|
242
|
+
key={`list-item-${actualIndex}`}
|
243
|
+
ref={(el) => {
|
244
|
+
if (el) {
|
245
|
+
rowRefs.current.set(actualIndex, el);
|
246
|
+
} else {
|
247
|
+
rowRefs.current.delete(actualIndex);
|
248
|
+
}
|
249
|
+
}}
|
250
|
+
>
|
251
|
+
{renderRow(item, actualIndex)}
|
252
|
+
</div>
|
253
|
+
);
|
254
|
+
});
|
255
|
+
}, [data, start, end, renderRow]);
|
256
|
+
|
257
|
+
const top = rowPositions.get(start) || 0;
|
258
|
+
const scrollProps = scrollRef ? {} : { onScroll: handleScroll };
|
259
|
+
|
260
|
+
return (
|
261
|
+
<div ref={baseRef} {...props} {...scrollProps} onKeyDown={onKeyDown}>
|
262
|
+
<div
|
263
|
+
className={clsx(
|
264
|
+
styles.container,
|
265
|
+
!scrollRef?.current ? styles.hidden : undefined,
|
266
|
+
)}
|
267
|
+
style={{ height: `${listMetrics.totalHeight}px` }}
|
268
|
+
>
|
269
|
+
<div
|
270
|
+
className={styles.content}
|
271
|
+
style={{ transform: `translateY(${top}px)` }}
|
272
|
+
ref={containerRef}
|
273
|
+
>
|
274
|
+
{renderedRows}
|
275
|
+
</div>
|
276
|
+
</div>
|
277
|
+
</div>
|
278
|
+
);
|
279
|
+
}) as <T>(
|
280
|
+
props: VirtualListProps<T> & { ref?: React.Ref<VirtualListRef> },
|
281
|
+
) => React.ReactElement;
|
282
|
+
|
283
|
+
const throttle = (func: (...args: any[]) => void, limit: number) => {
|
284
|
+
let inThrottle: boolean;
|
285
|
+
return function (this: any, ...args: any[]) {
|
286
|
+
if (!inThrottle) {
|
287
|
+
func.apply(this, args);
|
288
|
+
inThrottle = true;
|
289
|
+
setTimeout(() => (inThrottle = false), limit);
|
290
|
+
}
|
291
|
+
};
|
292
|
+
};
|
@@ -1,33 +1,59 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
|
4
|
-
import { App } from "./App.mjs";
|
1
|
+
import { createRoot } from "react-dom/client";
|
2
|
+
import { App } from "./App";
|
5
3
|
import api from "./api/index";
|
4
|
+
import { ApplicationState, Capabilities } from "./types";
|
5
|
+
import { throttle } from "./utils/sync";
|
6
6
|
import { getVscodeApi } from "./utils/vscode";
|
7
|
-
import { throttle } from "./utils/sync.mjs";
|
8
7
|
|
9
8
|
// Read any state from the page itself
|
10
9
|
const vscode = getVscodeApi();
|
11
10
|
let initialState = undefined;
|
11
|
+
let capabilities: Capabilities = {
|
12
|
+
downloadFiles: true,
|
13
|
+
webWorkers: true,
|
14
|
+
};
|
12
15
|
if (vscode) {
|
13
|
-
initialState = filterState(vscode.getState());
|
16
|
+
initialState = filterState(vscode.getState() as ApplicationState);
|
17
|
+
|
18
|
+
// Determine the capabilities
|
19
|
+
const extensionVersionEl = document.querySelector(
|
20
|
+
'meta[name="inspect-extension:version"]',
|
21
|
+
);
|
22
|
+
const extensionVersion = extensionVersionEl
|
23
|
+
? extensionVersionEl.getAttribute("content")
|
24
|
+
: undefined;
|
25
|
+
|
26
|
+
if (!extensionVersion) {
|
27
|
+
capabilities = { downloadFiles: false, webWorkers: false };
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
const containerId = "app";
|
32
|
+
const container = document.getElementById(containerId);
|
33
|
+
if (!container) {
|
34
|
+
console.error("Root container not found");
|
35
|
+
throw new Error(
|
36
|
+
`Expected a container element with Id '${containerId}' but no such container element was present.`,
|
37
|
+
);
|
14
38
|
}
|
15
39
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
40
|
+
const root = createRoot(container as HTMLElement);
|
41
|
+
root.render(
|
42
|
+
<App
|
43
|
+
api={api}
|
44
|
+
applicationState={initialState}
|
45
|
+
saveApplicationState={throttle((state) => {
|
21
46
|
const vscode = getVscodeApi();
|
22
47
|
if (vscode) {
|
23
48
|
vscode.setState(filterState(state));
|
24
49
|
}
|
25
50
|
}, 1000)}
|
26
|
-
|
27
|
-
|
51
|
+
capabilities={capabilities}
|
52
|
+
pollForLogs={false}
|
53
|
+
/>,
|
28
54
|
);
|
29
55
|
|
30
|
-
function filterState(state) {
|
56
|
+
function filterState(state: ApplicationState) {
|
31
57
|
if (!state) {
|
32
58
|
return state;
|
33
59
|
}
|
@@ -41,7 +67,7 @@ function filterState(state) {
|
|
41
67
|
}
|
42
68
|
|
43
69
|
// Filters the selected Sample if it is large
|
44
|
-
function filterLargeSample(state) {
|
70
|
+
function filterLargeSample(state: ApplicationState) {
|
45
71
|
if (!state || !state.selectedSample) {
|
46
72
|
return state;
|
47
73
|
}
|
@@ -56,7 +82,7 @@ function filterLargeSample(state) {
|
|
56
82
|
}
|
57
83
|
|
58
84
|
// Filters the selectedlog if it is too large
|
59
|
-
function filterLargeSelectedLog(state) {
|
85
|
+
function filterLargeSelectedLog(state: ApplicationState) {
|
60
86
|
if (!state || !state.selectedLog?.contents) {
|
61
87
|
return state;
|
62
88
|
}
|
@@ -72,8 +98,8 @@ function filterLargeSelectedLog(state) {
|
|
72
98
|
}
|
73
99
|
}
|
74
100
|
|
75
|
-
function estimateSize(list, frequency = 0.2) {
|
76
|
-
if (!list || list.
|
101
|
+
function estimateSize(list: unknown[], frequency = 0.2) {
|
102
|
+
if (!list || list.length === 0) {
|
77
103
|
return 0;
|
78
104
|
}
|
79
105
|
|
@@ -81,7 +107,7 @@ function estimateSize(list, frequency = 0.2) {
|
|
81
107
|
const sampleSize = Math.ceil(list.length * frequency);
|
82
108
|
|
83
109
|
// Get a proper random sample without duplicates
|
84
|
-
const messageIndices = new Set();
|
110
|
+
const messageIndices = new Set<number>();
|
85
111
|
while (
|
86
112
|
messageIndices.size < sampleSize &&
|
87
113
|
messageIndices.size < list.length
|
@@ -1,17 +1,13 @@
|
|
1
|
-
//@ts-check
|
2
1
|
import {
|
3
2
|
EvalHeader,
|
4
3
|
EvalSummary,
|
5
4
|
LogViewAPI,
|
6
5
|
SampleSummary,
|
7
|
-
} from "../api/
|
6
|
+
} from "../api/types";
|
8
7
|
import { EvalLog, EvalPlan, EvalSample, EvalSpec } from "../types/log";
|
9
8
|
import { asyncJsonParse } from "../utils/json-worker";
|
10
|
-
import { AsyncQueue } from "../utils/queue
|
11
|
-
import {
|
12
|
-
FileSizeLimitError,
|
13
|
-
openRemoteZipFile,
|
14
|
-
} from "../utils/remoteZipFile.mjs";
|
9
|
+
import { AsyncQueue } from "../utils/queue";
|
10
|
+
import { FileSizeLimitError, openRemoteZipFile } from "./remoteZipFile";
|
15
11
|
|
16
12
|
// don't try to load samples greater than 50mb
|
17
13
|
const MAX_BYTES = 50 * 1024 * 1024;
|
@@ -105,7 +101,6 @@ export const openRemoteLogFile = async (
|
|
105
101
|
if (remoteZipFile.centralDirectory.has(sampleFile)) {
|
106
102
|
return (await readJSONFile(sampleFile, MAX_BYTES)) as EvalSample;
|
107
103
|
} else {
|
108
|
-
console.log({ dir: remoteZipFile.centralDirectory });
|
109
104
|
throw new Error(
|
110
105
|
`Unable to read sample file ${sampleFile} - it is not present in the manifest.`,
|
111
106
|
);
|
@@ -1,72 +1,60 @@
|
|
1
|
-
|
2
|
-
import { decompress } from "fflate";
|
1
|
+
import { AsyncInflateOptions, decompress } from "fflate";
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
*/
|
3
|
+
export interface ZipFileEntry {
|
4
|
+
versionNeeded: number;
|
5
|
+
bitFlag: number;
|
6
|
+
compressionMethod: number;
|
7
|
+
crc32: number;
|
8
|
+
compressedSize: number;
|
9
|
+
uncompressedSize: number;
|
10
|
+
filenameLength: number;
|
11
|
+
extraFieldLength: number;
|
12
|
+
data: Uint8Array;
|
13
|
+
}
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
*/
|
15
|
+
export interface CentralDirectoryEntry {
|
16
|
+
filename: string;
|
17
|
+
compressionMethod: number;
|
18
|
+
compressedSize: number;
|
19
|
+
uncompressedSize: number;
|
20
|
+
fileOffset: number;
|
21
|
+
}
|
25
22
|
|
26
23
|
/**
|
27
24
|
* Represents an error thrown when a file exceeds the maximum allowed size.
|
28
|
-
*
|
29
|
-
* @class
|
30
|
-
* @extends {Error}
|
31
25
|
*/
|
32
26
|
export class FileSizeLimitError extends Error {
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
* @param {number} maxBytes - The maximum allowed size for the file, in bytes.
|
38
|
-
*/
|
39
|
-
constructor(file, maxBytes) {
|
27
|
+
public readonly file: string;
|
28
|
+
public readonly maxBytes: number;
|
29
|
+
|
30
|
+
constructor(file: string, maxBytes: number) {
|
40
31
|
super(
|
41
32
|
`File "${file}" exceeds the maximum size (${maxBytes} bytes) and cannot be loaded.`,
|
42
33
|
);
|
43
34
|
this.name = "FileSizeLimitError";
|
44
35
|
this.file = file;
|
45
36
|
this.maxBytes = maxBytes;
|
37
|
+
|
38
|
+
Object.setPrototypeOf(this, FileSizeLimitError.prototype);
|
46
39
|
}
|
47
40
|
}
|
48
41
|
|
49
42
|
/**
|
50
43
|
* Opens a remote ZIP file from the specified URL, fetches and parses the central directory,
|
51
44
|
* and provides a method to read files within the ZIP.
|
52
|
-
*
|
53
|
-
* @param {string} url - The URL of the remote ZIP file.
|
54
|
-
* @param {(url: string) => Promise<number>} [fetchContentLength] - Optional function to compute the content length of the remote file.
|
55
|
-
* @param {(url: string, start: number, end: number) => Promise<Uint8Array>} [fetchBytes] - Optional function to fetch a range of bytes from the remote file.
|
56
|
-
* @returns {Promise<{
|
57
|
-
* centralDirectory: Map<string, CentralDirectoryEntry>,
|
58
|
-
* readFile: (file: string, maxBytes?: number) => Promise<Uint8Array>
|
59
|
-
* }>} A promise that resolves with an object containing:
|
60
|
-
* - `centralDirectory`: A map where keys are filenames and values are their corresponding central directory entries.
|
61
|
-
* - `readFile`: A function to read a specific file from the ZIP archive by name.
|
62
|
-
* Takes the filename and an optional maximum byte length to read.
|
63
|
-
* @throws {Error} If the file is not found or if an unsupported compression method is encountered.
|
64
45
|
*/
|
65
46
|
export const openRemoteZipFile = async (
|
66
|
-
url,
|
67
|
-
fetchContentLength = fetchSize,
|
68
|
-
fetchBytes
|
69
|
-
|
47
|
+
url: string,
|
48
|
+
fetchContentLength: (url: string) => Promise<number> = fetchSize,
|
49
|
+
fetchBytes: (
|
50
|
+
url: string,
|
51
|
+
start: number,
|
52
|
+
end: number,
|
53
|
+
) => Promise<Uint8Array> = fetchRange,
|
54
|
+
): Promise<{
|
55
|
+
centralDirectory: Map<string, CentralDirectoryEntry>;
|
56
|
+
readFile: (file: string, maxBytes?: number) => Promise<Uint8Array>;
|
57
|
+
}> => {
|
70
58
|
const contentLength = await fetchContentLength(url);
|
71
59
|
|
72
60
|
// Read the end of central directory record
|
@@ -89,7 +77,7 @@ export const openRemoteZipFile = async (
|
|
89
77
|
const centralDirectory = parseCentralDirectory(centralDirBuffer);
|
90
78
|
return {
|
91
79
|
centralDirectory: centralDirectory,
|
92
|
-
readFile: async (file, maxBytes) => {
|
80
|
+
readFile: async (file, maxBytes): Promise<Uint8Array> => {
|
93
81
|
const entry = centralDirectory.get(file);
|
94
82
|
if (!entry) {
|
95
83
|
throw new Error(`File not found: ${file}`);
|
@@ -142,7 +130,7 @@ export const openRemoteZipFile = async (
|
|
142
130
|
};
|
143
131
|
};
|
144
132
|
|
145
|
-
export const fetchSize = async (url) => {
|
133
|
+
export const fetchSize = async (url: string): Promise<number> => {
|
146
134
|
const response = await fetch(`${url}`, { method: "HEAD" });
|
147
135
|
const contentLength = Number(response.headers.get("Content-Length"));
|
148
136
|
return contentLength;
|
@@ -150,14 +138,12 @@ export const fetchSize = async (url) => {
|
|
150
138
|
|
151
139
|
/**
|
152
140
|
* Fetches a range of bytes from a remote resource and returns it as a `Uint8Array`.
|
153
|
-
*
|
154
|
-
* @param {string} url - The URL of the remote resource to fetch.
|
155
|
-
* @param {number} start - The starting byte position of the range to fetch.
|
156
|
-
* @param {number} end - The ending byte position of the range to fetch.
|
157
|
-
* @returns {Promise<Uint8Array>} A promise that resolves to a `Uint8Array` containing the fetched byte range.
|
158
|
-
* @throws {Error} If there is an issue with the network request.
|
159
141
|
*/
|
160
|
-
export const fetchRange = async (
|
142
|
+
export const fetchRange = async (
|
143
|
+
url: string,
|
144
|
+
start: number,
|
145
|
+
end: number,
|
146
|
+
): Promise<Uint8Array> => {
|
161
147
|
const response = await fetch(`${url}`, {
|
162
148
|
headers: { Range: `bytes=${start}-${end}` },
|
163
149
|
});
|
@@ -167,13 +153,11 @@ export const fetchRange = async (url, start, end) => {
|
|
167
153
|
|
168
154
|
/**
|
169
155
|
* Asynchronously decompresses the provided data using the specified options.
|
170
|
-
*
|
171
|
-
* @param {Uint8Array} data - The compressed data to be decompressed.
|
172
|
-
* @param {Object} opts - Options to configure the decompression process.
|
173
|
-
* @returns {Promise<Uint8Array>} A promise that resolves with the decompressed data.
|
174
|
-
* @throws {Error} If an error occurs during decompression, the promise is rejected with the error.
|
175
156
|
*/
|
176
|
-
const decompressAsync = async (
|
157
|
+
const decompressAsync = async (
|
158
|
+
data: Uint8Array,
|
159
|
+
opts: AsyncInflateOptions,
|
160
|
+
): Promise<Uint8Array> => {
|
177
161
|
return new Promise((resolve, reject) => {
|
178
162
|
decompress(data, opts, (err, result) => {
|
179
163
|
if (err) {
|
@@ -187,13 +171,11 @@ const decompressAsync = async (data, opts) => {
|
|
187
171
|
|
188
172
|
/**
|
189
173
|
* Extracts and parses the header and data of a compressed ZIP entry from raw binary data.
|
190
|
-
*
|
191
|
-
* @param {string} file - The name of the file stream to be parsed
|
192
|
-
* @param {Uint8Array} rawData - The raw binary data containing the ZIP entry.
|
193
|
-
* @returns {Promise<ZipFileEntry>} A promise that resolves to an object containing the ZIP entry's header information and compressed data.
|
194
|
-
* @throws {Error} If the ZIP entry signature is invalid.
|
195
174
|
*/
|
196
|
-
const parseZipFileEntry = async (
|
175
|
+
const parseZipFileEntry = async (
|
176
|
+
file: string,
|
177
|
+
rawData: Uint8Array,
|
178
|
+
): Promise<ZipFileEntry> => {
|
197
179
|
// Parse ZIP entry header
|
198
180
|
const view = new DataView(rawData.buffer);
|
199
181
|
let offset = 0;
|
@@ -237,20 +219,17 @@ const parseZipFileEntry = async (file, rawData) => {
|
|
237
219
|
};
|
238
220
|
};
|
239
221
|
|
222
|
+
const kFileHeaderSize = 46;
|
240
223
|
/**
|
241
224
|
* Parses the central directory of a ZIP file from the provided buffer and returns a map of entries.
|
242
|
-
*
|
243
|
-
* @param {Uint8Array} buffer - The raw binary data containing the central directory of the ZIP archive.
|
244
|
-
* @returns {Map<string, CentralDirectoryEntry>} A map where the key is the filename and the value is the corresponding central directory entry.
|
245
|
-
* @throws {Error} If the buffer does not contain a valid central directory signature.
|
246
225
|
*/
|
247
|
-
const parseCentralDirectory = (buffer) => {
|
226
|
+
const parseCentralDirectory = (buffer: Uint8Array<ArrayBufferLike>) => {
|
248
227
|
let offset = 0;
|
249
228
|
const view = new DataView(buffer.buffer);
|
250
|
-
|
251
229
|
const entries = new Map();
|
230
|
+
|
252
231
|
while (offset < buffer.length) {
|
253
|
-
//
|
232
|
+
// Central Directory signature
|
254
233
|
if (view.getUint32(offset, true) !== 0x02014b50) break;
|
255
234
|
|
256
235
|
const filenameLength = view.getUint16(offset + 28, true);
|
@@ -258,20 +237,47 @@ const parseCentralDirectory = (buffer) => {
|
|
258
237
|
const fileCommentLength = view.getUint16(offset + 32, true);
|
259
238
|
|
260
239
|
const filename = new TextDecoder().decode(
|
261
|
-
buffer.subarray(
|
240
|
+
buffer.subarray(
|
241
|
+
offset + kFileHeaderSize,
|
242
|
+
offset + kFileHeaderSize + filenameLength,
|
243
|
+
),
|
262
244
|
);
|
263
245
|
|
246
|
+
// Read 32-bit file offset
|
247
|
+
let fileOffset = view.getUint32(offset + 42, true);
|
248
|
+
|
249
|
+
// If fileOffset is 0xFFFFFFFF, use the ZIP64 extended offset instead
|
250
|
+
if (fileOffset === 0xffffffff) {
|
251
|
+
// Move to extra field
|
252
|
+
let extraOffset = offset + kFileHeaderSize + filenameLength;
|
253
|
+
// Look through extra fields until we find zip64 extra field
|
254
|
+
while (
|
255
|
+
extraOffset <
|
256
|
+
offset + kFileHeaderSize + filenameLength + extraFieldLength
|
257
|
+
) {
|
258
|
+
const tag = view.getUint16(extraOffset, true);
|
259
|
+
const size = view.getUint16(extraOffset + 2, true);
|
260
|
+
if (tag === 0x0001) {
|
261
|
+
// ZIP64 Extra Field - Read 64-bit offset
|
262
|
+
fileOffset = Number(view.getBigUint64(extraOffset + 4, true));
|
263
|
+
break;
|
264
|
+
}
|
265
|
+
extraOffset += 4 + size; // Move to next extra field
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
264
269
|
const entry = {
|
265
270
|
filename,
|
266
271
|
compressionMethod: view.getUint16(offset + 10, true),
|
267
272
|
compressedSize: view.getUint32(offset + 20, true),
|
268
273
|
uncompressedSize: view.getUint32(offset + 24, true),
|
269
|
-
fileOffset
|
274
|
+
fileOffset,
|
270
275
|
};
|
271
276
|
|
272
277
|
entries.set(filename, entry);
|
273
|
-
|
274
|
-
|
278
|
+
offset +=
|
279
|
+
kFileHeaderSize + filenameLength + extraFieldLength + fileCommentLength;
|
275
280
|
}
|
281
|
+
|
276
282
|
return entries;
|
277
283
|
};
|