Commit c54806f
authored
feat(secrets): add Snyk Secrets product type [IDE-1126][IDE-1749] (#788)
* chore: add skills and rules
* feat(ui): add JCEF-based HTML tree view behind registry flag [IDE-1750]
Implement Phase 7 of the HTML tree view integration. When the
IntelliJ Registry flag `snyk.useHtmlTreeView` is enabled, the native
Swing tree + severity toolbar in SnykToolWindowPanel is replaced with
a JCEF-based HtmlTreePanel that renders server-driven HTML from the
`$/snyk.treeView` LSP notification.
Changes:
- Add `snyk.useHtmlTreeView` registry key in plugin.xml
- Add `isHtmlTreeViewEnabled()` helper in Utils.kt
- Add `SnykTreeViewParams` data class and `SnykTreeViewListener` topic
- Add `@JsonNotification("$/snyk.treeView")` handler in SnykLanguageClient
- Add `executeCommandWithArgs()` public method on LanguageServerWrapper
- Add `TreeViewBridgeHandler` with unified `__ideExecuteCommand__` JS bridge
- Add `HtmlTreePanel` JCEF panel subscribing to tree view notifications
- Conditionally swap TreePanel/HtmlTreePanel in SnykToolWindowPanel
- Hide native ViewActions and expand/collapse toolbar when flag is ON
- Add unit tests for bridge dispatch logic and LSP notification handler
* chore: update .gitignore
* chore: update build
* chore: update hooks to use spotlessApply
* chore: update skill
* fix: introduce init HTML
* chore: adjust coverage rules
* test: add coverage for HtmlTreePanel, executeCommandWithArgs, TreeViewBridgeHandler [IDE-1750]
- Add HtmlTreePanelTest: init, dispose, JCEF null path, notification
handling, resource file validation, placeholder replacement
- Add executeCommandWithArgs tests to LanguageServerWrapperTest:
not-initialized guard, successful execution, argument passing, null result
- Extend TreeViewBridgeHandlerTest: concurrent dispatch, LS exception
handling, null callbackExecutor, default values, missing fields
* chore: update skills
* chore: update required protocol version to 23
* fix: invoke JS callback on null LS result to prevent callback leak [IDE-1750]
- Remove result != null guard in dispatchCommand so callbacks fire even
when LanguageServerWrapper.executeCommandWithArgs returns null (e.g.
navigateToRange side-effect commands). Prevents leaked entries in
window.__ideCallbacks__ and stalled UI state.
- Change snyk.useHtmlTreeView registry key to restartRequired=true since
the panel swap only happens at SnykToolWindowPanel init time.
- Update test to assert callback IS invoked with null result (TDD).
* chore: update verification skill
* fix: address PR review findings for HTML tree view [IDE-1750]
- Fix JCEF browser memory leak: store browser as field, dispose in dispose()
- Replace SimpleToolWindowPanel with JPanel (fixes UiDataProvider warning)
- Add command allowlist to TreeViewBridgeHandler (security hardening)
- Add callbackId validation regex to prevent JS injection
- Skip native tree refresh when HTML tree view is enabled (performance)
- Replace Thread.sleep with Awaitility in tests
- Add tests for buildBridgeScript, ALLOWED_COMMANDS, and all new guards
* fix: fall back to native TreePanel when JCEF is unsupported [IDE-1750]
Add JBCefApp.isSupported() check before creating HtmlTreePanel to prevent
blank panel on systems without JCEF support. Falls back to native Swing
TreePanel gracefully.
* fix: implement showDocument for file URIs to enable tree view navigation [IDE-1750]
The LS snyk.navigateToRange command calls window/showDocument with a file
URI back to the client. The previous implementation fell through to
super.showDocument() which threw UnsupportedOperationException.
Now handles file URIs by resolving the VirtualFile and navigating to the
selection range. Unsupported schemes return ShowDocumentResult(false)
gracefully instead of throwing.
* fix: correct command allowlist — replace snyk.getTreeView with snyk.setNodeExpanded [IDE-1750]
The JS tree view uses snyk.setNodeExpanded for expand/collapse state
persistence but it was missing from the allowlist. snyk.getTreeView was
listed but never used by the JS.
* fix: display issue details in HTML tree view + deduplicate tree HTML [IDE-1750]
- onShowIssueDetail: bypass native tree search when HTML tree enabled,
directly create SuggestionDescriptionPanel from cached ScanIssue
- HtmlTreePanel: skip loadHTML when raw HTML hash unchanged to prevent
tree collapse on redundant LS re-emissions
* fix: broaden showDocument to all products + add debug logging [IDE-1750]
- showDocument: match any snyk:// URI with showInDetailPanel action,
not just Snyk Code. Map product string to correct ProductType.
- onShowIssueDetail: bypass native tree for HTML tree mode, directly
create SuggestionDescriptionPanel from cached ScanIssue.
- Add diagnostic logging to trace showDocument and cache lookup flow.
* feat: add tree view CSS variable mappings to ThemeBasedStylingGenerator [IDE-1750]
Add 7 missing --vscode-* CSS variable mappings needed by the HTML tree
view styles.css: tree-indentGuidesStroke, sideBar-background,
badge-background/foreground, list-activeSelectionBackground/Foreground,
list-hoverBackground.
* feat: select HTML tree node when gutter icon clicked [IDE-1750]
- Add HtmlTreePanel.selectNode() to execute __selectTreeNode__ JS bridge
- Store HtmlTreePanel reference in SnykToolWindowPanel
- Wire selectNodeAndDisplayDescription to also select in HTML tree
- Expands ancestor nodes and scrolls issue into view
* feat: select HTML tree node on showDocument snyk:// URI [IDE-1750]
Wire onShowIssueDetail to also call htmlTreePanel.selectNode when
processing snyk:// showDocument requests, so the tree highlights the
corresponding issue node.
* feat: reset HTML tree on clean all results action [IDE-1750]
- Add HtmlTreePanel.reset() to reload initial empty HTML
- Call reset() from doCleanUi so 'Clean all results' clears the HTML tree
* feat: replace spinner init HTML with proper product nodes tree [IDE-1750]
TreeViewInit.html now renders the same structure as the LS tree:
- Filter toolbar with severity SVG buttons (all active)
- Expand/collapse all buttons
- 3 product nodes (Open Source, Code Security, Infrastructure As Code)
with their inline SVG icons, matching the LS tree.html template
- Uses the same CSS classes for theme integration via var(--vscode-*)
* fix: update description panel directly when HTML tree active [IDE-1750]
When isHtmlTreeViewEnabled(), selectNodeAndDisplayDescription now
directly loads SuggestionDescriptionPanel instead of relying on
native JTree node lookup (which may not have nodes populated).
Fixes gutter icon click sometimes not updating the description panel.
* refactor: extract selectNodeInHtmlTreeAndShowDescription + fix unsafe offset [IDE-1750]
- Extract duplicated HTML tree description panel update logic into
private selectNodeInHtmlTreeAndShowDescription method, called from
both onShowIssueDetail and selectNodeAndDisplayDescription.
- Fix unsafe offset calculation in showDocument file URI handler by
clamping startOffset/endOffset to document.textLength, preventing
IndexOutOfBoundsException when character exceeds line length.
* test: add coverage for HtmlTreePanel reset, selectNode, and dedup [IDE-1750]
Add tests for:
- reset() reloads init HTML into browser
- reset() skipped after dispose
- reset() no-op when JCEF is null
- selectNode() no-op when JCEF is null
- duplicate HTML content is skipped (hash check)
HtmlTreePanel coverage: 71.2% -> 86.4%
* chore: bump required LS protocol version to 24 [IDE-1750]
* feat(treeview): add missing commands to TreeViewBridgeHandler allowlist [IDE-1750]
Add snyk.showScanErrorDetails and snyk.updateFolderConfig to the
JCEF bridge allowlist so tree.js can invoke them via
__ideExecuteCommand__.
* test(treeview): update allowlist tests for new commands [IDE-1750]
Add snyk.showScanErrorDetails and snyk.updateFolderConfig to the
expected commands in TreeViewBridgeHandlerTest.
* fix: address PR review findings in SnykToolWindowPanel, SnykLanguageClient, Types [IDE-1750]
- Add missing lateinit to scanListenerLS property declaration
- Extract Document.getSafeOffset() to Utils.kt as shared utility
- Use getSafeOffset in showDocument file navigation to prevent
IndexOutOfBoundsException from out-of-range character offsets
- Replace private getSafeOffset copy in Types.kt with shared utility
- Remove duplicated isHtmlTreeViewEnabled() check in onShowIssueDetail
listener, delegate to selectNodeAndDisplayDescription which handles it
* fix: dispose JCEF browsers in SuggestionDescriptionPanel and fix JS callback leak
- Make SuggestionDescriptionPanel implement Disposable to properly clean up
JCEF browser processes when panels are replaced
- Add clearDescriptionPanel() helper that disposes old Disposable children
before removeAll(), preventing cumulative native process/memory leaks
- Send error callback to JS when commands are rejected (not in allowlist)
or when execution throws, preventing __ideCallbacks__ memory leaks
- Add tests for Disposable behavior and error callback invocation
* fix: validate callbackId before allowlist check and downgrade log levels
- Move SAFE_CALLBACK_ID validation before allowlist rejection to prevent
unsafe callbackIds from reaching callbackExecutor (JS injection risk)
- Downgrade verbose logger.info to debug in onShowIssueDetail handler
* fix: address PR review bot findings and downgrade verbose logging
- Fix JCEF fallback: check htmlTreePanel != null instead of registry flag
in scheduleDebouncedTreeRefresh so native tree refreshes when JCEF is
unsupported even if HTML tree flag is enabled
- Fix async race: add isDisposed flag to SuggestionDescriptionPanel to
prevent orphaned JCEF browsers when panel is disposed during LS call
- Fix hash collision: use string equality instead of hashCode() for HTML
deduplication in HtmlTreePanel
- Downgrade routine logger.info to debug in SnykLanguageClient (scan
completed, force-saved settings, logTrace, MessageType.Log, showDocument)
* fix: show native toolbar actions when JCEF is unsupported
Guard toolbar action hiding in SnykToolWindow with JBCefApp.isSupported()
check so native ViewActions and expand/collapse actions remain visible
when JCEF is unavailable even if the HTML tree registry flag is enabled.
This matches the fallback logic in SnykToolWindowPanel.
* fix: adjust log levels per PR review comments
- L468: info→debug for missing issueID (routine condition)
- L500: warn→error for unsupported URI scheme (error condition)
* fix: optimize onShowIssueDetail performance and dispose panel on destroy
- Guard debug log evaluation with isDebugEnabled to avoid expensive
flatten/map operations when debug logging is disabled
- Use firstNotNullOfOrNull instead of flatten().firstOrNull() to avoid
creating intermediate lists for issue lookup
- Use sequence + sumOf for debug stats to reduce allocations
- Call clearDescriptionPanel() in dispose() to ensure last active
SuggestionDescriptionPanel JCEF browser is released on shutdown
* fix: delegate http/https URIs to browser and cap getSafeOffset at line end
- showDocument now opens http/https URIs via BrowserUtil.browse() instead
of returning false, enabling LS-triggered 'Open in Browser' actions
- getSafeOffset caps offset at line end (getLineEndOffset) instead of
document end (textLength) to prevent bleeding into next line when
character index exceeds actual line length
- Add test for https browser delegation, update existing tests
* fix: delegate unsupported URI schemes to super.showDocument
Instead of returning false for unknown schemes, delegate to the
LSP4j default handler via super.showDocument(param) to preserve
platform-level behavior.
* fix: update show document handler
* feat(secrets): add Snyk Secrets product type with annotations, caching, and tests
- Add SECRETS to ProductType enum with tree name and description
- Add Secrets to LsProduct enum with short/long name mappings
- Create SnykSecretsAnnotator extending SnykAnnotator for editor annotations
- Add secrets icons (secrets.svg, secrets_disabled.svg)
- Add currentSecretsResultsLS and currentSecretsError to SnykCachedResults
- Handle LsProduct.Secrets in SnykLanguageClient diagnostics pipeline
- Add SECRETS branches to getSnykCachedResultsForProduct, CodeActionIntention
- Fix ScanIssue.title() to handle SECRETS type (was TODO() crash)
- Fix CodeActionIntention.getIcon() for SECRETS (was TODO() crash)
- Fix scanningStarted to clear currentSecretsError on new scan
- Move annotation refresh debouncing from SnykToolWindowPanel to SnykCachedResults
- Rename IAC treeName from Configuration to Snyk Infrastructure as Code
- Add isSnykSecretsRunning utility function
- Add secretsScanEnabled setting to SnykApplicationSettingsStateService
- Add scanningSecretsFinished to SnykScanListener
- Add tests for ScanIssue SECRETS methods (title, issueNaming, priority, etc.)
- Add tests for SnykCachedResults secrets cache and LsProduct mapping
* chore: update secrets icons
* fix(secrets): add secretsEnabled settings check in SnykSecretsAnnotator
Suppress secrets annotations when the user disables the product in
settings, consistent with SnykOSSAnnotator and SnykIaCAnnotator.
* fix(lsp): prevent NPE on null baseBranch in FolderConfig.copy
perf(core): optimize memory consumption and execution time during high volume LSP message processing
- Lazily evaluate SnykFile.relativePath to reduce coroutine allocations
- Use O(1) map lookup for issue fetching in SnykAnnotator instead of O(N) iteration
- Lazily evaluate Document textRange and VirtualFile in ScanIssue to prevent massive memory allocations for large projects
* Revert "fix(lsp): prevent NPE on null baseBranch in FolderConfig.copy"
This reverts commit b01aded.
* fix: ignore action in integrity check notification
* test(jcef): replace MockK verify(timeout) with Awaitility for reliable async verification [IDE-1749]
MockK's verify(timeout=...) has a known race condition on Windows that causes
NoSuchElementException (List is empty) when the internal call list is polled
concurrently. Replaced both occurrences in TreeViewBridgeHandlerTest with
await().atMost(...).untilAsserted { verify {...} } which is thread-safe.
* fix(settings): use ParametersListUtil.parse for additionalParameters tokenization [IDE-1126]
Replace naive split(" ", lineSeparator) with ParametersListUtil.parse() which
correctly handles double-quoted arguments containing spaces, preventing them from
being split into multiple tokens.
Note: single-quoted arguments are not supported by ParametersListUtil; users
should use double quotes for arguments containing spaces.
Add table tests covering: simple flags, single-quoted (split, unsupported),
double-quoted (preserved), newline-separated, empty input, and the real-world
complex CLI invocation from the bug report.
* chore: remove smells
* feat: register secrets annotator
* fix: check file version for product int when clearing cache
* chore: cleanup warnings
* fix(cache): atomically drain pendingAnnotationRefreshFiles to prevent silent file loss [IDE-1749]
Replace non-atomic toList().also { clear() } with removeIf-based drain in
flushPendingAnnotationRefreshes. A file added between toList() and clear() was
silently dropped and would only be re-queued on the next diagnostic update.
With ConcurrentHashMap.newKeySet().removeIf, each element is removed and
collected atomically per-element. Any file added after the drain has passed its
bucket stays in the set and is processed on the next flush cycle — never lost.
Extract the drain into internal drainPendingAnnotationRefreshFiles() for
testability. Add table tests covering empty, single, multiple, and pre-drain
concurrent-add scenarios.
* chore: cleanup smells
* refactor(settings): remove dead code calls to isScanTypeChanged and isSeverityEnablementChanged [IDE-1749]
These calls had no effect after their return values were unassigned — the
methods have no side effects, so calling them without using the result
is pure dead code.
* chore: add isSecretsRunning to isScanRunning1 parent 1862e38 commit c54806f
File tree
24 files changed
+722
-189
lines changed- src
- main
- kotlin
- icons
- io/snyk/plugin
- events
- services
- download
- settings
- ui/toolwindow
- snyk/common
- annotator
- lsp
- settings
- resources
- META-INF
- icons
- test/kotlin
- io/snyk/plugin
- settings
- ui
- jcef
- toolwindow
- snyk/common
- lsp
24 files changed
+722
-189
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| 92 | + | |
92 | 93 | | |
93 | 94 | | |
94 | 95 | | |
| |||
223 | 224 | | |
224 | 225 | | |
225 | 226 | | |
| 227 | + | |
| 228 | + | |
226 | 229 | | |
227 | 230 | | |
228 | 231 | | |
229 | | - | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
230 | 236 | | |
231 | 237 | | |
232 | 238 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
| 25 | + | |
24 | 26 | | |
25 | 27 | | |
Lines changed: 16 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| 32 | + | |
| 33 | + | |
32 | 34 | | |
33 | | - | |
34 | 35 | | |
35 | 36 | | |
36 | 37 | | |
37 | | - | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
39 | 41 | | |
| 42 | + | |
40 | 43 | | |
41 | 44 | | |
42 | 45 | | |
| |||
50 | 53 | | |
51 | 54 | | |
52 | 55 | | |
| 56 | + | |
53 | 57 | | |
54 | 58 | | |
55 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
56 | 63 | | |
57 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
58 | 68 | | |
59 | 69 | | |
60 | 70 | | |
61 | 71 | | |
| 72 | + | |
| 73 | + | |
62 | 74 | | |
| 75 | + | |
| 76 | + | |
63 | 77 | | |
64 | 78 | | |
65 | 79 | | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | 80 | | |
71 | 81 | | |
72 | 82 | | |
| |||
Lines changed: 13 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
| 3 | + | |
5 | 4 | | |
6 | 5 | | |
7 | 6 | | |
| |||
54 | 53 | | |
55 | 54 | | |
56 | 55 | | |
| 56 | + | |
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
| 127 | + | |
127 | 128 | | |
128 | 129 | | |
129 | 130 | | |
| |||
207 | 208 | | |
208 | 209 | | |
209 | 210 | | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
| 211 | + | |
| 212 | + | |
214 | 213 | | |
215 | 214 | | |
216 | 215 | | |
217 | | - | |
218 | | - | |
219 | | - | |
220 | | - | |
221 | | - | |
222 | | - | |
223 | | - | |
224 | | - | |
225 | | - | |
226 | | - | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
227 | 224 | | |
228 | 225 | | |
229 | 226 | | |
| |||
Lines changed: 3 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
111 | 112 | | |
112 | 113 | | |
113 | 114 | | |
114 | | - | |
115 | | - | |
116 | 115 | | |
117 | 116 | | |
118 | 117 | | |
| |||
235 | 234 | | |
236 | 235 | | |
237 | 236 | | |
238 | | - | |
| 237 | + | |
239 | 238 | | |
240 | 239 | | |
241 | 240 | | |
| |||
272 | 271 | | |
273 | 272 | | |
274 | 273 | | |
275 | | - | |
| 274 | + | |
276 | 275 | | |
277 | 276 | | |
278 | 277 | | |
| |||
287 | 286 | | |
288 | 287 | | |
289 | 288 | | |
290 | | - | |
291 | 289 | | |
292 | 290 | | |
293 | 291 | | |
| |||
Lines changed: 2 additions & 78 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
5 | 3 | | |
6 | 4 | | |
7 | 5 | | |
| |||
12 | 10 | | |
13 | 11 | | |
14 | 12 | | |
15 | | - | |
16 | 13 | | |
17 | | - | |
18 | 14 | | |
19 | 15 | | |
20 | 16 | | |
| |||
128 | 124 | | |
129 | 125 | | |
130 | 126 | | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | 127 | | |
137 | 128 | | |
138 | 129 | | |
| |||
148 | 139 | | |
149 | 140 | | |
150 | 141 | | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | 142 | | |
155 | 143 | | |
156 | 144 | | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | 145 | | |
161 | 146 | | |
162 | 147 | | |
| |||
236 | 221 | | |
237 | 222 | | |
238 | 223 | | |
239 | | - | |
240 | | - | |
241 | | - | |
242 | | - | |
243 | | - | |
244 | | - | |
245 | | - | |
246 | | - | |
247 | | - | |
248 | | - | |
249 | 224 | | |
250 | 225 | | |
251 | 226 | | |
| |||
509 | 484 | | |
510 | 485 | | |
511 | 486 | | |
512 | | - | |
513 | | - | |
514 | | - | |
515 | | - | |
516 | | - | |
517 | | - | |
518 | | - | |
519 | | - | |
520 | | - | |
521 | | - | |
522 | | - | |
523 | | - | |
524 | | - | |
525 | | - | |
526 | | - | |
527 | | - | |
528 | | - | |
529 | | - | |
530 | | - | |
531 | | - | |
532 | | - | |
533 | | - | |
534 | | - | |
535 | | - | |
536 | | - | |
537 | | - | |
538 | | - | |
539 | | - | |
540 | | - | |
541 | | - | |
542 | | - | |
543 | | - | |
544 | | - | |
545 | | - | |
546 | | - | |
547 | | - | |
548 | | - | |
549 | | - | |
550 | | - | |
551 | | - | |
552 | | - | |
553 | | - | |
554 | | - | |
555 | | - | |
556 | | - | |
557 | | - | |
558 | | - | |
559 | | - | |
560 | | - | |
561 | | - | |
562 | | - | |
563 | | - | |
564 | 487 | | |
565 | 488 | | |
566 | 489 | | |
567 | 490 | | |
568 | 491 | | |
569 | 492 | | |
570 | 493 | | |
571 | | - | |
| 494 | + | |
572 | 495 | | |
573 | 496 | | |
574 | 497 | | |
| |||
615 | 538 | | |
616 | 539 | | |
617 | 540 | | |
| 541 | + | |
618 | 542 | | |
619 | 543 | | |
620 | 544 | | |
| |||
Lines changed: 9 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
94 | 99 | | |
95 | 100 | | |
96 | 101 | | |
| |||
110 | 115 | | |
111 | 116 | | |
112 | 117 | | |
113 | | - | |
114 | 118 | | |
115 | 119 | | |
116 | 120 | | |
| |||
125 | 129 | | |
126 | 130 | | |
127 | 131 | | |
128 | | - | |
129 | 132 | | |
130 | 133 | | |
131 | 134 | | |
| |||
140 | 143 | | |
141 | 144 | | |
142 | 145 | | |
143 | | - | |
144 | 146 | | |
145 | 147 | | |
146 | 148 | | |
| |||
156 | 158 | | |
157 | 159 | | |
158 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
159 | 164 | | |
160 | 165 | | |
161 | 166 | | |
| |||
172 | 177 | | |
173 | 178 | | |
174 | 179 | | |
175 | | - | |
| 180 | + | |
176 | 181 | | |
177 | 182 | | |
178 | 183 | | |
| |||
0 commit comments