codebase-onboarder 0.5.0 → 0.7.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/README.md +196 -47
- package/bin/build-if-source.js +23 -0
- package/cli/commands.d.ts +26 -0
- package/cli/commands.js +836 -811
- package/cli/commands.js.map +1 -0
- package/cli/explorer/advanced.d.ts +14 -0
- package/cli/explorer/advanced.js +449 -0
- package/cli/explorer/advanced.js.map +1 -0
- package/cli/explorer/app.d.ts +1 -0
- package/cli/explorer/app.js +396 -229
- package/cli/explorer/app.js.map +1 -0
- package/cli/explorer/assistant.d.ts +9 -0
- package/cli/explorer/assistant.js +58 -0
- package/cli/explorer/assistant.js.map +1 -0
- package/cli/explorer/commands.d.ts +17 -0
- package/cli/explorer/commands.js +400 -162
- package/cli/explorer/commands.js.map +1 -0
- package/cli/explorer/featureViews.d.ts +124 -0
- package/cli/explorer/featureViews.js +179 -0
- package/cli/explorer/featureViews.js.map +1 -0
- package/cli/explorer/github.d.ts +21 -0
- package/cli/explorer/github.js +73 -0
- package/cli/explorer/github.js.map +1 -0
- package/cli/explorer/graphs.d.ts +7 -0
- package/cli/explorer/graphs.js +173 -0
- package/cli/explorer/graphs.js.map +1 -0
- package/cli/explorer/picker.d.ts +22 -0
- package/cli/explorer/picker.js +150 -0
- package/cli/explorer/picker.js.map +1 -0
- package/cli/explorer/report.d.ts +85 -0
- package/cli/explorer/report.js +60 -0
- package/cli/explorer/report.js.map +1 -0
- package/cli/explorer/session.d.ts +449 -0
- package/cli/explorer/session.js +184 -95
- package/cli/explorer/session.js.map +1 -0
- package/cli/explorer/views.d.ts +19 -0
- package/cli/explorer/views.js +496 -412
- package/cli/explorer/views.js.map +1 -0
- package/cli/explorer/wrap.d.ts +1 -0
- package/cli/explorer/wrap.js +33 -0
- package/cli/explorer/wrap.js.map +1 -0
- package/cli/main.d.ts +1 -0
- package/cli/main.js +235 -138
- package/cli/main.js.map +1 -0
- package/cli/prompt.d.ts +5 -0
- package/cli/prompt.js +84 -80
- package/cli/prompt.js.map +1 -0
- package/cli/scanOptions.d.ts +2 -0
- package/cli/scanOptions.js +11 -0
- package/cli/scanOptions.js.map +1 -0
- package/cli/ui.d.ts +33 -0
- package/cli/ui.js +55 -35
- package/cli/ui.js.map +1 -0
- package/cli/wizard.d.ts +187 -0
- package/cli/wizard.js +304 -284
- package/cli/wizard.js.map +1 -0
- package/package.json +15 -4
- package/public/app.d.ts +1 -0
- package/public/app.js +1057 -1009
- package/public/app.js.map +1 -0
- package/public/browser.d.ts +68 -0
- package/public/browser.js +2 -0
- package/public/browser.js.map +1 -0
- package/public/index.html +30 -13
- package/public/js/about.d.ts +6 -0
- package/public/js/about.js +165 -172
- package/public/js/about.js.map +1 -0
- package/public/js/aiDraft.d.ts +3 -0
- package/public/js/aiDraft.js +116 -124
- package/public/js/aiDraft.js.map +1 -0
- package/public/js/analysisPanel.d.ts +7 -0
- package/public/js/analysisPanel.js +166 -166
- package/public/js/analysisPanel.js.map +1 -0
- package/public/js/analysisReport.d.ts +38 -0
- package/public/js/analysisReport.js +105 -110
- package/public/js/analysisReport.js.map +1 -0
- package/public/js/api.d.ts +26 -0
- package/public/js/api.js +176 -167
- package/public/js/api.js.map +1 -0
- package/public/js/atlas.d.ts +6 -0
- package/public/js/atlas.js +50 -58
- package/public/js/atlas.js.map +1 -0
- package/public/js/blameView.d.ts +2 -0
- package/public/js/blameView.js +36 -37
- package/public/js/blameView.js.map +1 -0
- package/public/js/codeTab.d.ts +3 -0
- package/public/js/codeTab.js +175 -180
- package/public/js/codeTab.js.map +1 -0
- package/public/js/codeViewer.d.ts +5 -0
- package/public/js/codeViewer.js +162 -150
- package/public/js/codeViewer.js.map +1 -0
- package/public/js/components/FileChip.d.ts +9 -0
- package/public/js/components/FileChip.js +45 -49
- package/public/js/components/FileChip.js.map +1 -0
- package/public/js/components/MetricSparkline.d.ts +7 -0
- package/public/js/components/MetricSparkline.js +35 -44
- package/public/js/components/MetricSparkline.js.map +1 -0
- package/public/js/components/RiskBadge.d.ts +9 -0
- package/public/js/components/RiskBadge.js +55 -63
- package/public/js/components/RiskBadge.js.map +1 -0
- package/public/js/deepAnalysisView.d.ts +99 -0
- package/public/js/deepAnalysisView.js +282 -302
- package/public/js/deepAnalysisView.js.map +1 -0
- package/public/js/diagramPane.d.ts +8 -0
- package/public/js/diagramPane.js +133 -135
- package/public/js/diagramPane.js.map +1 -0
- package/public/js/diffView.d.ts +6 -0
- package/public/js/diffView.js +222 -209
- package/public/js/diffView.js.map +1 -0
- package/public/js/docsView.d.ts +2 -0
- package/public/js/docsView.js +441 -442
- package/public/js/docsView.js.map +1 -0
- package/public/js/dom.d.ts +189 -0
- package/public/js/dom.js +5 -0
- package/public/js/dom.js.map +1 -0
- package/public/js/fileSourceBrowser.d.ts +5 -0
- package/public/js/fileSourceBrowser.js +33 -41
- package/public/js/fileSourceBrowser.js.map +1 -0
- package/public/js/flameGraph.d.ts +5 -0
- package/public/js/flameGraph.js +62 -72
- package/public/js/flameGraph.js.map +1 -0
- package/public/js/forceGraph.d.ts +10 -0
- package/public/js/forceGraph.js +581 -556
- package/public/js/forceGraph.js.map +1 -0
- package/public/js/heatmap.d.ts +4 -0
- package/public/js/heatmap.js +142 -164
- package/public/js/heatmap.js.map +1 -0
- package/public/js/highlight.d.ts +2 -0
- package/public/js/highlight.js +116 -107
- package/public/js/highlight.js.map +1 -0
- package/public/js/html.d.ts +2 -0
- package/public/js/html.js +14 -44
- package/public/js/html.js.map +1 -0
- package/public/js/insightsView.d.ts +5 -0
- package/public/js/insightsView.js +93 -111
- package/public/js/insightsView.js.map +1 -0
- package/public/js/inspector.d.ts +37 -0
- package/public/js/inspector.js +416 -445
- package/public/js/inspector.js.map +1 -0
- package/public/js/llm.d.ts +113 -0
- package/public/js/llm.js +233 -272
- package/public/js/llm.js.map +1 -0
- package/public/js/mapView.d.ts +3 -0
- package/public/js/mapView.js +121 -120
- package/public/js/mapView.js.map +1 -0
- package/public/js/markdown.d.ts +3 -0
- package/public/js/markdown.js +84 -91
- package/public/js/markdown.js.map +1 -0
- package/public/js/mindmap.d.ts +32 -0
- package/public/js/mindmap.js +244 -259
- package/public/js/mindmap.js.map +1 -0
- package/public/js/mobilePanels.d.ts +5 -0
- package/public/js/mobilePanels.js +50 -0
- package/public/js/mobilePanels.js.map +1 -0
- package/public/js/repoFiles.d.ts +12 -0
- package/public/js/repoFiles.js +28 -27
- package/public/js/repoFiles.js.map +1 -0
- package/public/js/reviewView.d.ts +28 -0
- package/public/js/reviewView.js +256 -0
- package/public/js/reviewView.js.map +1 -0
- package/public/js/sbomView.d.ts +3 -0
- package/public/js/sbomView.js +59 -67
- package/public/js/sbomView.js.map +1 -0
- package/public/js/scanCache.d.ts +16 -0
- package/public/js/scanCache.js +67 -65
- package/public/js/scanCache.js.map +1 -0
- package/public/js/search.d.ts +7 -0
- package/public/js/search.js +868 -800
- package/public/js/search.js.map +1 -0
- package/public/js/searchLocal.d.ts +42 -0
- package/public/js/searchLocal.js +87 -0
- package/public/js/searchLocal.js.map +1 -0
- package/public/js/serverSettings.d.ts +5 -0
- package/public/js/serverSettings.js +153 -164
- package/public/js/serverSettings.js.map +1 -0
- package/public/js/state.d.ts +798 -0
- package/public/js/state.js +114 -122
- package/public/js/state.js.map +1 -0
- package/public/js/tour.d.ts +6 -0
- package/public/js/tour.js +5 -7
- package/public/js/tour.js.map +1 -0
- package/public/js/transitions.d.ts +2 -0
- package/public/js/transitions.js +9 -10
- package/public/js/transitions.js.map +1 -0
- package/public/js/tree.d.ts +12 -0
- package/public/js/tree.js +157 -154
- package/public/js/tree.js.map +1 -0
- package/public/js/workflowsView.d.ts +3 -0
- package/public/js/workflowsView.js +15 -22
- package/public/js/workflowsView.js.map +1 -0
- package/public/search.css +495 -0
- package/public/styles.css +163 -346
- package/public/workbench.css +166 -0
- package/server/apiAuth.d.ts +3 -0
- package/server/apiAuth.js +18 -20
- package/server/apiAuth.js.map +1 -0
- package/server/apiDiff.d.ts +2 -0
- package/server/apiDiff.js +20 -18
- package/server/apiDiff.js.map +1 -0
- package/server/apiDocs.d.ts +2 -0
- package/server/apiDocs.js +38 -40
- package/server/apiDocs.js.map +1 -0
- package/server/apiFile.d.ts +1 -0
- package/server/apiFile.js +14 -17
- package/server/apiFile.js.map +1 -0
- package/server/apiGitBlame.d.ts +2 -0
- package/server/apiGitBlame.js +50 -51
- package/server/apiGitBlame.js.map +1 -0
- package/server/apiMcp.d.ts +4 -0
- package/server/apiMcp.js +64 -66
- package/server/apiMcp.js.map +1 -0
- package/server/apiReview.d.ts +2 -0
- package/server/apiReview.js +45 -0
- package/server/apiReview.js.map +1 -0
- package/server/apiScan.d.ts +5 -0
- package/server/apiScan.js +90 -71
- package/server/apiScan.js.map +1 -0
- package/server/apiSearch.d.ts +33 -0
- package/server/apiSearch.js +184 -200
- package/server/apiSearch.js.map +1 -0
- package/server/apiSettings.d.ts +4 -0
- package/server/apiSettings.js +84 -85
- package/server/apiSettings.js.map +1 -0
- package/server/apiTools.d.ts +3 -0
- package/server/apiTools.js +55 -56
- package/server/apiTools.js.map +1 -0
- package/server/auth.d.ts +5 -0
- package/server/auth.js +54 -51
- package/server/auth.js.map +1 -0
- package/server/config.d.ts +42 -0
- package/server/config.js +189 -194
- package/server/config.js.map +1 -0
- package/server/daemon.d.ts +12 -0
- package/server/daemon.js +124 -114
- package/server/daemon.js.map +1 -0
- package/server/fileSourceNode.d.ts +2 -0
- package/server/fileSourceNode.js +34 -36
- package/server/fileSourceNode.js.map +1 -0
- package/server/gitClone.d.ts +9 -0
- package/server/gitClone.js +59 -61
- package/server/gitClone.js.map +1 -0
- package/server/gitDiff.d.ts +36 -0
- package/server/gitDiff.js +271 -169
- package/server/gitDiff.js.map +1 -0
- package/server/gitHistory.d.ts +12 -0
- package/server/gitHistory.js +80 -80
- package/server/gitHistory.js.map +1 -0
- package/server/gitRemote.d.ts +12 -0
- package/server/gitRemote.js +60 -0
- package/server/gitRemote.js.map +1 -0
- package/server/htmlText.d.ts +4 -0
- package/server/htmlText.js +16 -23
- package/server/htmlText.js.map +1 -0
- package/server/http.d.ts +5 -0
- package/server/http.js +27 -30
- package/server/http.js.map +1 -0
- package/server/httpGuards.d.ts +2 -0
- package/server/httpGuards.js +47 -43
- package/server/httpGuards.js.map +1 -0
- package/server/https.d.ts +34 -0
- package/server/https.js +121 -111
- package/server/https.js.map +1 -0
- package/server/index.d.ts +40 -0
- package/server/index.js +139 -147
- package/server/index.js.map +1 -0
- package/server/layout.d.ts +26 -0
- package/server/layout.js +59 -37
- package/server/layout.js.map +1 -0
- package/server/llmProxy.d.ts +3 -0
- package/server/llmProxy.js +137 -135
- package/server/llmProxy.js.map +1 -0
- package/server/logger.d.ts +38 -0
- package/server/logger.js +198 -211
- package/server/logger.js.map +1 -0
- package/server/mcp/analysis.d.ts +29 -0
- package/server/mcp/analysis.js +99 -120
- package/server/mcp/analysis.js.map +1 -0
- package/server/mcp/http.d.ts +9 -0
- package/server/mcp/http.js +128 -137
- package/server/mcp/http.js.map +1 -0
- package/server/mcp/runner.d.ts +68 -0
- package/server/mcp/runner.js +208 -218
- package/server/mcp/runner.js.map +1 -0
- package/server/mcp/server.d.ts +29 -0
- package/server/mcp/server.js +166 -179
- package/server/mcp/server.js.map +1 -0
- package/server/mcp/standalone.d.ts +1 -0
- package/server/mcp/standalone.js +8 -10
- package/server/mcp/standalone.js.map +1 -0
- package/server/mcp/tools.d.ts +2020 -0
- package/server/mcp/tools.js +523 -574
- package/server/mcp/tools.js.map +1 -0
- package/server/paths.d.ts +3 -0
- package/server/paths.js +17 -15
- package/server/paths.js.map +1 -0
- package/server/pidfile.d.ts +9 -0
- package/server/pidfile.js +43 -45
- package/server/pidfile.js.map +1 -0
- package/server/review.d.ts +5 -0
- package/server/review.js +35 -0
- package/server/review.js.map +1 -0
- package/server/router.d.ts +33 -0
- package/server/router.js +191 -197
- package/server/router.js.map +1 -0
- package/server/scanRequest.d.ts +3 -0
- package/server/scanRequest.js +36 -0
- package/server/scanRequest.js.map +1 -0
- package/server/searchIndex.d.ts +17 -0
- package/server/searchIndex.js +83 -80
- package/server/searchIndex.js.map +1 -0
- package/server/sessions.d.ts +14 -0
- package/server/sessions.js +62 -70
- package/server/sessions.js.map +1 -0
- package/server/startup.d.ts +118 -0
- package/server/startup.js +143 -148
- package/server/startup.js.map +1 -0
- package/server/static.d.ts +6 -0
- package/server/static.js +28 -31
- package/server/static.js.map +1 -0
- package/server/tools/install.d.ts +4 -0
- package/server/tools/install.js +176 -185
- package/server/tools/install.js.map +1 -0
- package/server/tools/parse.d.ts +8 -0
- package/server/tools/parse.js +112 -114
- package/server/tools/parse.js.map +1 -0
- package/server/tools/platform.d.ts +9 -0
- package/server/tools/platform.js +49 -47
- package/server/tools/platform.js.map +1 -0
- package/server/tools/registry.d.ts +137 -0
- package/server/tools/registry.js +173 -172
- package/server/tools/registry.js.map +1 -0
- package/server/tools/scan.d.ts +34 -0
- package/server/tools/scan.js +89 -98
- package/server/tools/scan.js.map +1 -0
- package/server/tools.d.ts +34 -0
- package/server/tools.js +94 -107
- package/server/tools.js.map +1 -0
- package/server/tunnel.d.ts +29 -0
- package/server/tunnel.js +61 -66
- package/server/tunnel.js.map +1 -0
- package/shared/analyzer/docs.d.ts +16 -0
- package/shared/analyzer/docs.js +99 -93
- package/shared/analyzer/docs.js.map +1 -0
- package/shared/analyzer/explainLocal.d.ts +4 -0
- package/shared/analyzer/explainLocal.js +122 -142
- package/shared/analyzer/explainLocal.js.map +1 -0
- package/shared/analyzer/github.d.ts +37 -0
- package/shared/analyzer/github.js +79 -0
- package/shared/analyzer/github.js.map +1 -0
- package/shared/analyzer/graph.d.ts +41 -0
- package/shared/analyzer/graph.js +393 -400
- package/shared/analyzer/graph.js.map +1 -0
- package/shared/analyzer/health.d.ts +33 -0
- package/shared/analyzer/health.js +197 -193
- package/shared/analyzer/health.js.map +1 -0
- package/shared/analyzer/history.d.ts +29 -0
- package/shared/analyzer/history.js +110 -111
- package/shared/analyzer/history.js.map +1 -0
- package/shared/analyzer/jsonConfig.d.ts +2 -0
- package/shared/analyzer/jsonConfig.js +61 -0
- package/shared/analyzer/jsonConfig.js.map +1 -0
- package/shared/analyzer/languages/csharp.d.ts +26 -0
- package/shared/analyzer/languages/csharp.js +83 -88
- package/shared/analyzer/languages/csharp.js.map +1 -0
- package/shared/analyzer/languages/generic.d.ts +23 -0
- package/shared/analyzer/languages/generic.js +94 -105
- package/shared/analyzer/languages/generic.js.map +1 -0
- package/shared/analyzer/languages/go.d.ts +24 -0
- package/shared/analyzer/languages/go.js +45 -54
- package/shared/analyzer/languages/go.js.map +1 -0
- package/shared/analyzer/languages/index.d.ts +6 -0
- package/shared/analyzer/languages/index.js +19 -20
- package/shared/analyzer/languages/index.js.map +1 -0
- package/shared/analyzer/languages/java.d.ts +20 -0
- package/shared/analyzer/languages/java.js +73 -78
- package/shared/analyzer/languages/java.js.map +1 -0
- package/shared/analyzer/languages/javascript.d.ts +12 -0
- package/shared/analyzer/languages/javascript.js +258 -209
- package/shared/analyzer/languages/javascript.js.map +1 -0
- package/shared/analyzer/languages/python.d.ts +23 -0
- package/shared/analyzer/languages/python.js +92 -100
- package/shared/analyzer/languages/python.js.map +1 -0
- package/shared/analyzer/languages/rust.d.ts +17 -0
- package/shared/analyzer/languages/rust.js +96 -98
- package/shared/analyzer/languages/rust.js.map +1 -0
- package/shared/analyzer/languages/typescript.d.ts +11 -0
- package/shared/analyzer/languages/typescript.js +117 -116
- package/shared/analyzer/languages/typescript.js.map +1 -0
- package/shared/analyzer/licenses.d.ts +18 -0
- package/shared/analyzer/licenses.js +130 -133
- package/shared/analyzer/licenses.js.map +1 -0
- package/shared/analyzer/metrics.d.ts +20 -0
- package/shared/analyzer/metrics.js +112 -104
- package/shared/analyzer/metrics.js.map +1 -0
- package/shared/analyzer/pathUtil.d.ts +10 -0
- package/shared/analyzer/pathUtil.js +29 -35
- package/shared/analyzer/pathUtil.js.map +1 -0
- package/shared/analyzer/patterns.d.ts +11 -0
- package/shared/analyzer/patterns.js +231 -253
- package/shared/analyzer/patterns.js.map +1 -0
- package/shared/analyzer/scan.d.ts +62 -0
- package/shared/analyzer/scan.js +451 -442
- package/shared/analyzer/scan.js.map +1 -0
- package/shared/analyzer/scanControl.d.ts +11 -0
- package/shared/analyzer/scanControl.js +62 -0
- package/shared/analyzer/scanControl.js.map +1 -0
- package/shared/analyzer/security.d.ts +18 -0
- package/shared/analyzer/security.js +159 -159
- package/shared/analyzer/security.js.map +1 -0
- package/shared/analyzer/services.d.ts +5 -0
- package/shared/analyzer/services.js +141 -138
- package/shared/analyzer/services.js.map +1 -0
- package/shared/analyzer/stack.d.ts +6 -0
- package/shared/analyzer/stack.js +134 -141
- package/shared/analyzer/stack.js.map +1 -0
- package/shared/analyzer/tour.d.ts +2 -0
- package/shared/analyzer/tour.js +45 -53
- package/shared/analyzer/tour.js.map +1 -0
- package/shared/analyzer/util.d.ts +8 -0
- package/shared/analyzer/util.js +130 -76
- package/shared/analyzer/util.js.map +1 -0
- package/shared/analyzer/workflows.d.ts +8 -0
- package/shared/analyzer/workflows.js +139 -134
- package/shared/analyzer/workflows.js.map +1 -0
- package/shared/contracts.d.ts +250 -0
- package/shared/contracts.js +2 -0
- package/shared/contracts.js.map +1 -0
- package/shared/diagram/aiFacts.d.ts +35 -0
- package/shared/diagram/aiFacts.js +102 -105
- package/shared/diagram/aiFacts.js.map +1 -0
- package/shared/diagram/aiMermaid.d.ts +5 -0
- package/shared/diagram/aiMermaid.js +46 -45
- package/shared/diagram/aiMermaid.js.map +1 -0
- package/shared/diagram/atlas.d.ts +16 -0
- package/shared/diagram/atlas.js +51 -60
- package/shared/diagram/atlas.js.map +1 -0
- package/shared/diagram/mermaid.d.ts +43 -0
- package/shared/diagram/mermaid.js +348 -370
- package/shared/diagram/mermaid.js.map +1 -0
- package/shared/review/contracts.d.ts +95 -0
- package/shared/review/contracts.js +2 -0
- package/shared/review/contracts.js.map +1 -0
- package/shared/review/review.d.ts +10 -0
- package/shared/review/review.js +184 -0
- package/shared/review/review.js.map +1 -0
- package/shared/search/query.d.ts +32 -0
- package/shared/search/query.js +395 -388
- package/shared/search/query.js.map +1 -0
package/public/js/highlight.js
CHANGED
|
@@ -2,121 +2,130 @@
|
|
|
2
2
|
// regex tokenizing, so highlighting is linear-time even on pathological
|
|
3
3
|
// input (an earlier master-regex version could stall on real files).
|
|
4
4
|
// Runs in Node (tests) and the browser.
|
|
5
|
-
|
|
6
5
|
import { escapeHtml } from './html.js';
|
|
7
|
-
|
|
8
6
|
const KEYWORDS = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
js: 'const let var function return import export from default if else for while do class extends new await async try catch finally throw typeof instanceof of in switch case break continue yield static get set super this null undefined true false void delete',
|
|
8
|
+
py: 'def class return import from as if elif else for while in not and or is None True False try except finally raise with lambda pass break continue yield global nonlocal assert async await del',
|
|
9
|
+
go: 'func package import return if else for range var const type struct interface map chan go defer select switch case break continue fallthrough default nil true false iota',
|
|
10
|
+
c: 'int void char float double long short unsigned signed const static return if else for while do switch case break continue struct union enum typedef sizeof include define extern volatile register goto',
|
|
13
11
|
};
|
|
14
|
-
|
|
15
12
|
export function langOf(path) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
const ext = (path.match(/\.([A-Za-z0-9]+)$/) || [, ''])[1].toLowerCase();
|
|
14
|
+
if (['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'json'].includes(ext))
|
|
15
|
+
return 'js';
|
|
16
|
+
if (['py', 'pyi'].includes(ext))
|
|
17
|
+
return 'py';
|
|
18
|
+
if (ext === 'go')
|
|
19
|
+
return 'go';
|
|
20
|
+
if (['c', 'h', 'cpp', 'cc', 'java', 'rs', 'rb', 'php', 'cs', 'swift', 'kt', 'css'].includes(ext))
|
|
21
|
+
return 'c';
|
|
22
|
+
return null; // markdown, yaml, toml, plain text — shown unadorned
|
|
22
23
|
}
|
|
23
|
-
|
|
24
24
|
const isWordStart = (c) => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c === '_' || c === '$';
|
|
25
25
|
const isWordPart = (c) => isWordStart(c) || (c >= '0' && c <= '9');
|
|
26
26
|
const isDigit = (c) => c >= '0' && c <= '9';
|
|
27
|
-
|
|
28
27
|
export function highlightCode(source, lang) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
28
|
+
if (!lang || !KEYWORDS[lang])
|
|
29
|
+
return escapeHtml(source);
|
|
30
|
+
const kw = new Set(KEYWORDS[lang].split(' '));
|
|
31
|
+
const hashComment = lang === 'py';
|
|
32
|
+
const out = [];
|
|
33
|
+
let plain = '';
|
|
34
|
+
const flushPlain = () => {
|
|
35
|
+
if (plain) {
|
|
36
|
+
out.push(escapeHtml(plain));
|
|
37
|
+
plain = '';
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const emit = (cls, text) => {
|
|
41
|
+
flushPlain();
|
|
42
|
+
out.push(`<span class="${cls}">${escapeHtml(text)}</span>`);
|
|
43
|
+
};
|
|
44
|
+
const n = source.length;
|
|
45
|
+
let i = 0;
|
|
46
|
+
while (i < n) {
|
|
47
|
+
const c = source[i];
|
|
48
|
+
// Line comments: # for python, // elsewhere.
|
|
49
|
+
if ((hashComment && c === '#') || (!hashComment && c === '/' && source[i + 1] === '/')) {
|
|
50
|
+
let j = source.indexOf('\n', i);
|
|
51
|
+
if (j === -1)
|
|
52
|
+
j = n;
|
|
53
|
+
emit('tok-com', source.slice(i, j));
|
|
54
|
+
i = j;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
// Block comments (and preprocessor lines for the C family).
|
|
58
|
+
if (!hashComment && c === '/' && source[i + 1] === '*') {
|
|
59
|
+
const end = source.indexOf('*/', i + 2);
|
|
60
|
+
const j = end === -1 ? n : end + 2;
|
|
61
|
+
emit('tok-com', source.slice(i, j));
|
|
62
|
+
i = j;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (lang === 'c' && c === '#' && (i === 0 || source[i - 1] === '\n')) {
|
|
66
|
+
let j = source.indexOf('\n', i);
|
|
67
|
+
if (j === -1)
|
|
68
|
+
j = n;
|
|
69
|
+
emit('tok-com', source.slice(i, j));
|
|
70
|
+
i = j;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
// Strings. Python triple quotes first; backticks are multiline in js/go.
|
|
74
|
+
if (lang === 'py' && (source.startsWith("'''", i) || source.startsWith('"""', i))) {
|
|
75
|
+
const q = source.slice(i, i + 3);
|
|
76
|
+
const end = source.indexOf(q, i + 3);
|
|
77
|
+
const j = end === -1 ? n : end + 3;
|
|
78
|
+
emit('tok-str', source.slice(i, j));
|
|
79
|
+
i = j;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (c === "'" || c === '"' || (c === '`' && lang !== 'py' && lang !== 'c')) {
|
|
83
|
+
const multiline = c === '`' || lang === 'py';
|
|
84
|
+
let j = i + 1;
|
|
85
|
+
while (j < n) {
|
|
86
|
+
const d = source[j];
|
|
87
|
+
if (d === '\\') {
|
|
88
|
+
j += 2;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (d === c) {
|
|
92
|
+
j++;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
if (d === '\n' && !multiline)
|
|
96
|
+
break; // unterminated: stop at the line end
|
|
97
|
+
j++;
|
|
98
|
+
}
|
|
99
|
+
emit('tok-str', source.slice(i, j));
|
|
100
|
+
i = j;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
// Words → keywords when the language claims them.
|
|
104
|
+
if (isWordStart(c)) {
|
|
105
|
+
let j = i + 1;
|
|
106
|
+
while (j < n && isWordPart(source[j]))
|
|
107
|
+
j++;
|
|
108
|
+
const w = source.slice(i, j);
|
|
109
|
+
if (kw.has(w))
|
|
110
|
+
emit('tok-kw', w);
|
|
111
|
+
else
|
|
112
|
+
plain += w;
|
|
113
|
+
i = j;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
// Numbers.
|
|
117
|
+
if (isDigit(c)) {
|
|
118
|
+
let j = i + 1;
|
|
119
|
+
while (j < n && (isDigit(source[j]) || source[j] === '.' || source[j] === '_'))
|
|
120
|
+
j++;
|
|
121
|
+
emit('tok-num', source.slice(i, j));
|
|
122
|
+
i = j;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
plain += c;
|
|
126
|
+
i++;
|
|
81
127
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
let j = i + 1;
|
|
85
|
-
while (j < n) {
|
|
86
|
-
const d = source[j];
|
|
87
|
-
if (d === '\\') { j += 2; continue; }
|
|
88
|
-
if (d === c) { j++; break; }
|
|
89
|
-
if (d === '\n' && !multiline) break; // unterminated: stop at the line end
|
|
90
|
-
j++;
|
|
91
|
-
}
|
|
92
|
-
emit('tok-str', source.slice(i, j));
|
|
93
|
-
i = j;
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Words → keywords when the language claims them.
|
|
98
|
-
if (isWordStart(c)) {
|
|
99
|
-
let j = i + 1;
|
|
100
|
-
while (j < n && isWordPart(source[j])) j++;
|
|
101
|
-
const w = source.slice(i, j);
|
|
102
|
-
if (kw.has(w)) emit('tok-kw', w);
|
|
103
|
-
else plain += w;
|
|
104
|
-
i = j;
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Numbers.
|
|
109
|
-
if (isDigit(c)) {
|
|
110
|
-
let j = i + 1;
|
|
111
|
-
while (j < n && (isDigit(source[j]) || source[j] === '.' || source[j] === '_')) j++;
|
|
112
|
-
emit('tok-num', source.slice(i, j));
|
|
113
|
-
i = j;
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
plain += c;
|
|
118
|
-
i++;
|
|
119
|
-
}
|
|
120
|
-
flushPlain();
|
|
121
|
-
return out.join('');
|
|
128
|
+
flushPlain();
|
|
129
|
+
return out.join('');
|
|
122
130
|
}
|
|
131
|
+
//# sourceMappingURL=highlight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight.js","sourceRoot":"","sources":["../../src/public/js/highlight.ts"],"names":[],"mappings":"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","sourcesContent":["// Hand-rolled syntax highlighting — a single left-to-right scanner, no\n// regex tokenizing, so highlighting is linear-time even on pathological\n// input (an earlier master-regex version could stall on real files).\n// Runs in Node (tests) and the browser.\n\nimport { escapeHtml } from './html.js';\n\nconst KEYWORDS = {\n js: 'const let var function return import export from default if else for while do class extends new await async try catch finally throw typeof instanceof of in switch case break continue yield static get set super this null undefined true false void delete',\n py: 'def class return import from as if elif else for while in not and or is None True False try except finally raise with lambda pass break continue yield global nonlocal assert async await del',\n go: 'func package import return if else for range var const type struct interface map chan go defer select switch case break continue fallthrough default nil true false iota',\n c: 'int void char float double long short unsigned signed const static return if else for while do switch case break continue struct union enum typedef sizeof include define extern volatile register goto',\n};\n\nexport function langOf(path) {\n const ext = (path.match(/\\.([A-Za-z0-9]+)$/) || [, ''])[1].toLowerCase();\n if (['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'json'].includes(ext)) return 'js';\n if (['py', 'pyi'].includes(ext)) return 'py';\n if (ext === 'go') return 'go';\n if (['c', 'h', 'cpp', 'cc', 'java', 'rs', 'rb', 'php', 'cs', 'swift', 'kt', 'css'].includes(ext)) return 'c';\n return null; // markdown, yaml, toml, plain text — shown unadorned\n}\n\nconst isWordStart = (c) => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c === '_' || c === '$';\nconst isWordPart = (c) => isWordStart(c) || (c >= '0' && c <= '9');\nconst isDigit = (c) => c >= '0' && c <= '9';\n\nexport function highlightCode(source, lang) {\n if (!lang || !KEYWORDS[lang]) return escapeHtml(source);\n const kw = new Set(KEYWORDS[lang].split(' '));\n const hashComment = lang === 'py';\n const out = [];\n let plain = '';\n\n const flushPlain = () => {\n if (plain) { out.push(escapeHtml(plain)); plain = ''; }\n };\n const emit = (cls, text) => {\n flushPlain();\n out.push(`<span class=\"${cls}\">${escapeHtml(text)}</span>`);\n };\n\n const n = source.length;\n let i = 0;\n while (i < n) {\n const c = source[i];\n\n // Line comments: # for python, // elsewhere.\n if ((hashComment && c === '#') || (!hashComment && c === '/' && source[i + 1] === '/')) {\n let j = source.indexOf('\\n', i);\n if (j === -1) j = n;\n emit('tok-com', source.slice(i, j));\n i = j;\n continue;\n }\n\n // Block comments (and preprocessor lines for the C family).\n if (!hashComment && c === '/' && source[i + 1] === '*') {\n const end = source.indexOf('*/', i + 2);\n const j = end === -1 ? n : end + 2;\n emit('tok-com', source.slice(i, j));\n i = j;\n continue;\n }\n if (lang === 'c' && c === '#' && (i === 0 || source[i - 1] === '\\n')) {\n let j = source.indexOf('\\n', i);\n if (j === -1) j = n;\n emit('tok-com', source.slice(i, j));\n i = j;\n continue;\n }\n\n // Strings. Python triple quotes first; backticks are multiline in js/go.\n if (lang === 'py' && (source.startsWith(\"'''\", i) || source.startsWith('\"\"\"', i))) {\n const q = source.slice(i, i + 3);\n const end = source.indexOf(q, i + 3);\n const j = end === -1 ? n : end + 3;\n emit('tok-str', source.slice(i, j));\n i = j;\n continue;\n }\n if (c === \"'\" || c === '\"' || (c === '`' && lang !== 'py' && lang !== 'c')) {\n const multiline = c === '`' || lang === 'py';\n let j = i + 1;\n while (j < n) {\n const d = source[j];\n if (d === '\\\\') { j += 2; continue; }\n if (d === c) { j++; break; }\n if (d === '\\n' && !multiline) break; // unterminated: stop at the line end\n j++;\n }\n emit('tok-str', source.slice(i, j));\n i = j;\n continue;\n }\n\n // Words → keywords when the language claims them.\n if (isWordStart(c)) {\n let j = i + 1;\n while (j < n && isWordPart(source[j])) j++;\n const w = source.slice(i, j);\n if (kw.has(w)) emit('tok-kw', w);\n else plain += w;\n i = j;\n continue;\n }\n\n // Numbers.\n if (isDigit(c)) {\n let j = i + 1;\n while (j < n && (isDigit(source[j]) || source[j] === '.' || source[j] === '_')) j++;\n emit('tok-num', source.slice(i, j));\n i = j;\n continue;\n }\n\n plain += c;\n i++;\n }\n flushPlain();\n return out.join('');\n}\n"]}
|
package/public/js/html.js
CHANGED
|
@@ -1,50 +1,20 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// Onboarder renders content it does not control: file and folder names from a
|
|
4
|
-
// repository that may have been cloned from an arbitrary git URL, READMEs,
|
|
5
|
-
// GitHub API fields, and model output. All of it reaches the DOM as HTML
|
|
6
|
-
// strings, and a good deal of it lands inside attributes
|
|
7
|
-
// (`title="…"`, `data-path="…"`). So quotes matter as much as angle brackets:
|
|
8
|
-
// a file named `x" onmouseover="…` closes the attribute and opens a handler,
|
|
9
|
-
// and double quotes are legal in filenames on macOS and Linux.
|
|
10
|
-
//
|
|
11
|
-
// This used to be five near-copies — four of which escaped only & < > — with
|
|
12
|
-
// the attribute call sites quietly relying on the one that didn't. Now there
|
|
13
|
-
// is one function and it escapes all five characters.
|
|
14
|
-
//
|
|
15
|
-
// Single pass, one regex, one lookup per match: strictly cheaper than the
|
|
16
|
-
// chain of four .replace() calls it replaces, which matters because the
|
|
17
|
-
// syntax highlighter runs this over every token of every file.
|
|
18
|
-
|
|
1
|
+
// Escape untrusted repository data at the boundary before placing it in HTML.
|
|
19
2
|
const ESCAPES = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
3
|
+
'&': '&',
|
|
4
|
+
'<': '<',
|
|
5
|
+
'>': '>',
|
|
6
|
+
'"': '"',
|
|
7
|
+
"'": ''',
|
|
25
8
|
};
|
|
26
|
-
|
|
27
9
|
const NEEDS_ESCAPE = /[&<>"']/g;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
* Make a string safe to interpolate into HTML — as text, or inside a
|
|
31
|
-
* double- or single-quoted attribute value.
|
|
32
|
-
*/
|
|
33
|
-
export function escapeHtml(s) {
|
|
34
|
-
return String(s ?? '').replace(NEEDS_ESCAPE, (c) => ESCAPES[c]);
|
|
10
|
+
export function escapeHtml(value) {
|
|
11
|
+
return String(value ?? '').replace(NEEDS_ESCAPE, (character) => ESCAPES[character]);
|
|
35
12
|
}
|
|
36
|
-
|
|
37
|
-
// Whitespace and C0/C1 control characters, which browsers ignore when they
|
|
38
|
-
// parse a URL scheme — so `java\tscript:alert(1)` is a live javascript: URL.
|
|
39
13
|
const URL_NOISE = /[\s\u0000-\u001F\u007F-\u009F]/g;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
*/
|
|
46
|
-
export function safeUrl(url) {
|
|
47
|
-
const raw = String(url ?? '').trim();
|
|
48
|
-
if (!/^https?:\/\//i.test(raw.replace(URL_NOISE, ''))) return '';
|
|
49
|
-
return escapeHtml(raw);
|
|
14
|
+
export function safeUrl(value) {
|
|
15
|
+
const raw = String(value ?? '').trim();
|
|
16
|
+
if (!/^https?:\/\//i.test(raw.replace(URL_NOISE, '')))
|
|
17
|
+
return '';
|
|
18
|
+
return escapeHtml(raw);
|
|
50
19
|
}
|
|
20
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/public/js/html.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,OAAO,GAA2B;IACtC,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,OAAO;CACb,CAAC;AAEF,MAAM,YAAY,GAAG,UAAU,CAAC;AAEhC,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,SAAS,GAAG,iCAAiC,CAAC;AAEpD,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACvC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IACjE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC","sourcesContent":["// Escape untrusted repository data at the boundary before placing it in HTML.\nconst ESCAPES: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n};\n\nconst NEEDS_ESCAPE = /[&<>\"']/g;\n\nexport function escapeHtml(value: unknown): string {\n return String(value ?? '').replace(NEEDS_ESCAPE, (character) => ESCAPES[character]);\n}\n\nconst URL_NOISE = /[\\s\\u0000-\\u001F\\u007F-\\u009F]/g;\n\nexport function safeUrl(value: unknown): string {\n const raw = String(value ?? '').trim();\n if (!/^https?:\\/\\//i.test(raw.replace(URL_NOISE, ''))) return '';\n return escapeHtml(raw);\n}\n"]}
|
|
@@ -1,42 +1,37 @@
|
|
|
1
1
|
// GitHub Insights & Pulse View.
|
|
2
2
|
// Renders 52-week contribution heatmap, contributor leaderboard, punchcard, and release timeline.
|
|
3
|
-
|
|
4
3
|
import { escapeHtml } from './html.js';
|
|
5
|
-
|
|
6
4
|
export function renderInsights(container, { scan, facts, history }) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
if (!container)
|
|
6
|
+
return;
|
|
7
|
+
const commits = history?.commits || [];
|
|
8
|
+
const authorMap = new Map();
|
|
9
|
+
const dayHourMatrix = Array.from({ length: 7 }, () => Array(24).fill(0));
|
|
10
|
+
const dayCounts = new Map();
|
|
11
|
+
// Process commit dates & authors
|
|
12
|
+
for (const c of commits) {
|
|
13
|
+
const { key, name } = authorIdentity(c.author);
|
|
14
|
+
if (!authorMap.has(key)) {
|
|
15
|
+
authorMap.set(key, { name, commits: 0, additions: 0, deletions: 0, firstDate: c.date, lastDate: c.date, files: new Set() });
|
|
16
|
+
}
|
|
17
|
+
const a = authorMap.get(key);
|
|
18
|
+
a.commits++;
|
|
19
|
+
if (c.date < a.firstDate)
|
|
20
|
+
a.firstDate = c.date;
|
|
21
|
+
if (c.date > a.lastDate)
|
|
22
|
+
a.lastDate = c.date;
|
|
23
|
+
const d = new Date(c.date || Date.now());
|
|
24
|
+
if (!isNaN(d.getTime())) {
|
|
25
|
+
const day = d.getDay(); // 0 = Sun, 6 = Sat
|
|
26
|
+
const hour = d.getHours();
|
|
27
|
+
dayHourMatrix[day][hour]++;
|
|
28
|
+
const ymd = d.toISOString().slice(0, 10);
|
|
29
|
+
dayCounts.set(ymd, (dayCounts.get(ymd) || 0) + 1);
|
|
30
|
+
}
|
|
19
31
|
}
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (c.date > a.lastDate) a.lastDate = c.date;
|
|
24
|
-
|
|
25
|
-
const d = new Date(c.date || Date.now());
|
|
26
|
-
if (!isNaN(d.getTime())) {
|
|
27
|
-
const day = d.getDay(); // 0 = Sun, 6 = Sat
|
|
28
|
-
const hour = d.getHours();
|
|
29
|
-
dayHourMatrix[day][hour]++;
|
|
30
|
-
|
|
31
|
-
const ymd = d.toISOString().slice(0, 10);
|
|
32
|
-
dayCounts.set(ymd, (dayCounts.get(ymd) || 0) + 1);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const sortedAuthors = [...authorMap.values()].sort((a, b) => b.commits - a.commits);
|
|
37
|
-
const totalCommits = commits.length || 1;
|
|
38
|
-
|
|
39
|
-
container.innerHTML = `
|
|
32
|
+
const sortedAuthors = [...authorMap.values()].sort((a, b) => b.commits - a.commits);
|
|
33
|
+
const totalCommits = commits.length || 1;
|
|
34
|
+
container.innerHTML = `
|
|
40
35
|
<div class="insights-layout">
|
|
41
36
|
<section class="insights-hero">
|
|
42
37
|
<div class="insights-stat-card">
|
|
@@ -106,63 +101,54 @@ export function renderInsights(container, { scan, facts, history }) {
|
|
|
106
101
|
</div>
|
|
107
102
|
`;
|
|
108
103
|
}
|
|
109
|
-
|
|
110
104
|
// gitHistory shapes commit.author as { name, email }; a bare string is also
|
|
111
105
|
// tolerated so older cached payloads don't break the view. Commits are grouped
|
|
112
106
|
// by email when present — the same person with two name spellings is one
|
|
113
107
|
// contributor, like shared/analyzer/history.js does server-side.
|
|
114
108
|
function authorIdentity(author) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
109
|
+
if (author && typeof author === 'object') {
|
|
110
|
+
const name = author.name || author.email || 'Anonymous';
|
|
111
|
+
return { key: author.email || name, name };
|
|
112
|
+
}
|
|
113
|
+
const name = author || 'Anonymous';
|
|
114
|
+
return { key: name, name };
|
|
121
115
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
116
|
function renderCalendarHeatmap(dayCounts) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const x = w * (cellSize + cellGap) + 30;
|
|
152
|
-
const y = d * (cellSize + cellGap) + 20;
|
|
153
|
-
|
|
154
|
-
cells.push(`
|
|
117
|
+
const weeks = 52;
|
|
118
|
+
const daysPerWeek = 7;
|
|
119
|
+
const cellSize = 12;
|
|
120
|
+
const cellGap = 3;
|
|
121
|
+
const now = new Date();
|
|
122
|
+
const cells = [];
|
|
123
|
+
const oneDayMs = 24 * 60 * 60 * 1000;
|
|
124
|
+
// Align to end on current day
|
|
125
|
+
const endDay = new Date(now);
|
|
126
|
+
const startDay = new Date(endDay.getTime() - (weeks * 7) * oneDayMs);
|
|
127
|
+
let maxCount = 1;
|
|
128
|
+
for (const c of dayCounts.values())
|
|
129
|
+
if (c > maxCount)
|
|
130
|
+
maxCount = c;
|
|
131
|
+
const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
132
|
+
for (let w = 0; w < weeks; w++) {
|
|
133
|
+
for (let d = 0; d < 7; d++) {
|
|
134
|
+
const cur = new Date(startDay.getTime() + (w * 7 + d) * oneDayMs);
|
|
135
|
+
const ymd = cur.toISOString().slice(0, 10);
|
|
136
|
+
const count = dayCounts.get(ymd) || 0;
|
|
137
|
+
let level = 0;
|
|
138
|
+
if (count > 0)
|
|
139
|
+
level = Math.min(4, Math.ceil((count / maxCount) * 4));
|
|
140
|
+
const x = w * (cellSize + cellGap) + 30;
|
|
141
|
+
const y = d * (cellSize + cellGap) + 20;
|
|
142
|
+
cells.push(`
|
|
155
143
|
<rect class="cal-cell lvl-${level}" x="${x}" y="${y}" width="${cellSize}" height="${cellSize}" rx="2">
|
|
156
144
|
<title>${ymd}: ${count} commit${count === 1 ? '' : 's'}</title>
|
|
157
145
|
</rect>
|
|
158
146
|
`);
|
|
147
|
+
}
|
|
159
148
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const svgHeight = 7 * (cellSize + cellGap) + 30;
|
|
164
|
-
|
|
165
|
-
return `
|
|
149
|
+
const svgWidth = weeks * (cellSize + cellGap) + 40;
|
|
150
|
+
const svgHeight = 7 * (cellSize + cellGap) + 30;
|
|
151
|
+
return `
|
|
166
152
|
<div class="cal-scroll-wrap">
|
|
167
153
|
<svg class="cal-heatmap-svg" viewBox="0 0 ${svgWidth} ${svgHeight}" style="max-width: 100%; height: auto;">
|
|
168
154
|
<text class="cal-label" x="5" y="42">Mon</text>
|
|
@@ -182,49 +168,44 @@ function renderCalendarHeatmap(dayCounts) {
|
|
|
182
168
|
</div>
|
|
183
169
|
`;
|
|
184
170
|
}
|
|
185
|
-
|
|
186
171
|
function renderPunchcardSvg(matrix) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
172
|
+
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
173
|
+
const cellW = 20;
|
|
174
|
+
const cellH = 20;
|
|
175
|
+
const padLeft = 40;
|
|
176
|
+
const padTop = 20;
|
|
177
|
+
let max = 1;
|
|
178
|
+
for (let d = 0; d < 7; d++) {
|
|
179
|
+
for (let h = 0; h < 24; h++) {
|
|
180
|
+
if (matrix[d][h] > max)
|
|
181
|
+
max = matrix[d][h];
|
|
182
|
+
}
|
|
197
183
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
dots.push(`
|
|
184
|
+
const dots = [];
|
|
185
|
+
for (let d = 0; d < 7; d++) {
|
|
186
|
+
for (let h = 0; h < 24; h++) {
|
|
187
|
+
const val = matrix[d][h];
|
|
188
|
+
if (val === 0)
|
|
189
|
+
continue;
|
|
190
|
+
const r = Math.max(2, Math.min(8, (val / max) * 8));
|
|
191
|
+
const cx = padLeft + h * cellW + cellW / 2;
|
|
192
|
+
const cy = padTop + d * cellH + cellH / 2;
|
|
193
|
+
dots.push(`
|
|
209
194
|
<circle cx="${cx}" cy="${cy}" r="${r}" class="punch-dot">
|
|
210
195
|
<title>${days[d]} ${h}:00 - ${val} commit${val === 1 ? '' : 's'}</title>
|
|
211
196
|
</circle>
|
|
212
197
|
`);
|
|
198
|
+
}
|
|
213
199
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const hoursHeader = [0, 4, 8, 12, 16, 20].map((h) => `
|
|
200
|
+
const hoursHeader = [0, 4, 8, 12, 16, 20].map((h) => `
|
|
217
201
|
<text class="punch-lbl" x="${padLeft + h * cellW + cellW / 2}" y="12" text-anchor="middle">${h}h</text>
|
|
218
202
|
`).join('');
|
|
219
|
-
|
|
220
|
-
const daysHeader = days.map((day, idx) => `
|
|
203
|
+
const daysHeader = days.map((day, idx) => `
|
|
221
204
|
<text class="punch-lbl" x="5" y="${padTop + idx * cellH + cellH / 2 + 4}">${day}</text>
|
|
222
205
|
`).join('');
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
return `
|
|
206
|
+
const svgW = padLeft + 24 * cellW + 10;
|
|
207
|
+
const svgH = padTop + 7 * cellH + 10;
|
|
208
|
+
return `
|
|
228
209
|
<div class="cal-scroll-wrap">
|
|
229
210
|
<svg class="punch-svg" viewBox="0 0 ${svgW} ${svgH}">
|
|
230
211
|
${hoursHeader}
|
|
@@ -234,3 +215,4 @@ function renderPunchcardSvg(matrix) {
|
|
|
234
215
|
</div>
|
|
235
216
|
`;
|
|
236
217
|
}
|
|
218
|
+
//# sourceMappingURL=insightsView.js.map
|