dsh-diff-approval 0.22.2 → 0.23.1
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.zh.md +1 -1
- package/lib/client.js +1596 -231
- package/lib/index.js +119 -2
- package/lib/types/client/PendingPanel.d.ts +1 -1
- package/lib/types/client/chat-bridge.d.ts +70 -0
- package/lib/types/client/discussion.d.ts +199 -0
- package/lib/types/client/locales.d.ts +34 -0
- package/lib/types/client/scroll-follow.d.ts +44 -0
- package/lib/types/client/settings.d.ts +13 -0
- package/lib/types/client/slots.d.ts +16 -0
- package/lib/types/comment-skill.d.ts +39 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/types.d.ts +6 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -21,7 +21,7 @@ window.__ModuleLoader__.load({
|
|
|
21
21
|
let react_dom = require("react-dom");
|
|
22
22
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
23
23
|
//#region \0dsh-css:/home/runner/work/dsh-diff-approval/dsh-diff-approval/src/client/PendingPanel.module.css.mjs
|
|
24
|
-
const css = ".F1KBNa_panelFailure{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;gap:8px;padding:8px 10px;font-size:12px;line-height:16px;display:flex}.F1KBNa_panelFailureText{min-width:0}.F1KBNa_panelFailureRetry{border:1px solid var(--dsw-alias-border-l2);color:inherit;font:inherit;cursor:pointer;background:0 0;border-radius:6px;flex:none;margin-left:auto;padding:2px 8px}.F1KBNa_panelFailureRetry:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_layer{box-sizing:border-box;flex:none;align-items:center;width:calc(100% + 4px);height:42px;margin:4px -2px;display:flex;position:relative}.F1KBNa_headerEntry{box-sizing:border-box;width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:28px;flex:none;justify-content:center;align-items:center;padding:6px;display:inline-flex;position:relative}.F1KBNa_headerEntry:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_headerEntry[data-active]{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}.F1KBNa_headerEntry:disabled{color:var(--dsw-alias-label-tertiary);cursor:default;background:0 0}.F1KBNa_headerEntryCount{box-sizing:border-box;background:var(--dsw-alias-button-primary-fill);min-width:14px;height:14px;color:var(--dsw-alias-label-primary-foreground);text-align:center;font-variant-numeric:tabular-nums;pointer-events:none;border-radius:7px;padding:0 3px;font-size:10px;line-height:14px;position:absolute;top:-1px;right:-1px}.F1KBNa_headerEntry svg{display:block}.F1KBNa_footerButtons{align-items:center;width:100%;display:flex}.F1KBNa_badge{box-sizing:border-box;width:100%;height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.F1KBNa_badge:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_badge[data-active]{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_badge:disabled{color:var(--dsw-alias-label-tertiary);cursor:default;background:0 0}.F1KBNa_badgeLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.F1KBNa_badgeCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto;font-size:12px;line-height:16px}.F1KBNa_layer.F1KBNa_rail{width:36px;height:36px;margin:8px 0 10px}.F1KBNa_rail .F1KBNa_badge{border-radius:50%;justify-content:center;gap:0;width:36px;height:36px;padding:0}.F1KBNa_rail .F1KBNa_badgeLabel{display:none}.F1KBNa_rail .F1KBNa_badgeCount{box-sizing:border-box;background:var(--dsw-alias-state-business-primary);min-width:18px;height:18px;color:var(--dsw-alias-label-primary-foreground);font-variant-numeric:tabular-nums;border-radius:9px;justify-content:center;align-items:center;padding:0 4px;font-size:11px;line-height:18px;display:flex;position:absolute;top:-3px;right:-7px}.F1KBNa_coverBackdrop{z-index:29;background:var(--dsw-specific-sidebar-fill);position:fixed;inset:0}.F1KBNa_panel{z-index:30;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:none;box-shadow:var(--dsw-shadow-lv2);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex-direction:column;display:flex;position:fixed;inset:8px 8px 128px;overflow:hidden}.F1KBNa_panelDocked{width:100%;max-width:none;height:100%;box-shadow:none;border:none;border-radius:0;position:static;inset:auto}.F1KBNa_dockHost{flex-direction:column;min-height:0;display:flex;position:absolute;inset:0}.F1KBNa_header{box-sizing:border-box;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:10px 12px;display:flex}.F1KBNa_headerActions{align-items:center;gap:2px;display:flex}.F1KBNa_settingsPage{padding:8px 12px}.F1KBNa_settingsGroup{border-bottom:1px solid var(--dsw-alias-border-l2)}.F1KBNa_settingsGroupHeader{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:8px;padding:16px 0;display:flex}.F1KBNa_settingsGroupText{text-align:left;flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.F1KBNa_settingsGroupTitle{font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsGroupDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.F1KBNa_settingsGroupChevron{margin-left:auto;transition:transform .15s}.F1KBNa_settingsGroup[data-open] .F1KBNa_settingsGroupChevron{transform:rotate(180deg)}.F1KBNa_settingsGroup[data-open] .F1KBNa_settingsGroupHeader{border-bottom:1px solid var(--dsw-alias-border-l2)}.F1KBNa_settingsGroupBody{flex-direction:column;display:flex}.F1KBNa_settingsGroupBody .F1KBNa_settingsRow{padding-left:16px}.F1KBNa_settingsGroupBody .F1KBNa_settingsRow:last-child,.F1KBNa_settingsPage>.F1KBNa_settingsRow:last-child{border-bottom:none}.F1KBNa_settingsRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.F1KBNa_settingsRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.F1KBNa_settingsRowTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsRowDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.F1KBNa_settingsSelector{background:var(--dsw-alias-bg-module-platform);min-width:72px;height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;justify-content:center;align-items:center;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.F1KBNa_settingsSelector:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_settingsSelector[data-recording]{box-shadow:inset 0 0 0 1px var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-secondary)}.F1KBNa_settingsReset{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;margin-left:6px;padding:0;display:inline-flex}.F1KBNa_settingsReset:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_settingsReset:disabled{opacity:.4;cursor:default}.F1KBNa_colorPicker{position:relative}.F1KBNa_colorPickerTrigger{background:var(--dsw-alias-bg-module-platform);width:120px;height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:8px;padding:0 8px;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_colorPickerTrigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_colorSwatch{border:1px solid var(--dsw-alias-border-l2);border-radius:50%;flex:none;width:24px;height:24px}.F1KBNa_colorValue{text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums;flex:1;min-width:0;overflow:hidden}.F1KBNa_colorPickerChevron{flex:none}.F1KBNa_colorBackdrop{z-index:40;position:fixed;inset:0}.F1KBNa_colorPickerPopover{z-index:41;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv2);border-radius:10px;padding:10px;position:absolute;top:calc(100% + 6px);right:0}.F1KBNa_colorPickerPanel{flex-direction:column;gap:8px;display:flex}.F1KBNa_colorPickerInputRow{align-items:center;gap:8px;display:flex}.F1KBNa_colorPickerPreview{border:1px solid var(--dsw-alias-border-l2);border-radius:6px;flex:none;width:22px;height:22px}.F1KBNa_colorPickerInput{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-module-platform);min-width:0;height:30px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;flex:1;padding:0 8px;font-size:12px;line-height:28px}.F1KBNa_colorPickerInput:focus{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-1px}.F1KBNa_colorSv{border:1px solid var(--dsw-alias-border-l1);cursor:crosshair;touch-action:none;border-radius:8px;height:140px;position:relative}.F1KBNa_colorSvCursor{pointer-events:none;border:2px solid #fff;border-radius:50%;width:14px;height:14px;position:absolute;transform:translate(-50%,-50%);box-shadow:0 0 0 1px #00000080}.F1KBNa_colorHue{border:1px solid var(--dsw-alias-border-l1);cursor:pointer;touch-action:none;border-radius:7px;height:14px;position:relative}.F1KBNa_colorHueCursor{pointer-events:none;border:2px solid #fff;border-radius:50%;width:16px;height:16px;position:absolute;top:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 1px #00000080}.F1KBNa_diffPreview{z-index:2;border:1px solid var(--dsw-alias-border-l1);font:var(--dsw-font-markdown-code-block);background:var(--dsw-alias-markdown-code-block);border-radius:8px;margin:16px 0 8px;padding:8px;position:sticky;top:0;overflow:hidden}.F1KBNa_diffPreviewTitle{color:var(--dsw-alias-label-tertiary);margin-bottom:6px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_diffPreviewScroll{height:132px;overflow-y:auto}.F1KBNa_mdPreviewWrap{flex:1;min-width:0;min-height:0;display:flex;position:relative}.F1KBNa_mdPreviewBody{min-width:0;min-height:0;color:var(--dsw-alias-label-primary);flex:1;padding:12px 16px;position:relative;overflow:auto}.F1KBNa_mdPreviewContent{width:100%;min-width:0;margin:0 auto}.F1KBNa_mdPreviewSingle{display:block}.F1KBNa_mdPreviewDouble{display:flex}.F1KBNa_mdPreviewBody .mdBlock{border-radius:4px;margin-bottom:12px;padding:2px 6px}.F1KBNa_mdPreviewBody .mdAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_mdPreviewBody .mdDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_mdPreviewBody .mdWordDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 34%, transparent);border-radius:2px;padding:0 1px}.F1KBNa_mdPreviewBody .mdWordAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 34%, transparent);border-radius:2px;padding:0 1px}.F1KBNa_mdPreviewBody .mdDouble{flex-direction:column;width:100%;min-width:0;display:flex}.F1KBNa_mdPreviewBody .mdDoubleRow{align-items:flex-start;width:100%;min-width:0;display:flex}.F1KBNa_mdPreviewBody .mdDoubleCol{flex:1;min-width:0}.F1KBNa_mdPreviewBody .mdDoubleRule{background:var(--dsw-alias-border-l2);flex:none;align-self:stretch;width:1px;margin:0 12px}.F1KBNa_mdPreviewFallback{font-family:var(--dsw-font-markdown-code-block);color:var(--dsw-alias-label-tertiary);padding:12px 16px;font-size:12px;line-height:18px}.F1KBNa_mdPreviewBody{word-break:break-word;font-size:13px;line-height:20px}.F1KBNa_mdPreviewBody>:first-child{margin-top:0}.F1KBNa_mdPreviewBody>:last-child{margin-bottom:0}.F1KBNa_mdPreviewBody h1,.F1KBNa_mdPreviewBody h2,.F1KBNa_mdPreviewBody h3,.F1KBNa_mdPreviewBody h4,.F1KBNa_mdPreviewBody h5,.F1KBNa_mdPreviewBody h6{margin:16px 0 8px;font-weight:600;line-height:1.3}.F1KBNa_mdPreviewBody h1{font-size:22px}.F1KBNa_mdPreviewBody h2{font-size:19px}.F1KBNa_mdPreviewBody h3{font-size:16px}.F1KBNa_mdPreviewBody h4{font-size:15px}.F1KBNa_mdPreviewBody h5{font-size:14px}.F1KBNa_mdPreviewBody h6{font-size:13px}.F1KBNa_mdPreviewBody p{margin:8px 0}.F1KBNa_mdPreviewBody ul,.F1KBNa_mdPreviewBody ol{margin:8px 0;padding-left:22px}.F1KBNa_mdPreviewBody li{margin:2px 0}.F1KBNa_mdPreviewBody a{color:var(--dsw-alias-state-business-primary);text-decoration:none}.F1KBNa_mdPreviewBody a:hover{text-decoration:underline}.F1KBNa_mdPreviewBody code{font-family:var(--dsw-font-markdown-code-block);background:#9e9e9e40;border-radius:4px;padding:1px 5px;font-size:12.5px}.F1KBNa_mdPreviewBody pre{border:1px solid var(--dsw-alias-border-l1);font-family:var(--dsw-font-markdown-code-block);background:#9e9e9e40;border-radius:8px;margin:8px 0;padding:10px 12px;font-size:12.5px;line-height:18px;overflow:auto}.F1KBNa_mdPreviewBody pre code{background:0 0;padding:0}.F1KBNa_mdPreviewBody blockquote{border-left:3px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);margin:8px 0;padding:0 12px}.F1KBNa_mdPreviewBody hr{background:var(--dsw-alias-border-l1);border:none;height:1px;margin:16px 0}.F1KBNa_mdPreviewBody table{border-collapse:collapse;margin:8px 0}.F1KBNa_mdPreviewBody th,.F1KBNa_mdPreviewBody td{border:1px solid var(--dsw-alias-border-l1);padding:4px 10px}.F1KBNa_mdPreviewBody img{max-width:100%}.F1KBNa_mdPreviewBody .mdImageFallback{border:1px dashed var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-markdown-code-block) 45%, transparent);width:100%;min-height:120px;color:var(--dsw-alias-label-secondary);font-family:var(--dsw-font-markdown-code-block);text-align:center;white-space:pre-wrap;word-break:break-all;border-radius:4px;justify-content:center;align-items:center;margin:0 auto;padding:8px 12px;font-size:12px;line-height:16px;display:flex}.F1KBNa_toggle{border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:18px;flex:none;width:60px;height:36px;padding:0;position:relative}.F1KBNa_toggle:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_toggle:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.F1KBNa_toggleOn{border-color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-state-business-primary)}.F1KBNa_toggleOn:hover{background:var(--dsw-alias-state-business-primary)}.F1KBNa_toggleThumb{background:var(--dsw-alias-label-primary);border-radius:50%;width:28px;height:28px;transition:left .12s;position:absolute;top:3px;left:3px}.F1KBNa_toggleOn .F1KBNa_toggleThumb{background:#fff;left:27px}.F1KBNa_stepper{align-items:center;gap:6px;display:inline-flex}.F1KBNa_stepperButton{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-module-platform);width:32px;height:32px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:8px;padding:0;position:relative}.F1KBNa_stepperButton:before,.F1KBNa_stepperButton:after{content:\"\";background:currentColor;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.F1KBNa_stepperButton:before{width:10px;height:1px}.F1KBNa_stepperButton:after{width:1px;height:10px;display:none}.F1KBNa_stepperButtonUp:after{display:block}.F1KBNa_stepperButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_stepperButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_stepperValue{text-align:center;min-width:2ch;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:14px;line-height:22px}.F1KBNa_states{flex-direction:column;flex:1;min-height:0;padding:4px 12px 12px;display:flex;overflow-y:auto}.F1KBNa_split{flex:1;align-items:stretch;min-height:0;display:flex;position:relative}.F1KBNa_fileListKnob{z-index:39;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);opacity:.45;width:28px;height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;box-shadow:var(--dsw-shadow-lv2);border-radius:8px;justify-content:center;align-items:center;padding:0;transition:opacity .12s;display:inline-flex;position:absolute}.F1KBNa_fileListKnob:hover,.F1KBNa_fileListKnob:focus-visible{opacity:1;background-color:var(--dsw-alias-bg-base);background-image:linear-gradient(var(--dsw-alias-interactive-bg-hover), var(--dsw-alias-interactive-bg-hover))}.F1KBNa_fileListFloat{z-index:40;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv2);transform-origin:0 0;border-radius:12px;flex-direction:column;padding:6px 8px 10px;animation:.14s ease-out F1KBNa_fileListGrow;display:flex;position:absolute;overflow:hidden}@keyframes F1KBNa_fileListGrow{0%{opacity:0;transform:scale(.92)}to{opacity:1;transform:scale(1)}}@media (prefers-reduced-motion:reduce){.F1KBNa_fileListFloat{animation:none}}.F1KBNa_fileList{box-sizing:border-box;border-right:1px solid var(--dsw-alias-border-l2);flex-direction:column;flex:none;width:240px;min-height:0;padding:4px 8px 12px;display:flex}.F1KBNa_listScroll{flex:1;min-height:0;overflow-y:scroll}.F1KBNa_bulkActions{flex:none;gap:6px;padding:8px 8px 0 0;display:flex}.F1KBNa_bulkActions .F1KBNa_action{text-align:center;flex:1}.F1KBNa_resizeHandle{cursor:col-resize;touch-action:none;background:0 0;flex:none;width:5px;margin:0 -2px}.F1KBNa_resizeHandle:hover{background:var(--dsw-alias-border-l2)}.F1KBNa_floatResizeHandle{z-index:41;cursor:col-resize;-webkit-user-select:none;user-select:none;touch-action:none;background:0 0;border-radius:4px;position:absolute}.F1KBNa_floatResizeHandle:hover{background-color:var(--dsw-alias-bg-base);background-image:linear-gradient(var(--dsw-alias-border-l2), var(--dsw-alias-border-l2))}.F1KBNa_detail{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.F1KBNa_detailEmpty{color:var(--dsw-alias-label-tertiary);text-align:center;flex:1;justify-content:center;align-items:center;margin:0;padding:24px;font-size:12px;line-height:18px;display:flex}.F1KBNa_confirmBackdrop{z-index:55;background:color-mix(in srgb, var(--dsw-alias-bg-base) 55%, transparent);justify-content:center;align-items:center;padding:24px;display:flex;position:absolute;inset:0}.F1KBNa_confirmCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);max-width:340px;box-shadow:var(--dsw-shadow-lv3);border-radius:12px;flex-direction:column;gap:12px;padding:16px;display:flex}.F1KBNa_confirmText{font:var(--dsw-font-caption);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0;line-height:1.5}.F1KBNa_confirmActions{flex:none;justify-content:flex-end;align-items:center;gap:8px;display:flex}.F1KBNa_pickerCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:420px;max-width:100%;height:70%;max-height:100%;box-shadow:var(--dsw-shadow-lv3);border-radius:12px;flex-direction:column;gap:8px;padding:14px 16px 16px;display:flex;position:relative;overflow:hidden}.F1KBNa_pickerTitle{color:var(--dsw-alias-label-primary);flex:none;font-size:13px;font-weight:500;line-height:20px}.F1KBNa_pickerClose{width:22px;height:22px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:6px;justify-content:center;align-items:center;padding:0;display:inline-flex;position:absolute;top:10px;right:10px}.F1KBNa_pickerClose:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_pickerForm{flex:none;gap:8px;display:flex}.F1KBNa_pickerInput{border:1px solid var(--dsw-alias-border-l1);min-width:0;color:var(--dsw-alias-label-primary);background:0 0;border-radius:8px;flex:auto;padding:3px 8px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_pickerInput:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}.F1KBNa_tree{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex:auto;min-height:0;padding:4px 2px 4px 4px;overflow:auto scroll}.F1KBNa_treeRow{border-radius:6px;align-items:center;gap:2px;padding-right:4px;display:flex}.F1KBNa_treeRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_treeRow[data-selected]{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 18%, transparent)}.F1KBNa_treeCaret{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_treeCaret:hover{color:var(--dsw-alias-label-primary)}.F1KBNa_treeName{min-width:0;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:0;border-radius:6px;flex:auto;align-items:center;gap:6px;padding:2px 4px;font-family:inherit;font-size:12px;line-height:18px;display:flex}.F1KBNa_treeName:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_treeNote{color:var(--dsw-alias-label-tertiary);margin:2px 0;font-size:12px;line-height:18px}.F1KBNa_pickerIcon{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:inline-flex}.F1KBNa_pickerName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.F1KBNa_pickerNote{color:var(--dsw-alias-label-tertiary);flex:none;margin:0;font-size:12px;line-height:18px}.F1KBNa_pickerCheck{color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:6px;margin-right:auto;font-size:12px;line-height:18px;display:flex}.F1KBNa_title{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}.F1KBNa_note,.F1KBNa_readError,.F1KBNa_hint{color:var(--dsw-alias-label-tertiary);margin:4px 0;font-size:12px;line-height:18px}.F1KBNa_noteCentered{text-align:center;margin:auto}.F1KBNa_emptyState{flex-direction:column;align-items:center;gap:10px;margin:auto;display:flex}.F1KBNa_importButton{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:5px 14px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_importButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_importButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_importNote{color:var(--dsw-alias-label-tertiary);text-align:center;margin:0;font-size:12px;line-height:18px}.F1KBNa_readError{color:var(--dsw-alias-state-error-primary)}.F1KBNa_group{color:var(--dsw-alias-label-tertiary);margin:8px 0 4px;font-size:12px;font-weight:500;line-height:16px}.F1KBNa_groupHead{align-items:center;gap:4px;margin:8px 0 4px;padding-right:8px;display:flex}.F1KBNa_action.F1KBNa_addButton{box-sizing:border-box;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;min-height:0;padding:0;display:inline-flex}.F1KBNa_groupHead>.F1KBNa_group{margin:0}.F1KBNa_emptyActions{flex-wrap:wrap;justify-content:center;gap:8px;display:flex}.F1KBNa_rows{margin:0;padding:0;list-style:none}.F1KBNa_row{border:1px solid #0000;border-radius:10px;margin:2px 0}.F1KBNa_rowHead{width:100%;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;align-items:baseline;gap:8px;padding:6px 8px;display:flex}.F1KBNa_rowHead:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_rowHead[data-selected]{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_rowPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-markdown-code-block);overflow:hidden}.F1KBNa_kindTag{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_kindHint{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:16px}.F1KBNa_divergedHint,.F1KBNa_missingHint{border-bottom:1px solid var(--dsw-alias-border-l2);margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missing{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary));white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_rowFailed{border:1px solid var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_actionError{border-bottom:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missingHint{color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary))}.F1KBNa_rowMeta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;gap:6px;margin-left:auto;font-size:12px;line-height:16px;display:inline-flex}.F1KBNa_addCount{color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 60%, var(--dsw-alias-label-primary))}.F1KBNa_delCount{color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 60%, var(--dsw-alias-label-primary))}.F1KBNa_diff{background:var(--dsw-alias-markdown-code-block);flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_diffHeader{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffPath{white-space:nowrap;scrollbar-width:none;min-width:0;color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code-block);-webkit-user-select:text;user-select:text;flex:1;font-size:12px;line-height:18px;overflow:auto hidden}.F1KBNa_diffPath::-webkit-scrollbar{display:none}.F1KBNa_diffActions{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffStats{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:16px}.F1KBNa_flexSpacer{flex:1}.F1KBNa_divider{background:var(--dsw-alias-border-l1);align-self:stretch;width:1px;margin:2px 0}.F1KBNa_action{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_action:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_actionPrimary{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_actionPrimary:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_actionPrimary:disabled{background:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:.55}.F1KBNa_actionQuietDisabled:disabled{cursor:pointer;color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l1);background:0 0}.F1KBNa_actionPrimary.F1KBNa_actionQuietDisabled:disabled{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:1}.F1KBNa_iconAction{justify-content:center;align-items:center;min-height:25px;padding:4px 6px;display:inline-flex}.F1KBNa_close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expand{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_expand:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expandExpanded svg{transform:rotate(180deg)}.F1KBNa_diffBodyWrap{flex:1;min-height:0;display:flex;position:relative}.F1KBNa_diffBody{min-width:0;font:var(--dsw-font-markdown-code-block);-webkit-text-size-adjust:100%;text-size-adjust:100%;cursor:text;outline:none;flex:1;padding:0;position:relative;overflow:auto}.F1KBNa_diffBody::-webkit-scrollbar,.F1KBNa_diffBody::-webkit-scrollbar-track,.F1KBNa_diffBody::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_blockActions{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);z-index:2;border-radius:10px;align-items:center;gap:9px;padding:5px;display:flex;position:absolute;right:8px}.F1KBNa_blockPosition{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;margin-top:1px;margin-left:7px;font-size:12px;line-height:16px}.F1KBNa_searchBar{z-index:3;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);border-radius:10px;align-items:center;gap:4px;padding:4px;display:flex;position:absolute;top:8px;right:8px}.F1KBNa_searchInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);width:150px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:3px 8px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_searchInput:focus{border-color:var(--dsw-alias-state-business-primary)}.F1KBNa_searchCount{text-align:center;min-width:34px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:16px}.F1KBNa_searchToggle{border:1px solid var(--dsw-alias-border-l1);min-height:25px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;justify-content:center;align-items:center;padding:4px 6px;display:inline-flex}.F1KBNa_searchToggle:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_searchToggleOn{border-color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-state-business-primary)}.F1KBNa_searchMatch{color:inherit;background-color:#facc1542;border-radius:2px}.F1KBNa_searchMatchCurrent{color:inherit;background-color:#facc1599;border-radius:2px}.F1KBNa_blockFlash{z-index:1;box-sizing:border-box;border:2px solid var(--dsw-alias-state-business-primary);pointer-events:none;border-radius:4px;animation:1s ease-out forwards F1KBNa_diffFlashFade;position:absolute;left:0;right:0}.F1KBNa_blockFlashShake{animation:.7s ease-out forwards F1KBNa_diffFlashShake}@keyframes F1KBNa_diffFlashFade{0%{opacity:1}to{opacity:0}}@keyframes F1KBNa_diffFlashShake{0%{opacity:1;transform:translateY(0)}10%{transform:translateY(1px)}20%{transform:translateY(-1px)}30%{transform:translateY(1px)}40%{transform:translateY(-1px)}50%{transform:translateY(1px)}60%{transform:translateY(-1px)}70%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(0)}}.F1KBNa_overviewRuler{pointer-events:none;opacity:.5;width:4px;position:absolute;top:0;bottom:0;right:0}.F1KBNa_overviewMarker{border-radius:2px;width:100%;min-height:2px;position:absolute;right:0}.F1KBNa_markerDel{background-color:var(--dsw-alias-state-error-primary)}.F1KBNa_markerAdd{background-color:var(--dsw-alias-state-success-primary)}.F1KBNa_lines{border-spacing:0;width:max-content;min-width:100%;font-size:calc(1em * var(--dsh-diff-font-scale,1));display:table}.F1KBNa_line{height:var(--dsh-diff-line-height,22px);line-height:var(--dsh-diff-line-height,22px);-webkit-user-select:none;user-select:none;display:table-row}.F1KBNa_vSpacer{display:table-row}.F1KBNa_gutter{box-sizing:border-box;text-align:right;width:44px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;-webkit-user-select:none;user-select:none;cursor:default;padding-right:10px;display:table-cell}.F1KBNa_code{white-space:pre;-webkit-user-select:text;user-select:text;display:table-cell}.F1KBNa_context{color:var(--dsw-alias-label-primary)}.F1KBNa_del{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_add{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_statusBar{box-sizing:border-box;border-top:1px solid var(--dsw-alias-border-l2);height:34px;color:var(--dsw-alias-label-tertiary);font-family:var(--dsw-font-markdown-code-block);font-variant-numeric:tabular-nums;flex:none;align-items:center;gap:8px;padding:0 8px;font-size:12px;line-height:18px;display:flex}.F1KBNa_statusAction{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_statusAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langSelect{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;flex:none;align-items:center;gap:4px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_langSelect:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langLabel{text-overflow:ellipsis;white-space:nowrap;max-width:140px;overflow:hidden}.F1KBNa_presentationSelect{cursor:pointer;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;gap:2px;padding:0 6px;display:inline-flex}.F1KBNa_presentationSelect:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_chip{justify-content:flex-end;align-items:center;gap:5px;min-width:0;padding-right:14px;display:inline-flex}.F1KBNa_chipLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.F1KBNa_coverHost{align-items:center;display:inline-flex;position:relative}.F1KBNa_coverCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv2);border-radius:12px;align-items:center;gap:4px;padding:6px;display:flex}.F1KBNa_coverPopover{z-index:50;position:absolute;top:calc(100% + 6px);right:0}.F1KBNa_coverNotice{z-index:80;pointer-events:none;animation:1.25s ease-out forwards F1KBNa_coverNoticeFade;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.F1KBNa_coverNoticeCard{gap:4px;padding:6px 8px}@keyframes F1KBNa_coverNoticeFade{0%,78%{opacity:1}to{opacity:0}}.F1KBNa_coverNoticeGlyph{width:44px;height:44px;color:var(--dsw-alias-label-tertiary);border-radius:10px;justify-content:center;align-items:center;display:inline-flex}.F1KBNa_coverNoticeGlyph[data-on]{color:var(--dsw-alias-label-primary)}.F1KBNa_coverNoticeGlyph[data-changed]{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_coverNoticeText{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.F1KBNa_coverButton{width:32px;height:32px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:8px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_coverButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_coverButton[data-on]{color:var(--dsw-alias-label-primary)}.F1KBNa_presentationHost{align-items:center;display:inline-flex}.F1KBNa_chipPresentation{min-width:36px;height:20px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:20px;flex:none;justify-content:center;align-items:center;gap:2px;padding:0 6px;display:inline-flex}.F1KBNa_chipPresentation:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_mirrored{transform:scaleX(-1)}.F1KBNa_notice{z-index:60;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);max-width:360px;box-shadow:var(--dsw-shadow-lv3);border-radius:10px;align-items:flex-start;gap:12px;padding:12px 14px;display:flex;position:fixed;bottom:24px;right:24px}.F1KBNa_noticeText{font:var(--dsw-font-caption);color:var(--dsw-alias-label-primary);flex:1;margin:0;line-height:1.45}.F1KBNa_noticeButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);font:var(--dsw-font-caption);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px}.F1KBNa_noticeButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_wrap .F1KBNa_line{height:auto;min-height:var(--dsh-diff-line-height,22px)}.F1KBNa_subline{height:var(--dsh-diff-line-height,22px);line-height:var(--dsh-diff-line-height,22px);white-space:pre;display:block;overflow:hidden}.F1KBNa_wrapActive{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_wrapActive:hover{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_splitRoot{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.F1KBNa_diffBodySplit{flex:1;min-height:0;overflow-x:hidden}.F1KBNa_splitCols{width:100%;min-width:0;display:flex}.F1KBNa_splitCol{box-sizing:border-box;flex:1 1 0;min-width:0;overflow:hidden}.F1KBNa_splitDivider{background:var(--dsw-alias-border-l2);flex:0 0 1px}.F1KBNa_splitCol .F1KBNa_gutter,.F1KBNa_splitCol .F1KBNa_code{vertical-align:top}.F1KBNa_splitHScrollRow{border-top:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;width:100%;min-width:0;display:flex}.F1KBNa_splitHScroll{min-width:0;height:var(--dsh-scrollbar-width,8px);flex:1 1 0;overflow:auto hidden}.F1KBNa_splitHScroll::-webkit-scrollbar{height:var(--dsh-scrollbar-width,8px)}.F1KBNa_splitHScroll::-webkit-scrollbar-track{cursor:default}.F1KBNa_splitHScroll::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_splitHScrollFill{height:1px}.F1KBNa_splitLdel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_splitLadd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_splitRdel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_splitRadd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_intraDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 26%, transparent);text-decoration:line-through}.F1KBNa_intraAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 24%, transparent)}";
|
|
24
|
+
const css = ".F1KBNa_panelFailure{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;gap:8px;padding:8px 10px;font-size:12px;line-height:16px;display:flex}.F1KBNa_panelFailureText{min-width:0}.F1KBNa_panelFailureRetry{border:1px solid var(--dsw-alias-border-l2);color:inherit;font:inherit;cursor:pointer;background:0 0;border-radius:6px;flex:none;margin-left:auto;padding:2px 8px}.F1KBNa_panelFailureRetry:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_layer{box-sizing:border-box;flex:none;align-items:center;width:calc(100% + 4px);height:42px;margin:4px -2px;display:flex;position:relative}.F1KBNa_headerEntry{box-sizing:border-box;width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:28px;flex:none;justify-content:center;align-items:center;padding:6px;display:inline-flex;position:relative}.F1KBNa_headerEntry:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_headerEntry[data-active]{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}.F1KBNa_headerEntry:disabled{color:var(--dsw-alias-label-tertiary);cursor:default;background:0 0}.F1KBNa_headerEntryCount{box-sizing:border-box;background:var(--dsw-alias-button-primary-fill);min-width:14px;height:14px;color:var(--dsw-alias-label-primary-foreground);text-align:center;font-variant-numeric:tabular-nums;pointer-events:none;border-radius:7px;padding:0 3px;font-size:10px;line-height:14px;position:absolute;top:-1px;right:-1px}.F1KBNa_headerEntry svg{display:block}.F1KBNa_footerButtons{align-items:center;width:100%;display:flex}.F1KBNa_badge{box-sizing:border-box;width:100%;height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.F1KBNa_badge:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_badge[data-active]{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_badge:disabled{color:var(--dsw-alias-label-tertiary);cursor:default;background:0 0}.F1KBNa_badgeLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.F1KBNa_badgeCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto;font-size:12px;line-height:16px}.F1KBNa_layer.F1KBNa_rail{width:36px;height:36px;margin:8px 0 10px}.F1KBNa_rail .F1KBNa_badge{border-radius:50%;justify-content:center;gap:0;width:36px;height:36px;padding:0}.F1KBNa_rail .F1KBNa_badgeLabel{display:none}.F1KBNa_rail .F1KBNa_badgeCount{box-sizing:border-box;background:var(--dsw-alias-state-business-primary);min-width:18px;height:18px;color:var(--dsw-alias-label-primary-foreground);font-variant-numeric:tabular-nums;border-radius:9px;justify-content:center;align-items:center;padding:0 4px;font-size:11px;line-height:18px;display:flex;position:absolute;top:-3px;right:-7px}.F1KBNa_coverBackdrop{z-index:29;background:var(--dsw-specific-sidebar-fill);position:fixed;inset:0}.F1KBNa_panel{z-index:30;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:none;box-shadow:var(--dsw-shadow-lv2);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex-direction:column;display:flex;position:fixed;inset:8px 8px 128px;overflow:hidden}.F1KBNa_panelDocked{width:100%;max-width:none;height:100%;box-shadow:none;border:none;border-radius:0;position:static;inset:auto}.F1KBNa_dockHost{flex-direction:column;min-height:0;display:flex;position:absolute;inset:0}.F1KBNa_header{box-sizing:border-box;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:10px 12px;display:flex}.F1KBNa_headerActions{align-items:center;gap:2px;display:flex}.F1KBNa_settingsPage{padding:8px 12px}.F1KBNa_settingsGroup{border-bottom:1px solid var(--dsw-alias-border-l2)}.F1KBNa_settingsGroupHeader{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:8px;padding:16px 0;display:flex}.F1KBNa_settingsGroupText{text-align:left;flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.F1KBNa_settingsGroupTitle{font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsGroupDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.F1KBNa_settingsGroupChevron{margin-left:auto;transition:transform .15s}.F1KBNa_settingsGroup[data-open] .F1KBNa_settingsGroupChevron{transform:rotate(180deg)}.F1KBNa_settingsGroup[data-open] .F1KBNa_settingsGroupHeader{border-bottom:1px solid var(--dsw-alias-border-l2)}.F1KBNa_settingsGroupBody{flex-direction:column;display:flex}.F1KBNa_settingsGroupBody .F1KBNa_settingsRow{padding-left:16px}.F1KBNa_settingsGroupBody .F1KBNa_settingsRow:last-child,.F1KBNa_settingsPage>.F1KBNa_settingsRow:last-child{border-bottom:none}.F1KBNa_settingsRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.F1KBNa_settingsRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.F1KBNa_settingsRowTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsRowDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.F1KBNa_settingsSelector{background:var(--dsw-alias-bg-module-platform);min-width:72px;height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;justify-content:center;align-items:center;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.F1KBNa_settingsSelector:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_settingsSelector[data-recording]{box-shadow:inset 0 0 0 1px var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-secondary)}.F1KBNa_settingsReset{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;margin-left:6px;padding:0;display:inline-flex}.F1KBNa_settingsReset:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_settingsReset:disabled{opacity:.4;cursor:default}.F1KBNa_colorPicker{position:relative}.F1KBNa_colorPickerTrigger{background:var(--dsw-alias-bg-module-platform);width:120px;height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:8px;padding:0 8px;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_colorPickerTrigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_colorSwatch{border:1px solid var(--dsw-alias-border-l2);border-radius:50%;flex:none;width:24px;height:24px}.F1KBNa_colorValue{text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums;flex:1;min-width:0;overflow:hidden}.F1KBNa_colorPickerChevron{flex:none}.F1KBNa_colorBackdrop{z-index:40;position:fixed;inset:0}.F1KBNa_colorPickerPopover{z-index:41;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv2);border-radius:10px;padding:10px;position:absolute;top:calc(100% + 6px);right:0}.F1KBNa_colorPickerPanel{flex-direction:column;gap:8px;display:flex}.F1KBNa_colorPickerInputRow{align-items:center;gap:8px;display:flex}.F1KBNa_colorPickerPreview{border:1px solid var(--dsw-alias-border-l2);border-radius:6px;flex:none;width:22px;height:22px}.F1KBNa_colorPickerInput{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-module-platform);min-width:0;height:30px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;flex:1;padding:0 8px;font-size:12px;line-height:28px}.F1KBNa_colorPickerInput:focus{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-1px}.F1KBNa_colorSv{border:1px solid var(--dsw-alias-border-l1);cursor:crosshair;touch-action:none;border-radius:8px;height:140px;position:relative}.F1KBNa_colorSvCursor{pointer-events:none;border:2px solid #fff;border-radius:50%;width:14px;height:14px;position:absolute;transform:translate(-50%,-50%);box-shadow:0 0 0 1px #00000080}.F1KBNa_colorHue{border:1px solid var(--dsw-alias-border-l1);cursor:pointer;touch-action:none;border-radius:7px;height:14px;position:relative}.F1KBNa_colorHueCursor{pointer-events:none;border:2px solid #fff;border-radius:50%;width:16px;height:16px;position:absolute;top:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 1px #00000080}.F1KBNa_diffPreview{z-index:2;border:1px solid var(--dsw-alias-border-l1);font:var(--dsw-font-markdown-code-block);background:var(--dsw-alias-markdown-code-block);border-radius:8px;margin:16px 0 8px;padding:8px;position:sticky;top:0;overflow:hidden}.F1KBNa_diffPreviewTitle{color:var(--dsw-alias-label-tertiary);margin-bottom:6px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_diffPreviewScroll{height:132px;overflow-y:auto}.F1KBNa_mdPreviewWrap{isolation:isolate;flex:1;min-width:0;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_mdPreviewBody{min-width:0;min-height:0;color:var(--dsw-alias-label-primary);flex:1;padding:12px 16px;position:relative;overflow:auto}.F1KBNa_mdPreviewContent{width:100%;min-width:0;margin:0 auto}.F1KBNa_mdPreviewSingle{display:block}.F1KBNa_mdPreviewDouble{display:flex}.F1KBNa_mdPreviewBody .mdBlock{border-radius:4px;margin-bottom:12px;padding:2px 6px}.F1KBNa_mdPreviewBody .mdAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_mdPreviewBody .mdDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_mdPreviewBody .mdWordDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 34%, transparent);border-radius:2px;padding:0 1px}.F1KBNa_mdPreviewBody .mdWordAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 34%, transparent);border-radius:2px;padding:0 1px}.F1KBNa_mdPreviewBody .mdDouble{flex-direction:column;width:100%;min-width:0;display:flex}.F1KBNa_mdPreviewBody .mdDoubleRow{align-items:flex-start;width:100%;min-width:0;display:flex}.F1KBNa_mdPreviewBody .mdDoubleCol{flex:1;min-width:0}.F1KBNa_mdPreviewBody .mdDoubleRule{background:var(--dsw-alias-border-l2);flex:none;align-self:stretch;width:1px;margin:0 12px}.F1KBNa_mdPreviewFallback{font-family:var(--dsw-font-markdown-code-block);color:var(--dsw-alias-label-tertiary);padding:12px 16px;font-size:12px;line-height:18px}.F1KBNa_mdPreviewBody{word-break:break-word;font-size:13px;line-height:20px}.F1KBNa_mdPreviewBody>:first-child{margin-top:0}.F1KBNa_mdPreviewBody>:last-child{margin-bottom:0}.F1KBNa_mdPreviewBody h1,.F1KBNa_mdPreviewBody h2,.F1KBNa_mdPreviewBody h3,.F1KBNa_mdPreviewBody h4,.F1KBNa_mdPreviewBody h5,.F1KBNa_mdPreviewBody h6{margin:16px 0 8px;font-weight:600;line-height:1.3}.F1KBNa_mdPreviewBody h1{font-size:22px}.F1KBNa_mdPreviewBody h2{font-size:19px}.F1KBNa_mdPreviewBody h3{font-size:16px}.F1KBNa_mdPreviewBody h4{font-size:15px}.F1KBNa_mdPreviewBody h5{font-size:14px}.F1KBNa_mdPreviewBody h6{font-size:13px}.F1KBNa_mdPreviewBody p{margin:8px 0}.F1KBNa_mdPreviewBody ul,.F1KBNa_mdPreviewBody ol{margin:8px 0;padding-left:22px}.F1KBNa_mdPreviewBody li{margin:2px 0}.F1KBNa_mdPreviewBody a{color:var(--dsw-alias-state-business-primary);text-decoration:none}.F1KBNa_mdPreviewBody a:hover{text-decoration:underline}.F1KBNa_mdPreviewBody code{font-family:var(--dsw-font-markdown-code-block);background:#9e9e9e40;border-radius:4px;padding:1px 5px;font-size:12.5px}.F1KBNa_mdPreviewBody pre{border:1px solid var(--dsw-alias-border-l1);font-family:var(--dsw-font-markdown-code-block);background:#9e9e9e40;border-radius:8px;margin:8px 0;padding:10px 12px;font-size:12.5px;line-height:18px;overflow:auto}.F1KBNa_mdPreviewBody pre code{background:0 0;padding:0}.F1KBNa_mdPreviewBody blockquote{border-left:3px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);margin:8px 0;padding:0 12px}.F1KBNa_mdPreviewBody hr{background:var(--dsw-alias-border-l1);border:none;height:1px;margin:16px 0}.F1KBNa_mdPreviewBody table{border-collapse:collapse;margin:8px 0}.F1KBNa_mdPreviewBody th,.F1KBNa_mdPreviewBody td{border:1px solid var(--dsw-alias-border-l1);padding:4px 10px}.F1KBNa_mdPreviewBody img{max-width:100%}.F1KBNa_mdPreviewBody .mdImageFallback{border:1px dashed var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-markdown-code-block) 45%, transparent);width:100%;min-height:120px;color:var(--dsw-alias-label-secondary);font-family:var(--dsw-font-markdown-code-block);text-align:center;white-space:pre-wrap;word-break:break-all;border-radius:4px;justify-content:center;align-items:center;margin:0 auto;padding:8px 12px;font-size:12px;line-height:16px;display:flex}.F1KBNa_toggle{border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:18px;flex:none;width:60px;height:36px;padding:0;position:relative}.F1KBNa_toggle:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_toggle:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.F1KBNa_toggleOn{border-color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-state-business-primary)}.F1KBNa_toggleOn:hover{background:var(--dsw-alias-state-business-primary)}.F1KBNa_toggleThumb{background:var(--dsw-alias-label-primary);border-radius:50%;width:28px;height:28px;transition:left .12s;position:absolute;top:3px;left:3px}.F1KBNa_toggleOn .F1KBNa_toggleThumb{background:#fff;left:27px}.F1KBNa_stepper{align-items:center;gap:6px;display:inline-flex}.F1KBNa_stepperButton{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-module-platform);width:32px;height:32px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:8px;padding:0;position:relative}.F1KBNa_stepperButton:before,.F1KBNa_stepperButton:after{content:\"\";background:currentColor;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.F1KBNa_stepperButton:before{width:10px;height:1px}.F1KBNa_stepperButton:after{width:1px;height:10px;display:none}.F1KBNa_stepperButtonUp:after{display:block}.F1KBNa_stepperButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_stepperButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_stepperValue{text-align:center;min-width:2ch;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:14px;line-height:22px}.F1KBNa_states{flex-direction:column;flex:1;min-height:0;padding:4px 12px 12px;display:flex;overflow-y:auto}.F1KBNa_split{flex:1;align-items:stretch;min-height:0;display:flex;position:relative}.F1KBNa_fileListKnob{z-index:39;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:28px;height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;box-shadow:var(--dsw-elevation-prominent);border-radius:8px;justify-content:center;align-items:center;padding:0;display:inline-flex;position:absolute}.F1KBNa_fileListKnob[data-open]{box-shadow:none;opacity:0}.F1KBNa_fileListKnob:not([data-open]){animation:.32s ease-in-out .5s both F1KBNa_fileListKnobIn}@keyframes F1KBNa_fileListKnobIn{0%{opacity:0}to{opacity:1}}.F1KBNa_fileListKnob:hover,.F1KBNa_fileListKnob:focus-visible{background-color:var(--dsw-alias-bg-base);background-image:linear-gradient(var(--dsw-alias-interactive-bg-hover), var(--dsw-alias-interactive-bg-hover))}.F1KBNa_fileListFloat{z-index:40;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);box-shadow:none;transform-origin:0 0;border-radius:12px;flex-direction:column;padding:6px 8px 10px;display:flex;position:absolute;overflow:hidden}.F1KBNa_fileListFloatClosing{pointer-events:none;animation:.14s ease-in forwards F1KBNa_fileListShrink}@keyframes F1KBNa_fileListShrink{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.96)}}.F1KBNa_fileList{box-sizing:border-box;border-right:1px solid var(--dsw-alias-border-l2);flex-direction:column;flex:none;width:240px;min-height:0;padding:4px 8px 12px;display:flex}.F1KBNa_listScroll{flex:1;min-height:0;overflow-y:scroll}.F1KBNa_bulkActions{flex:none;gap:6px;padding:8px 8px 0 0;display:flex}.F1KBNa_bulkActions .F1KBNa_action{text-align:center;flex:1}.F1KBNa_resizeHandle{cursor:col-resize;touch-action:none;background:0 0;flex:none;width:5px;margin:0 -2px}.F1KBNa_resizeHandle:hover{background:var(--dsw-alias-border-l2)}.F1KBNa_floatResizeHandle{z-index:41;cursor:col-resize;-webkit-user-select:none;user-select:none;touch-action:none;background:0 0;border-radius:4px;position:absolute}.F1KBNa_floatResizeHandle:hover{background-color:var(--dsw-alias-bg-base);background-image:linear-gradient(var(--dsw-alias-border-l2), var(--dsw-alias-border-l2))}.F1KBNa_detail{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.F1KBNa_detailEmpty{color:var(--dsw-alias-label-tertiary);text-align:center;flex:1;justify-content:center;align-items:center;margin:0;padding:24px;font-size:12px;line-height:18px;display:flex}.F1KBNa_confirmBackdrop{z-index:55;background:color-mix(in srgb, var(--dsw-alias-bg-base) 55%, transparent);justify-content:center;align-items:center;padding:24px;display:flex;position:absolute;inset:0}.F1KBNa_confirmCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);max-width:340px;box-shadow:var(--dsw-shadow-lv3);border-radius:12px;flex-direction:column;gap:12px;padding:16px;display:flex}.F1KBNa_confirmText{font:var(--dsw-font-caption);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0;line-height:1.5}.F1KBNa_confirmActions{flex:none;justify-content:flex-end;align-items:center;gap:8px;display:flex}.F1KBNa_pickerCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:420px;max-width:100%;height:70%;max-height:100%;box-shadow:var(--dsw-shadow-lv3);border-radius:12px;flex-direction:column;gap:8px;padding:14px 16px 16px;display:flex;position:relative;overflow:hidden}.F1KBNa_pickerTitle{color:var(--dsw-alias-label-primary);flex:none;font-size:13px;font-weight:500;line-height:20px}.F1KBNa_pickerClose{width:22px;height:22px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:6px;justify-content:center;align-items:center;padding:0;display:inline-flex;position:absolute;top:10px;right:10px}.F1KBNa_pickerClose:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_pickerForm{flex:none;gap:8px;display:flex}.F1KBNa_pickerInput{border:1px solid var(--dsw-alias-border-l1);min-width:0;color:var(--dsw-alias-label-primary);background:0 0;border-radius:8px;flex:auto;padding:3px 8px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_pickerInput:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}.F1KBNa_tree{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex:auto;min-height:0;padding:4px 2px 4px 4px;overflow:auto scroll}.F1KBNa_treeRow{border-radius:6px;align-items:center;gap:2px;padding-right:4px;display:flex}.F1KBNa_treeRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_treeRow[data-selected]{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 18%, transparent)}.F1KBNa_treeCaret{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_treeCaret:hover{color:var(--dsw-alias-label-primary)}.F1KBNa_treeName{min-width:0;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:0;border-radius:6px;flex:auto;align-items:center;gap:6px;padding:2px 4px;font-family:inherit;font-size:12px;line-height:18px;display:flex}.F1KBNa_treeName:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_treeNote{color:var(--dsw-alias-label-tertiary);margin:2px 0;font-size:12px;line-height:18px}.F1KBNa_pickerIcon{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:inline-flex}.F1KBNa_pickerName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.F1KBNa_pickerNote{color:var(--dsw-alias-label-tertiary);flex:none;margin:0;font-size:12px;line-height:18px}.F1KBNa_pickerCheck{color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:6px;margin-right:auto;font-size:12px;line-height:18px;display:flex}.F1KBNa_title{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}.F1KBNa_note,.F1KBNa_readError,.F1KBNa_hint{color:var(--dsw-alias-label-tertiary);margin:4px 0;font-size:12px;line-height:18px}.F1KBNa_noteCentered{text-align:center;margin:auto}.F1KBNa_emptyState{flex-direction:column;align-items:center;gap:10px;margin:auto;display:flex}.F1KBNa_importButton{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:5px 14px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_importButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_importButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_importNote{color:var(--dsw-alias-label-tertiary);text-align:center;margin:0;font-size:12px;line-height:18px}.F1KBNa_readError{color:var(--dsw-alias-state-error-primary)}.F1KBNa_group{color:var(--dsw-alias-label-tertiary);margin:8px 0 4px;font-size:12px;font-weight:500;line-height:16px}.F1KBNa_groupHead{align-items:center;gap:4px;margin:8px 0 4px;padding-right:8px;display:flex}.F1KBNa_action.F1KBNa_addButton{box-sizing:border-box;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;min-height:0;padding:0;display:inline-flex}.F1KBNa_groupHead>.F1KBNa_group{margin:0}.F1KBNa_emptyActions{flex-wrap:wrap;justify-content:center;gap:8px;display:flex}.F1KBNa_rows{margin:0;padding:0;list-style:none}.F1KBNa_row{border:1px solid #0000;border-radius:10px;margin:2px 0}.F1KBNa_rowHead{width:100%;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_rowHead:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_rowHead[data-selected]{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_rowPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;margin-left:4px;font-size:12px;line-height:18px;position:relative;top:1px;overflow:hidden}.F1KBNa_kindTag{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_kindHint{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:16px}.F1KBNa_divergedHint,.F1KBNa_missingHint{border-bottom:1px solid var(--dsw-alias-border-l2);margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missing{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary));white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_rowFailed{border:1px solid var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_actionError{border-bottom:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missingHint{color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary))}.F1KBNa_rowMeta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;gap:6px;margin-left:auto;font-size:12px;line-height:16px;display:inline-flex}.F1KBNa_addCount{color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 60%, var(--dsw-alias-label-primary))}.F1KBNa_delCount{color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 60%, var(--dsw-alias-label-primary))}.F1KBNa_diff{background:var(--dsw-alias-markdown-code-block);flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_diffHeader{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_panelDocked .F1KBNa_diffHeader{background:var(--dsw-alias-bg-base)}.F1KBNa_diffPath{white-space:nowrap;scrollbar-width:none;min-width:0;color:var(--dsw-alias-label-primary);-webkit-user-select:text;user-select:text;flex:1;margin-left:4px;font-size:12px;line-height:18px;position:relative;top:1px;overflow:auto hidden}.F1KBNa_diffPath::-webkit-scrollbar{display:none}.F1KBNa_diffActions{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffStats{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:16px}.F1KBNa_flexSpacer{flex:1}.F1KBNa_divider{background:var(--dsw-alias-border-l1);align-self:stretch;width:1px;margin:2px 0}.F1KBNa_action{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_action:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_actionPrimary{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_actionPrimary:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_actionPrimary:disabled{background:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:.55}.F1KBNa_actionQuietDisabled:disabled{cursor:pointer;color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l1);background:0 0}.F1KBNa_actionPrimary.F1KBNa_actionQuietDisabled:disabled{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:1}.F1KBNa_iconAction{justify-content:center;align-items:center;min-height:25px;padding:4px 6px;display:inline-flex}.F1KBNa_close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expand{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_expand:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expandExpanded svg{transform:rotate(180deg)}.F1KBNa_diffBodyWrap{isolation:isolate;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_diffBody{min-width:0;font:var(--dsw-font-markdown-code-block);-webkit-text-size-adjust:100%;text-size-adjust:100%;cursor:text;outline:none;flex:1;padding:0;position:relative;overflow:auto}.F1KBNa_diffBody::-webkit-scrollbar,.F1KBNa_diffBody::-webkit-scrollbar-track,.F1KBNa_diffBody::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_blockActions{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);z-index:2;border-radius:10px;align-items:center;gap:9px;padding:5px;display:flex;position:absolute;right:8px}.F1KBNa_blockActionsDivider{background:var(--dsw-alias-border-l2);flex:none;align-self:stretch;width:1px;margin:2px 0}.F1KBNa_blockPosition{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;margin-top:1px;margin-left:7px;font-size:12px;line-height:16px}.F1KBNa_searchBar{z-index:3;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);border-radius:10px;align-items:center;gap:4px;padding:4px;display:flex;position:absolute;top:8px;right:8px}.F1KBNa_searchInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);width:150px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:3px 8px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_searchInput:focus{border-color:var(--dsw-alias-state-business-primary)}.F1KBNa_searchCount{text-align:center;min-width:34px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:16px}.F1KBNa_searchToggle{border:1px solid var(--dsw-alias-border-l1);min-height:25px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;justify-content:center;align-items:center;padding:4px 6px;display:inline-flex}.F1KBNa_searchToggle:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_searchToggleOn{border-color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-state-business-primary)}.F1KBNa_searchMatch{color:inherit;background-color:#facc1542;border-radius:2px}.F1KBNa_searchMatchCurrent{color:inherit;background-color:#facc1599;border-radius:2px}.F1KBNa_blockFlash{z-index:1;box-sizing:border-box;border:2px solid var(--dsw-alias-state-business-primary);pointer-events:none;border-radius:4px;animation:1s ease-out forwards F1KBNa_diffFlashFade;position:absolute;left:0;right:0}.F1KBNa_blockFlashShake{animation:.7s ease-out forwards F1KBNa_diffFlashShake}.F1KBNa_discussionRow{display:table-row}.F1KBNa_discussionCell{display:table-cell}.F1KBNa_discussionPin{width:0;height:0;position:sticky;left:0}.F1KBNa_discussion{z-index:2;box-sizing:border-box;background:var(--dsw-alias-bg-base);border-left:3px solid var(--dsw-alias-label-secondary);flex-direction:column;display:flex;position:absolute;top:0;left:0;overflow:hidden}.F1KBNa_discussionHead,.F1KBNa_discussionBody{font:var(--dsw-font-markdown-code-block)}.F1KBNa_discussionBody{flex-direction:column;flex:auto;min-height:0;padding:0 12px;display:flex;overflow:hidden}.F1KBNa_discussion[data-lost]{border-left-color:var(--dsw-alias-state-warn-primary,var(--dsw-alias-label-tertiary))}.F1KBNa_discussion[data-lost] .F1KBNa_discussionAnswer{color:var(--dsw-alias-label-secondary)}.F1KBNa_discussionAnswer{color:var(--dsw-alias-label-primary);font-family:inherit;font-size:calc(1em * var(--dsh-diff-font-scale,1));line-height:var(--dsh-diff-line-height,22px);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;padding:0}.F1KBNa_discussionUser{padding:calc(var(--dsh-diff-line-height,22px) * .2) calc(var(--dsh-diff-line-height,22px) * .5);margin:calc(var(--dsh-diff-line-height,22px) * .3) 0 calc(var(--dsh-diff-line-height,22px) * .3) auto;box-sizing:border-box;background:var(--dsw-specific-bubble,var(--dsw-alias-bg-layer-2,var(--dsw-alias-interactive-bg-hover)));width:fit-content;max-width:82%;color:var(--dsw-alias-label-primary);font-family:inherit;font-size:calc(1em * var(--dsh-diff-font-scale,1));line-height:var(--dsh-diff-line-height,22px);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:8px}.F1KBNa_discussionNote{color:var(--dsw-alias-label-secondary);font-family:inherit;font-size:calc(1em * var(--dsh-diff-font-scale,1));line-height:var(--dsh-diff-line-height,22px);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;padding:0}.F1KBNa_discussionNote[data-diff-discussion-hidden]{color:var(--dsw-alias-label-tertiary)}.F1KBNa_discussionHead{box-sizing:border-box;height:var(--dsh-diff-line-height,22px);flex:none;align-items:center;gap:8px;padding:0 12px;font-size:12px;line-height:16px;display:flex}.F1KBNa_discussionCompose{box-sizing:border-box;height:calc(var(--dsh-diff-line-height,22px) * 2);flex:none;align-items:center;gap:8px;margin:0 -6px;padding:0;display:flex}.F1KBNa_discussionInput{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);min-width:0;color:var(--dsw-alias-label-primary);font-family:inherit;font-size:calc(1em * var(--dsh-diff-font-scale,1));border-radius:6px;flex:auto;padding:3px 8px;line-height:18px}.F1KBNa_discussionToggle{width:18px;height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_discussionToggle:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_discussionRangeWrap{font:var(--dsw-font-markdown-code-block);flex:none}.F1KBNa_discussionRange{color:var(--dsw-alias-label-tertiary);font-family:inherit;font-size:calc(1em * var(--dsh-diff-font-scale,1))}.F1KBNa_discussionInput:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}.F1KBNa_discussionInput::placeholder{font-family:inherit;font-size:inherit;color:var(--dsw-alias-label-tertiary)}.F1KBNa_discussionSend{box-sizing:border-box;white-space:nowrap;flex:none;justify-content:center;align-items:center;gap:6px;padding-left:9px;padding-right:9px;display:inline-flex}.F1KBNa_rowDiscussed{background-image:linear-gradient(color-mix(in srgb, var(--dsw-alias-label-secondary) 14%, transparent), color-mix(in srgb, var(--dsw-alias-label-secondary) 14%, transparent))}@keyframes F1KBNa_diffFlashFade{0%{opacity:1}to{opacity:0}}@keyframes F1KBNa_diffFlashShake{0%{opacity:1;transform:translateY(0)}10%{transform:translateY(1px)}20%{transform:translateY(-1px)}30%{transform:translateY(1px)}40%{transform:translateY(-1px)}50%{transform:translateY(1px)}60%{transform:translateY(-1px)}70%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(0)}}.F1KBNa_overviewRuler{pointer-events:none;opacity:.5;width:4px;position:absolute;top:0;bottom:0;right:0}.F1KBNa_overviewMarker{border-radius:2px;width:100%;min-height:2px;position:absolute;right:0}.F1KBNa_markerDel{background-color:var(--dsw-alias-state-error-primary)}.F1KBNa_markerAdd{background-color:var(--dsw-alias-state-success-primary)}.F1KBNa_lines{border-spacing:0;width:max-content;min-width:100%;font-size:calc(1em * var(--dsh-diff-font-scale,1));display:table}.F1KBNa_line{height:var(--dsh-diff-line-height,22px);line-height:var(--dsh-diff-line-height,22px);-webkit-user-select:none;user-select:none;display:table-row}.F1KBNa_vSpacer{display:table-row}.F1KBNa_gutter{box-sizing:border-box;text-align:right;width:44px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;-webkit-user-select:none;user-select:none;cursor:default;padding-right:10px;display:table-cell}.F1KBNa_code{white-space:pre;-webkit-user-select:text;user-select:text;display:table-cell}.F1KBNa_context{color:var(--dsw-alias-label-primary)}.F1KBNa_del{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_add{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_statusBar{box-sizing:border-box;border-top:1px solid var(--dsw-alias-border-l2);height:34px;color:var(--dsw-alias-label-tertiary);font-family:var(--dsw-font-markdown-code-block);font-variant-numeric:tabular-nums;flex:none;align-items:center;gap:8px;padding:0 8px;font-size:12px;line-height:18px;display:flex}.F1KBNa_statusAction{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_statusAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langSelect{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;flex:none;align-items:center;gap:4px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_langSelect:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langLabel{text-overflow:ellipsis;white-space:nowrap;max-width:140px;overflow:hidden}.F1KBNa_presentationSelect{cursor:pointer;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;gap:2px;padding:0 6px;display:inline-flex}.F1KBNa_presentationSelect:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_chip{justify-content:flex-end;align-items:center;gap:5px;min-width:0;padding-right:14px;display:inline-flex}.F1KBNa_chipLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.F1KBNa_coverHost{align-items:center;display:inline-flex;position:relative}.F1KBNa_coverCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv2);border-radius:12px;align-items:center;gap:4px;padding:6px;display:flex}.F1KBNa_coverPopover{z-index:50;position:absolute;top:calc(100% + 6px);right:0}.F1KBNa_coverNotice{z-index:80;pointer-events:none;animation:1.25s ease-out forwards F1KBNa_coverNoticeFade;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.F1KBNa_coverNoticeCard{gap:4px;padding:6px 8px}@keyframes F1KBNa_coverNoticeFade{0%,78%{opacity:1}to{opacity:0}}.F1KBNa_coverNoticeGlyph{width:44px;height:44px;color:var(--dsw-alias-label-tertiary);border-radius:10px;justify-content:center;align-items:center;display:inline-flex}.F1KBNa_coverNoticeGlyph[data-on]{color:var(--dsw-alias-label-primary)}.F1KBNa_coverNoticeGlyph[data-changed]{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_coverNoticeText{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.F1KBNa_coverButton{width:32px;height:32px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:8px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_coverButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_coverButton[data-on]{color:var(--dsw-alias-label-primary)}.F1KBNa_presentationHost{align-items:center;display:inline-flex}.F1KBNa_chipPresentation{min-width:36px;height:20px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:20px;flex:none;justify-content:center;align-items:center;gap:2px;padding:0 6px;display:inline-flex}.F1KBNa_chipPresentation:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_mirrored{transform:scaleX(-1)}.F1KBNa_notice{z-index:60;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);max-width:360px;box-shadow:var(--dsw-shadow-lv3);border-radius:10px;align-items:flex-start;gap:12px;padding:12px 14px;display:flex;position:fixed;bottom:24px;right:24px}.F1KBNa_noticeText{font:var(--dsw-font-caption);color:var(--dsw-alias-label-primary);flex:1;margin:0;line-height:1.45}.F1KBNa_noticeButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);font:var(--dsw-font-caption);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px}.F1KBNa_noticeButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_wrap .F1KBNa_line{height:auto;min-height:var(--dsh-diff-line-height,22px)}.F1KBNa_subline{height:var(--dsh-diff-line-height,22px);line-height:var(--dsh-diff-line-height,22px);white-space:pre;display:block;overflow:hidden}.F1KBNa_wrapActive{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_wrapActive:hover{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_splitRoot{isolation:isolate;flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_diffBodySplit{flex:1;min-height:0;overflow-x:hidden}.F1KBNa_splitCols{width:100%;min-width:0;display:flex}.F1KBNa_splitCol{box-sizing:border-box;flex:1 1 0;min-width:0;overflow:hidden}.F1KBNa_splitDivider{background:var(--dsw-alias-border-l2);flex:0 0 1px}.F1KBNa_splitCol .F1KBNa_gutter,.F1KBNa_splitCol .F1KBNa_code{vertical-align:top}.F1KBNa_splitHScrollRow{border-top:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;width:100%;min-width:0;display:flex}.F1KBNa_splitHScroll{min-width:0;height:var(--dsh-scrollbar-width,8px);flex:1 1 0;overflow:auto hidden}.F1KBNa_splitHScroll::-webkit-scrollbar{height:var(--dsh-scrollbar-width,8px)}.F1KBNa_splitHScroll::-webkit-scrollbar-track{cursor:default}.F1KBNa_splitHScroll::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_splitHScrollFill{height:1px}.F1KBNa_splitLdel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_splitLadd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_splitRdel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_splitRadd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_intraDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 26%, transparent);text-decoration:line-through}.F1KBNa_intraAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 24%, transparent)}";
|
|
25
25
|
const tagId = "dsh-diff-approval/PendingPanel.module.css";
|
|
26
26
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
27
27
|
const tag = document.createElement("style");
|
|
@@ -31,204 +31,223 @@ window.__ModuleLoader__.load({
|
|
|
31
31
|
document.head.appendChild(tag);
|
|
32
32
|
}
|
|
33
33
|
var PendingPanel_module_css_default = {
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
34
|
+
"wrap": "F1KBNa_wrap",
|
|
35
|
+
"colorPickerChevron": "F1KBNa_colorPickerChevron",
|
|
36
|
+
"headerActions": "F1KBNa_headerActions",
|
|
37
|
+
"pickerIcon": "F1KBNa_pickerIcon",
|
|
38
|
+
"searchToggle": "F1KBNa_searchToggle",
|
|
39
|
+
"settingsGroup": "F1KBNa_settingsGroup",
|
|
40
|
+
"mdPreviewBody": "F1KBNa_mdPreviewBody",
|
|
40
41
|
"mirrored": "F1KBNa_mirrored",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
42
|
+
"wrapActive": "F1KBNa_wrapActive",
|
|
43
|
+
"settingsGroupDesc": "F1KBNa_settingsGroupDesc",
|
|
44
|
+
"pickerForm": "F1KBNa_pickerForm",
|
|
45
|
+
"importButton": "F1KBNa_importButton",
|
|
46
|
+
"splitRadd": "F1KBNa_splitRadd",
|
|
45
47
|
"colorHueCursor": "F1KBNa_colorHueCursor",
|
|
46
|
-
"statusBar": "F1KBNa_statusBar",
|
|
47
|
-
"settingsGroupBody": "F1KBNa_settingsGroupBody",
|
|
48
|
-
"toggleThumb": "F1KBNa_toggleThumb",
|
|
49
|
-
"fileListFloat": "F1KBNa_fileListFloat",
|
|
50
|
-
"panel": "F1KBNa_panel",
|
|
51
48
|
"groupHead": "F1KBNa_groupHead",
|
|
52
|
-
"
|
|
53
|
-
"
|
|
49
|
+
"fileListKnobIn": "F1KBNa_fileListKnobIn",
|
|
50
|
+
"diffFlashFade": "F1KBNa_diffFlashFade",
|
|
51
|
+
"coverHost": "F1KBNa_coverHost",
|
|
52
|
+
"pickerName": "F1KBNa_pickerName",
|
|
53
|
+
"colorPickerPanel": "F1KBNa_colorPickerPanel",
|
|
54
|
+
"stepperValue": "F1KBNa_stepperValue",
|
|
55
|
+
"stepperButton": "F1KBNa_stepperButton",
|
|
56
|
+
"discussionCell": "F1KBNa_discussionCell",
|
|
54
57
|
"layer": "F1KBNa_layer",
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"delCount": "F1KBNa_delCount",
|
|
63
|
-
"pickerCard": "F1KBNa_pickerCard",
|
|
64
|
-
"note": "F1KBNa_note",
|
|
65
|
-
"emptyActions": "F1KBNa_emptyActions",
|
|
66
|
-
"close": "F1KBNa_close",
|
|
67
|
-
"split": "F1KBNa_split",
|
|
68
|
-
"blockActions": "F1KBNa_blockActions",
|
|
58
|
+
"line": "F1KBNa_line",
|
|
59
|
+
"chipLabel": "F1KBNa_chipLabel",
|
|
60
|
+
"footerButtons": "F1KBNa_footerButtons",
|
|
61
|
+
"searchInput": "F1KBNa_searchInput",
|
|
62
|
+
"searchCount": "F1KBNa_searchCount",
|
|
63
|
+
"discussionCompose": "F1KBNa_discussionCompose",
|
|
64
|
+
"toggle": "F1KBNa_toggle",
|
|
69
65
|
"searchMatchCurrent": "F1KBNa_searchMatchCurrent",
|
|
66
|
+
"rowDiscussed": "F1KBNa_rowDiscussed",
|
|
67
|
+
"coverNotice": "F1KBNa_coverNotice",
|
|
68
|
+
"diffPath": "F1KBNa_diffPath",
|
|
69
|
+
"fileListShrink": "F1KBNa_fileListShrink",
|
|
70
|
+
"dockHost": "F1KBNa_dockHost",
|
|
71
|
+
"noteCentered": "F1KBNa_noteCentered",
|
|
72
|
+
"stepper": "F1KBNa_stepper",
|
|
73
|
+
"colorValue": "F1KBNa_colorValue",
|
|
74
|
+
"addButton": "F1KBNa_addButton",
|
|
75
|
+
"settingsGroupTitle": "F1KBNa_settingsGroupTitle",
|
|
76
|
+
"colorSwatch": "F1KBNa_colorSwatch",
|
|
70
77
|
"searchMatch": "F1KBNa_searchMatch",
|
|
71
|
-
"
|
|
72
|
-
"add": "F1KBNa_add",
|
|
73
|
-
"chipLabel": "F1KBNa_chipLabel",
|
|
74
|
-
"chipPresentation": "F1KBNa_chipPresentation",
|
|
75
|
-
"splitHScrollRow": "F1KBNa_splitHScrollRow",
|
|
76
|
-
"searchToggleOn": "F1KBNa_searchToggleOn",
|
|
78
|
+
"statusAction": "F1KBNa_statusAction",
|
|
77
79
|
"importNote": "F1KBNa_importNote",
|
|
80
|
+
"settingsPage": "F1KBNa_settingsPage",
|
|
78
81
|
"chip": "F1KBNa_chip",
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
+
"context": "F1KBNa_context",
|
|
83
|
+
"coverNoticeCard": "F1KBNa_coverNoticeCard",
|
|
84
|
+
"presentationHost": "F1KBNa_presentationHost",
|
|
85
|
+
"emptyActions": "F1KBNa_emptyActions",
|
|
82
86
|
"splitLadd": "F1KBNa_splitLadd",
|
|
83
|
-
"pickerClose": "F1KBNa_pickerClose",
|
|
84
|
-
"gutter": "F1KBNa_gutter",
|
|
85
|
-
"kindTag": "F1KBNa_kindTag",
|
|
86
|
-
"addButton": "F1KBNa_addButton",
|
|
87
|
-
"intraDel": "F1KBNa_intraDel",
|
|
88
|
-
"splitCol": "F1KBNa_splitCol",
|
|
89
|
-
"header": "F1KBNa_header",
|
|
90
87
|
"addCount": "F1KBNa_addCount",
|
|
91
|
-
"
|
|
92
|
-
"noticeButton": "F1KBNa_noticeButton",
|
|
88
|
+
"settingsGroupBody": "F1KBNa_settingsGroupBody",
|
|
93
89
|
"mdPreviewSingle": "F1KBNa_mdPreviewSingle",
|
|
94
|
-
"settingsGroupTitle": "F1KBNa_settingsGroupTitle",
|
|
95
90
|
"diffBodyWrap": "F1KBNa_diffBodyWrap",
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
91
|
+
"diffPreview": "F1KBNa_diffPreview",
|
|
92
|
+
"action": "F1KBNa_action",
|
|
93
|
+
"discussionRow": "F1KBNa_discussionRow",
|
|
94
|
+
"confirmBackdrop": "F1KBNa_confirmBackdrop",
|
|
95
|
+
"treeRow": "F1KBNa_treeRow",
|
|
96
|
+
"discussionToggle": "F1KBNa_discussionToggle",
|
|
97
|
+
"discussionRange": "F1KBNa_discussionRange",
|
|
98
|
+
"gutter": "F1KBNa_gutter",
|
|
103
99
|
"settingsGroupText": "F1KBNa_settingsGroupText",
|
|
104
|
-
"
|
|
105
|
-
"toggleOn": "F1KBNa_toggleOn",
|
|
106
|
-
"context": "F1KBNa_context",
|
|
107
|
-
"stepperButtonUp": "F1KBNa_stepperButtonUp",
|
|
108
|
-
"diffPath": "F1KBNa_diffPath",
|
|
109
|
-
"listScroll": "F1KBNa_listScroll",
|
|
110
|
-
"pickerForm": "F1KBNa_pickerForm",
|
|
111
|
-
"readError": "F1KBNa_readError",
|
|
112
|
-
"markerAdd": "F1KBNa_markerAdd",
|
|
113
|
-
"dockHost": "F1KBNa_dockHost",
|
|
114
|
-
"diffPreviewScroll": "F1KBNa_diffPreviewScroll",
|
|
115
|
-
"stepperButton": "F1KBNa_stepperButton",
|
|
116
|
-
"diffFlashShake": "F1KBNa_diffFlashShake",
|
|
117
|
-
"mdPreviewFallback": "F1KBNa_mdPreviewFallback",
|
|
118
|
-
"code": "F1KBNa_code",
|
|
119
|
-
"coverNoticeText": "F1KBNa_coverNoticeText",
|
|
120
|
-
"splitRdel": "F1KBNa_splitRdel",
|
|
121
|
-
"noticeText": "F1KBNa_noticeText",
|
|
122
|
-
"diffBody": "F1KBNa_diffBody",
|
|
123
|
-
"fileListKnob": "F1KBNa_fileListKnob",
|
|
100
|
+
"colorSv": "F1KBNa_colorSv",
|
|
124
101
|
"divergedHint": "F1KBNa_divergedHint",
|
|
125
|
-
"
|
|
102
|
+
"mdPreviewWrap": "F1KBNa_mdPreviewWrap",
|
|
103
|
+
"del": "F1KBNa_del",
|
|
104
|
+
"actionError": "F1KBNa_actionError",
|
|
105
|
+
"badgeCount": "F1KBNa_badgeCount",
|
|
106
|
+
"header": "F1KBNa_header",
|
|
107
|
+
"fileList": "F1KBNa_fileList",
|
|
108
|
+
"pickerNote": "F1KBNa_pickerNote",
|
|
109
|
+
"colorPickerInput": "F1KBNa_colorPickerInput",
|
|
110
|
+
"chipPresentation": "F1KBNa_chipPresentation",
|
|
111
|
+
"split": "F1KBNa_split",
|
|
126
112
|
"tree": "F1KBNa_tree",
|
|
127
|
-
"
|
|
113
|
+
"close": "F1KBNa_close",
|
|
114
|
+
"panelDocked": "F1KBNa_panelDocked",
|
|
115
|
+
"actionPrimary": "F1KBNa_actionPrimary",
|
|
116
|
+
"discussionPin": "F1KBNa_discussionPin",
|
|
117
|
+
"splitLdel": "F1KBNa_splitLdel",
|
|
118
|
+
"fileListFloatClosing": "F1KBNa_fileListFloatClosing",
|
|
119
|
+
"pickerCheck": "F1KBNa_pickerCheck",
|
|
120
|
+
"overviewMarker": "F1KBNa_overviewMarker",
|
|
121
|
+
"delCount": "F1KBNa_delCount",
|
|
122
|
+
"divider": "F1KBNa_divider",
|
|
123
|
+
"coverNoticeText": "F1KBNa_coverNoticeText",
|
|
124
|
+
"panel": "F1KBNa_panel",
|
|
125
|
+
"splitRdel": "F1KBNa_splitRdel",
|
|
128
126
|
"detail": "F1KBNa_detail",
|
|
129
|
-
"
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"
|
|
127
|
+
"intraDel": "F1KBNa_intraDel",
|
|
128
|
+
"panelFailure": "F1KBNa_panelFailure",
|
|
129
|
+
"discussionAnswer": "F1KBNa_discussionAnswer",
|
|
130
|
+
"splitHScrollFill": "F1KBNa_splitHScrollFill",
|
|
131
|
+
"colorHue": "F1KBNa_colorHue",
|
|
132
|
+
"emptyState": "F1KBNa_emptyState",
|
|
133
|
+
"blockFlashShake": "F1KBNa_blockFlashShake",
|
|
134
|
+
"colorPickerPreview": "F1KBNa_colorPickerPreview",
|
|
135
|
+
"blockActionsDivider": "F1KBNa_blockActionsDivider",
|
|
136
|
+
"lines": "F1KBNa_lines",
|
|
136
137
|
"rowMeta": "F1KBNa_rowMeta",
|
|
138
|
+
"noticeText": "F1KBNa_noticeText",
|
|
139
|
+
"group": "F1KBNa_group",
|
|
140
|
+
"coverNoticeGlyph": "F1KBNa_coverNoticeGlyph",
|
|
141
|
+
"colorPickerTrigger": "F1KBNa_colorPickerTrigger",
|
|
142
|
+
"row": "F1KBNa_row",
|
|
137
143
|
"flexSpacer": "F1KBNa_flexSpacer",
|
|
144
|
+
"missingHint": "F1KBNa_missingHint",
|
|
145
|
+
"blockActions": "F1KBNa_blockActions",
|
|
146
|
+
"kindTag": "F1KBNa_kindTag",
|
|
147
|
+
"discussionInput": "F1KBNa_discussionInput",
|
|
148
|
+
"markerDel": "F1KBNa_markerDel",
|
|
149
|
+
"listScroll": "F1KBNa_listScroll",
|
|
150
|
+
"resizeHandle": "F1KBNa_resizeHandle",
|
|
151
|
+
"panelFailureText": "F1KBNa_panelFailureText",
|
|
152
|
+
"diffStats": "F1KBNa_diffStats",
|
|
138
153
|
"hint": "F1KBNa_hint",
|
|
139
|
-
"
|
|
154
|
+
"mdPreviewContent": "F1KBNa_mdPreviewContent",
|
|
155
|
+
"badgeLabel": "F1KBNa_badgeLabel",
|
|
156
|
+
"bulkActions": "F1KBNa_bulkActions",
|
|
157
|
+
"settingsGroupHeader": "F1KBNa_settingsGroupHeader",
|
|
158
|
+
"detailEmpty": "F1KBNa_detailEmpty",
|
|
159
|
+
"expandExpanded": "F1KBNa_expandExpanded",
|
|
160
|
+
"diffFlashShake": "F1KBNa_diffFlashShake",
|
|
161
|
+
"presentationSelect": "F1KBNa_presentationSelect",
|
|
162
|
+
"coverPopover": "F1KBNa_coverPopover",
|
|
163
|
+
"add": "F1KBNa_add",
|
|
164
|
+
"coverButton": "F1KBNa_coverButton",
|
|
165
|
+
"pickerInput": "F1KBNa_pickerInput",
|
|
166
|
+
"note": "F1KBNa_note",
|
|
167
|
+
"rowHead": "F1KBNa_rowHead",
|
|
168
|
+
"toggleThumb": "F1KBNa_toggleThumb",
|
|
169
|
+
"discussionSend": "F1KBNa_discussionSend",
|
|
170
|
+
"treeCaret": "F1KBNa_treeCaret",
|
|
140
171
|
"settingsSelector": "F1KBNa_settingsSelector",
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
"
|
|
172
|
+
"confirmActions": "F1KBNa_confirmActions",
|
|
173
|
+
"title": "F1KBNa_title",
|
|
174
|
+
"panelFailureRetry": "F1KBNa_panelFailureRetry",
|
|
175
|
+
"colorPickerInputRow": "F1KBNa_colorPickerInputRow",
|
|
176
|
+
"fileListFloat": "F1KBNa_fileListFloat",
|
|
144
177
|
"settingsRowTitle": "F1KBNa_settingsRowTitle",
|
|
145
|
-
"
|
|
146
|
-
"
|
|
147
|
-
"
|
|
148
|
-
"expand": "F1KBNa_expand",
|
|
149
|
-
"expandExpanded": "F1KBNa_expandExpanded",
|
|
150
|
-
"blockPosition": "F1KBNa_blockPosition",
|
|
151
|
-
"searchInput": "F1KBNa_searchInput",
|
|
152
|
-
"searchCount": "F1KBNa_searchCount",
|
|
153
|
-
"states": "F1KBNa_states",
|
|
154
|
-
"mdPreviewContent": "F1KBNa_mdPreviewContent",
|
|
178
|
+
"pickerTitle": "F1KBNa_pickerTitle",
|
|
179
|
+
"iconAction": "F1KBNa_iconAction",
|
|
180
|
+
"intraAdd": "F1KBNa_intraAdd",
|
|
155
181
|
"confirmCard": "F1KBNa_confirmCard",
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
182
|
+
"splitHScrollRow": "F1KBNa_splitHScrollRow",
|
|
183
|
+
"missing": "F1KBNa_missing",
|
|
184
|
+
"headerEntry": "F1KBNa_headerEntry",
|
|
185
|
+
"blockPosition": "F1KBNa_blockPosition",
|
|
186
|
+
"discussionRangeWrap": "F1KBNa_discussionRangeWrap",
|
|
187
|
+
"kindHint": "F1KBNa_kindHint",
|
|
188
|
+
"headerEntryCount": "F1KBNa_headerEntryCount",
|
|
189
|
+
"rail": "F1KBNa_rail",
|
|
164
190
|
"splitDivider": "F1KBNa_splitDivider",
|
|
165
|
-
"
|
|
166
|
-
"
|
|
167
|
-
"
|
|
168
|
-
"
|
|
169
|
-
"
|
|
170
|
-
"splitRadd": "F1KBNa_splitRadd",
|
|
171
|
-
"resizeHandle": "F1KBNa_resizeHandle",
|
|
172
|
-
"searchToggle": "F1KBNa_searchToggle",
|
|
191
|
+
"diffPreviewTitle": "F1KBNa_diffPreviewTitle",
|
|
192
|
+
"searchToggleOn": "F1KBNa_searchToggleOn",
|
|
193
|
+
"discussionNote": "F1KBNa_discussionNote",
|
|
194
|
+
"pickerCard": "F1KBNa_pickerCard",
|
|
195
|
+
"diffActions": "F1KBNa_diffActions",
|
|
173
196
|
"notice": "F1KBNa_notice",
|
|
174
|
-
"
|
|
175
|
-
"
|
|
176
|
-
"
|
|
197
|
+
"settingsGroupChevron": "F1KBNa_settingsGroupChevron",
|
|
198
|
+
"fileListKnob": "F1KBNa_fileListKnob",
|
|
199
|
+
"discussionUser": "F1KBNa_discussionUser",
|
|
200
|
+
"confirmText": "F1KBNa_confirmText",
|
|
201
|
+
"states": "F1KBNa_states",
|
|
202
|
+
"noticeButton": "F1KBNa_noticeButton",
|
|
203
|
+
"overviewRuler": "F1KBNa_overviewRuler",
|
|
204
|
+
"rowFailed": "F1KBNa_rowFailed",
|
|
205
|
+
"settingsRow": "F1KBNa_settingsRow",
|
|
206
|
+
"diffPreviewScroll": "F1KBNa_diffPreviewScroll",
|
|
207
|
+
"discussionBody": "F1KBNa_discussionBody",
|
|
208
|
+
"code": "F1KBNa_code",
|
|
209
|
+
"subline": "F1KBNa_subline",
|
|
210
|
+
"splitRoot": "F1KBNa_splitRoot",
|
|
211
|
+
"readError": "F1KBNa_readError",
|
|
212
|
+
"mdPreviewFallback": "F1KBNa_mdPreviewFallback",
|
|
213
|
+
"splitCols": "F1KBNa_splitCols",
|
|
214
|
+
"discussionHead": "F1KBNa_discussionHead",
|
|
215
|
+
"pickerClose": "F1KBNa_pickerClose",
|
|
216
|
+
"settingsRowText": "F1KBNa_settingsRowText",
|
|
217
|
+
"blockFlash": "F1KBNa_blockFlash",
|
|
218
|
+
"langSelect": "F1KBNa_langSelect",
|
|
219
|
+
"treeNote": "F1KBNa_treeNote",
|
|
220
|
+
"rows": "F1KBNa_rows",
|
|
221
|
+
"diffBody": "F1KBNa_diffBody",
|
|
222
|
+
"statusBar": "F1KBNa_statusBar",
|
|
223
|
+
"toggleOn": "F1KBNa_toggleOn",
|
|
224
|
+
"searchBar": "F1KBNa_searchBar",
|
|
225
|
+
"vSpacer": "F1KBNa_vSpacer",
|
|
226
|
+
"rowPath": "F1KBNa_rowPath",
|
|
227
|
+
"colorBackdrop": "F1KBNa_colorBackdrop",
|
|
177
228
|
"coverBackdrop": "F1KBNa_coverBackdrop",
|
|
178
|
-
"
|
|
229
|
+
"colorPicker": "F1KBNa_colorPicker",
|
|
179
230
|
"splitHScroll": "F1KBNa_splitHScroll",
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
"
|
|
183
|
-
"
|
|
184
|
-
"
|
|
231
|
+
"colorSvCursor": "F1KBNa_colorSvCursor",
|
|
232
|
+
"diffHeader": "F1KBNa_diffHeader",
|
|
233
|
+
"expand": "F1KBNa_expand",
|
|
234
|
+
"colorPickerPopover": "F1KBNa_colorPickerPopover",
|
|
235
|
+
"discussion": "F1KBNa_discussion",
|
|
236
|
+
"markerAdd": "F1KBNa_markerAdd",
|
|
237
|
+
"settingsRowDesc": "F1KBNa_settingsRowDesc",
|
|
185
238
|
"actionQuietDisabled": "F1KBNa_actionQuietDisabled",
|
|
186
|
-
"treeNote": "F1KBNa_treeNote",
|
|
187
|
-
"subline": "F1KBNa_subline",
|
|
188
|
-
"floatResizeHandle": "F1KBNa_floatResizeHandle",
|
|
189
239
|
"diffBodySplit": "F1KBNa_diffBodySplit",
|
|
190
|
-
"headerActions": "F1KBNa_headerActions",
|
|
191
|
-
"noteCentered": "F1KBNa_noteCentered",
|
|
192
|
-
"group": "F1KBNa_group",
|
|
193
|
-
"coverHost": "F1KBNa_coverHost",
|
|
194
|
-
"blockFlashShake": "F1KBNa_blockFlashShake",
|
|
195
|
-
"emptyState": "F1KBNa_emptyState",
|
|
196
|
-
"colorSv": "F1KBNa_colorSv",
|
|
197
|
-
"colorHue": "F1KBNa_colorHue",
|
|
198
|
-
"treeCaret": "F1KBNa_treeCaret",
|
|
199
|
-
"diffFlashFade": "F1KBNa_diffFlashFade",
|
|
200
240
|
"mdPreviewDouble": "F1KBNa_mdPreviewDouble",
|
|
201
|
-
"
|
|
202
|
-
"
|
|
203
|
-
"
|
|
204
|
-
"
|
|
205
|
-
"
|
|
206
|
-
"coverButton": "F1KBNa_coverButton",
|
|
207
|
-
"del": "F1KBNa_del",
|
|
208
|
-
"lines": "F1KBNa_lines",
|
|
209
|
-
"missingHint": "F1KBNa_missingHint",
|
|
210
|
-
"settingsGroupHeader": "F1KBNa_settingsGroupHeader",
|
|
211
|
-
"detailEmpty": "F1KBNa_detailEmpty",
|
|
241
|
+
"stepperButtonUp": "F1KBNa_stepperButtonUp",
|
|
242
|
+
"settingsReset": "F1KBNa_settingsReset",
|
|
243
|
+
"floatResizeHandle": "F1KBNa_floatResizeHandle",
|
|
244
|
+
"diff": "F1KBNa_diff",
|
|
245
|
+
"splitCol": "F1KBNa_splitCol",
|
|
212
246
|
"treeName": "F1KBNa_treeName",
|
|
213
|
-
"
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
-
"kindHint": "F1KBNa_kindHint",
|
|
218
|
-
"diffStats": "F1KBNa_diffStats",
|
|
219
|
-
"fileList": "F1KBNa_fileList",
|
|
220
|
-
"splitCols": "F1KBNa_splitCols",
|
|
221
|
-
"badgeLabel": "F1KBNa_badgeLabel",
|
|
222
|
-
"confirmActions": "F1KBNa_confirmActions",
|
|
223
|
-
"pickerNote": "F1KBNa_pickerNote",
|
|
224
|
-
"searchBar": "F1KBNa_searchBar",
|
|
225
|
-
"coverNoticeGlyph": "F1KBNa_coverNoticeGlyph",
|
|
226
|
-
"blockFlash": "F1KBNa_blockFlash",
|
|
227
|
-
"line": "F1KBNa_line",
|
|
228
|
-
"rows": "F1KBNa_rows",
|
|
229
|
-
"coverNoticeCard": "F1KBNa_coverNoticeCard",
|
|
230
|
-
"diffActions": "F1KBNa_diffActions",
|
|
231
|
-
"coverNotice": "F1KBNa_coverNotice"
|
|
247
|
+
"coverCard": "F1KBNa_coverCard",
|
|
248
|
+
"coverNoticeFade": "F1KBNa_coverNoticeFade",
|
|
249
|
+
"badge": "F1KBNa_badge",
|
|
250
|
+
"langLabel": "F1KBNa_langLabel"
|
|
232
251
|
};
|
|
233
252
|
//#endregion
|
|
234
253
|
//#region lib/types/client/PathPicker.js
|
|
@@ -757,6 +776,7 @@ window.__ModuleLoader__.load({
|
|
|
757
776
|
const PRESENTATION_KEY = "diff-approval:presentation";
|
|
758
777
|
const FLOAT_COVER_KEY = "diff-approval:float-cover";
|
|
759
778
|
const FILE_LIST_FLOAT_KEY = "diff-approval:file-list-float";
|
|
779
|
+
const COMMENT_MODE_PREVIEW_KEY = "diff-approval:comment-mode-preview";
|
|
760
780
|
const WRAP_PREFIX = "diff-approval:wrap:";
|
|
761
781
|
/** The floating panel's default coverage: the header and both sidebars, not the
|
|
762
782
|
* composer. */
|
|
@@ -1059,6 +1079,24 @@ window.__ModuleLoader__.load({
|
|
|
1059
1079
|
localStorage.setItem(MD_PREVIEW_KEY, value ? "1" : "0");
|
|
1060
1080
|
}
|
|
1061
1081
|
/**
|
|
1082
|
+
* Whether commenting on a diff range is offered: the selection frame's comment button,
|
|
1083
|
+
* and the chord that stands for it. Defaults to off while the mode is a preview (see
|
|
1084
|
+
* {@link COMMENT_MODE_PREVIEW_KEY}); only an explicit `'1'` enables it. This gates
|
|
1085
|
+
* STARTING a thread, not the threads themselves — one already written keeps rendering,
|
|
1086
|
+
* so turning the mode off never hides work or interrupts an answer on its way back.
|
|
1087
|
+
* @returns whether comment mode is on.
|
|
1088
|
+
*/
|
|
1089
|
+
function commentModeEnabled() {
|
|
1090
|
+
return localStorage.getItem(COMMENT_MODE_PREVIEW_KEY) === "1";
|
|
1091
|
+
}
|
|
1092
|
+
/** Window event: comment mode was toggled (see {@link setCommentModeEnabled}). */
|
|
1093
|
+
const COMMENT_MODE_CHANGED_EVENT = "diff-approval:comment-mode";
|
|
1094
|
+
/** Persist the comment-mode preference. */
|
|
1095
|
+
function setCommentModeEnabled(value) {
|
|
1096
|
+
localStorage.setItem(COMMENT_MODE_PREVIEW_KEY, value ? "1" : "0");
|
|
1097
|
+
if (typeof window !== "undefined") window.dispatchEvent(new CustomEvent(COMMENT_MODE_CHANGED_EVENT));
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1062
1100
|
* The Markdown-preview content max width, in pixels (single column). Defaults to
|
|
1063
1101
|
* 800; the double-column view totals 2x this. An out-of-range or non-integer
|
|
1064
1102
|
* value falls back to the default.
|
|
@@ -1110,6 +1148,7 @@ window.__ModuleLoader__.load({
|
|
|
1110
1148
|
jumpUp: "Ctrl+ArrowUp",
|
|
1111
1149
|
jumpDown: "Ctrl+ArrowDown",
|
|
1112
1150
|
copyRef: "Ctrl+L",
|
|
1151
|
+
addComment: "Ctrl+K",
|
|
1113
1152
|
openSearch: "Ctrl+F",
|
|
1114
1153
|
searchNext: "F3",
|
|
1115
1154
|
searchPrev: "Shift+F3",
|
|
@@ -2683,6 +2722,215 @@ window.__ModuleLoader__.load({
|
|
|
2683
2722
|
if (text === "") return [];
|
|
2684
2723
|
return (text.endsWith("\n") ? text.slice(0, -1) : text).split("\n");
|
|
2685
2724
|
}
|
|
2725
|
+
/**
|
|
2726
|
+
* The newest turns that fit a size budget, and how many older ones were left out.
|
|
2727
|
+
* A thread grows without bound, so the block shows its tail and says what it is
|
|
2728
|
+
* hiding rather than clipping silently; the hidden note costs one row of the
|
|
2729
|
+
* budget itself. Sizes are in whatever unit the caller budgets in (the panel uses
|
|
2730
|
+
* code rows, fractions included, and rounds the total up once).
|
|
2731
|
+
*
|
|
2732
|
+
* @param messages - the whole thread, oldest first.
|
|
2733
|
+
* @param sizeOf - the size one message needs when rendered (text plus its chrome).
|
|
2734
|
+
* @param capRows - the body budget.
|
|
2735
|
+
* @returns the messages to render, the count left out, and the size they need.
|
|
2736
|
+
*/
|
|
2737
|
+
function discussionTail(messages, sizeOf, capRows) {
|
|
2738
|
+
let rows = 0;
|
|
2739
|
+
let keep = 0;
|
|
2740
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
2741
|
+
const size = Math.max(1, sizeOf(messages[index]));
|
|
2742
|
+
const reserve = index > 0 ? 1 : 0;
|
|
2743
|
+
if (keep > 0 && rows + size + reserve > capRows) break;
|
|
2744
|
+
rows += size;
|
|
2745
|
+
keep += 1;
|
|
2746
|
+
}
|
|
2747
|
+
const hidden = messages.length - keep;
|
|
2748
|
+
return {
|
|
2749
|
+
messages: messages.slice(hidden),
|
|
2750
|
+
hidden,
|
|
2751
|
+
rows: rows + (hidden > 0 ? 1 : 0)
|
|
2752
|
+
};
|
|
2753
|
+
}
|
|
2754
|
+
/**
|
|
2755
|
+
* An answer with its blank lines dropped.
|
|
2756
|
+
*
|
|
2757
|
+
* The thread is plain text laid out in code rows, so a blank line between two
|
|
2758
|
+
* paragraphs costs a whole row of height and reads as a gap in the code it
|
|
2759
|
+
* annotates. The prompt asks the agent not to write them; this is what makes a
|
|
2760
|
+
* stray one harmless, and both the render and the row measurement run the answer
|
|
2761
|
+
* through it so the two can never disagree about how tall a turn is. What the user
|
|
2762
|
+
* typed is shown exactly as typed.
|
|
2763
|
+
*
|
|
2764
|
+
* @param text - the answer text.
|
|
2765
|
+
* @returns the same text without empty (or whitespace-only) lines.
|
|
2766
|
+
*/
|
|
2767
|
+
function stripBlankLines(text) {
|
|
2768
|
+
return text.split("\n").filter((line) => line.trim() !== "").join("\n");
|
|
2769
|
+
}
|
|
2770
|
+
/**
|
|
2771
|
+
* The text of one turn as the thread shows it: an answer loses its blank lines, a
|
|
2772
|
+
* first-person turn keeps every one of them.
|
|
2773
|
+
*
|
|
2774
|
+
* @param message - the turn to render.
|
|
2775
|
+
* @returns the text to lay out and to render.
|
|
2776
|
+
*/
|
|
2777
|
+
function discussionText(message) {
|
|
2778
|
+
return message.role === "assistant" ? stripBlankLines(message.text) : message.text;
|
|
2779
|
+
}
|
|
2780
|
+
/**
|
|
2781
|
+
* How many rows a block reserves, so the diff's height table stays exact.
|
|
2782
|
+
* @param discussion - the discussion to measure.
|
|
2783
|
+
* @returns the row count the block contributes.
|
|
2784
|
+
*/
|
|
2785
|
+
function discussionRows(discussion) {
|
|
2786
|
+
if (discussion.collapsed) return 1;
|
|
2787
|
+
return 1 + Math.max(1, discussion.bodyRows ?? 2);
|
|
2788
|
+
}
|
|
2789
|
+
/**
|
|
2790
|
+
* Extra rows to add to each diff row's height: the block hangs below its range's
|
|
2791
|
+
* last row, so a block's rows belong to that row's entry in the height table.
|
|
2792
|
+
* Several blocks on one row sum up.
|
|
2793
|
+
*
|
|
2794
|
+
* @param discussions - the blocks currently attached to this file.
|
|
2795
|
+
* @param rowCount - how many rows the diff has (clamps a stale anchor).
|
|
2796
|
+
* @returns a map from row index to the rows added below it.
|
|
2797
|
+
*/
|
|
2798
|
+
function discussionRowExtras(discussions, rowCount) {
|
|
2799
|
+
const extras = /* @__PURE__ */ new Map();
|
|
2800
|
+
for (const discussion of discussions) {
|
|
2801
|
+
const last = Math.max(0, Math.min(discussion.anchor.end, Math.max(0, rowCount - 1)));
|
|
2802
|
+
extras.set(last, (extras.get(last) ?? 0) + discussionRows(discussion));
|
|
2803
|
+
}
|
|
2804
|
+
return extras;
|
|
2805
|
+
}
|
|
2806
|
+
/**
|
|
2807
|
+
* The discussion that already covers any part of this range. A row belongs to one
|
|
2808
|
+
* annotation at most, so a selection that touches an existing block offers no
|
|
2809
|
+
* second one - otherwise two blocks would describe the same line.
|
|
2810
|
+
*
|
|
2811
|
+
* @param discussions - the blocks currently attached to this file.
|
|
2812
|
+
* @param anchor - the candidate range.
|
|
2813
|
+
* @returns the overlapping discussion, or `undefined`.
|
|
2814
|
+
*/
|
|
2815
|
+
function discussionOverlapping(discussions, anchor) {
|
|
2816
|
+
return discussions.find((entry) => entry.anchor.start <= anchor.end && anchor.start <= entry.anchor.end);
|
|
2817
|
+
}
|
|
2818
|
+
/**
|
|
2819
|
+
* Re-anchor one discussion against the current rows: the rows whose new-file line
|
|
2820
|
+
* falls inside the annotation's line range. When no line matches any more, the
|
|
2821
|
+
* block keeps the rows it last matched and is marked lost, so it stays where the
|
|
2822
|
+
* user last saw it and can only be deleted.
|
|
2823
|
+
*
|
|
2824
|
+
* @param discussion - the block to re-anchor.
|
|
2825
|
+
* @param lineOf - the new-file line number of a row, or `undefined` for a row that has none.
|
|
2826
|
+
* @param rowCount - how many rows the current model has.
|
|
2827
|
+
* @returns the re-anchored discussion (the same object when nothing moved).
|
|
2828
|
+
*/
|
|
2829
|
+
function remapDiscussion(discussion, lineOf, rowCount) {
|
|
2830
|
+
if (discussion.lost === true) return discussion;
|
|
2831
|
+
let start = -1;
|
|
2832
|
+
let end = -1;
|
|
2833
|
+
for (let row = 0; row < rowCount; row++) {
|
|
2834
|
+
const line = lineOf(row);
|
|
2835
|
+
if (line === void 0 || line < discussion.anchor.startLine || line > discussion.anchor.endLine) continue;
|
|
2836
|
+
if (start === -1) start = row;
|
|
2837
|
+
end = row;
|
|
2838
|
+
}
|
|
2839
|
+
if (start === -1) return {
|
|
2840
|
+
...discussion,
|
|
2841
|
+
lost: true
|
|
2842
|
+
};
|
|
2843
|
+
if (start === discussion.anchor.start && end === discussion.anchor.end) return discussion;
|
|
2844
|
+
return {
|
|
2845
|
+
...discussion,
|
|
2846
|
+
anchor: {
|
|
2847
|
+
...discussion.anchor,
|
|
2848
|
+
start,
|
|
2849
|
+
end
|
|
2850
|
+
}
|
|
2851
|
+
};
|
|
2852
|
+
}
|
|
2853
|
+
/**
|
|
2854
|
+
* Decide the selection frame's contents.
|
|
2855
|
+
*
|
|
2856
|
+
* Keep/revert needs covered change blocks; commenting needs a range that has no
|
|
2857
|
+
* discussion yet. A frame with neither would be an empty floating box, so it is
|
|
2858
|
+
* not rendered at all.
|
|
2859
|
+
*
|
|
2860
|
+
* @param options - whether change blocks are covered, and whether this range already has a discussion.
|
|
2861
|
+
* @returns the three flags the caller branches on.
|
|
2862
|
+
*/
|
|
2863
|
+
function selectionFrame(options) {
|
|
2864
|
+
const keepRevert = options.coversBlocks;
|
|
2865
|
+
const comment = !options.hasDiscussion;
|
|
2866
|
+
return {
|
|
2867
|
+
keepRevert,
|
|
2868
|
+
comment,
|
|
2869
|
+
visible: keepRevert || comment
|
|
2870
|
+
};
|
|
2871
|
+
}
|
|
2872
|
+
//#endregion
|
|
2873
|
+
//#region lib/types/client/scroll-follow.js
|
|
2874
|
+
/**
|
|
2875
|
+
* Whether the follow animation can drive the frame, or the render has to place it.
|
|
2876
|
+
*
|
|
2877
|
+
* A scroller with nothing to scroll has an INACTIVE timeline. Measured in a browser: the
|
|
2878
|
+
* animation reports a null current time and its transform is never applied at all, which
|
|
2879
|
+
* left the frame wherever the render had put it — the wrapper's top edge, i.e. the top of
|
|
2880
|
+
* the viewport — on a file short enough that the code does not scroll. There is nothing
|
|
2881
|
+
* to follow in that case either, so the clamp at rest is already exact; the same holds
|
|
2882
|
+
* before the box has been measured, and where the browser has no scroll timelines.
|
|
2883
|
+
*
|
|
2884
|
+
* @param hasTimeline - whether the browser supports scroll-driven animations.
|
|
2885
|
+
* @param viewportHeight - the scroller's client height (0 before it is measured).
|
|
2886
|
+
* @param maxScroll - the scroller's maximum `scrollTop` (0 when it does not scroll).
|
|
2887
|
+
* @returns whether the animation, rather than the render, places the frame.
|
|
2888
|
+
*/
|
|
2889
|
+
function frameFollowIsAnimated(hasTimeline, viewportHeight, maxScroll) {
|
|
2890
|
+
return hasTimeline && viewportHeight > 0 && maxScroll > 0;
|
|
2891
|
+
}
|
|
2892
|
+
/**
|
|
2893
|
+
* The floating action frame's vertical position, as scroll-driven keyframes.
|
|
2894
|
+
*
|
|
2895
|
+
* The frame follows the row its anchor ends on — a point in the scroller's CONTENT
|
|
2896
|
+
* coordinates — and is clamped into the visible area, so that it stays clickable when
|
|
2897
|
+
* that row is off-screen. Written the direct way ("read `scrollTop`, subtract, clamp")
|
|
2898
|
+
* it has to be recomputed on the main thread for every scroll event, which leaves it a
|
|
2899
|
+
* frame behind the code the compositor has already moved. The same clamp expressed as
|
|
2900
|
+
* keyframes over the scroll range becomes a scroll-driven animation, which the browser
|
|
2901
|
+
* runs off the main thread: the code and the frame never disagree about the offset.
|
|
2902
|
+
*
|
|
2903
|
+
* The clamp is piecewise linear in the scroll offset, with exactly two corners — where
|
|
2904
|
+
* the frame stops being held down by the viewport's bottom edge, and where it reaches
|
|
2905
|
+
* the viewport's top edge and stays there — so listing those stops makes the animation
|
|
2906
|
+
* reproduce it exactly, not approximately.
|
|
2907
|
+
*
|
|
2908
|
+
* @param anchorTop - the anchor's offset in the scroller's content, in px.
|
|
2909
|
+
* @param maxScroll - the scroller's maximum `scrollTop` (0 when it does not scroll).
|
|
2910
|
+
* @param viewportHeight - the scroller's client height, in px.
|
|
2911
|
+
* @param frameHeight - the frame's own height, which the clamp has to keep on screen.
|
|
2912
|
+
* @returns the keyframe stops: `offset` is the scroll progress (0-1) and `y` the frame's
|
|
2913
|
+
* position in px from the viewport's top. Ascending, deduplicated, and including the
|
|
2914
|
+
* corners; with nothing to scroll there is a single stop, the clamp being constant.
|
|
2915
|
+
*/
|
|
2916
|
+
function frameFollowKeyframes(anchorTop, maxScroll, viewportHeight, frameHeight) {
|
|
2917
|
+
const limit = Math.max(0, viewportHeight - frameHeight);
|
|
2918
|
+
const at = (progress) => Math.min(limit, Math.max(0, anchorTop - progress * maxScroll));
|
|
2919
|
+
if (maxScroll <= 0) return [{
|
|
2920
|
+
offset: 0,
|
|
2921
|
+
y: at(0)
|
|
2922
|
+
}];
|
|
2923
|
+
const offsets = [
|
|
2924
|
+
0,
|
|
2925
|
+
(anchorTop - limit) / maxScroll,
|
|
2926
|
+
anchorTop / maxScroll,
|
|
2927
|
+
1
|
|
2928
|
+
].filter((offset) => offset >= 0 && offset <= 1);
|
|
2929
|
+
return [...new Set(offsets)].sort((left, right) => left - right).map((offset) => ({
|
|
2930
|
+
offset,
|
|
2931
|
+
y: at(offset)
|
|
2932
|
+
}));
|
|
2933
|
+
}
|
|
2686
2934
|
//#endregion
|
|
2687
2935
|
//#region node_modules/.pnpm/marked@18.0.11/node_modules/marked/lib/marked.esm.js
|
|
2688
2936
|
/**
|
|
@@ -19188,6 +19436,9 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
19188
19436
|
* scrollbar strip stays clear). */
|
|
19189
19437
|
const FLOAT_GRIP_WIDTH_PX = 9;
|
|
19190
19438
|
const FLOAT_GRIP_OVERHANG_PX = 3;
|
|
19439
|
+
/** How long the floating file list takes to fold away once it is put back — the
|
|
19440
|
+
* `fileListShrink` animation's duration, which the panel holds the card for. */
|
|
19441
|
+
const FILE_LIST_FOLD_MS = 140;
|
|
19191
19442
|
/** Normalize a path for comparison: forward slashes, no trailing slash. */
|
|
19192
19443
|
function normalizeDiffPath(p) {
|
|
19193
19444
|
return p.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
@@ -19285,8 +19536,32 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
19285
19536
|
})] })]
|
|
19286
19537
|
});
|
|
19287
19538
|
}
|
|
19539
|
+
/** Return/enter glyph for the comment button: the key's own corner arrow, drawn on
|
|
19540
|
+
* MarkdownModeIcon's 14-grid so the two read at the same weight. It is what tells
|
|
19541
|
+
* the user that Enter sends the comment, without spending a row on the hint. */
|
|
19542
|
+
function ReturnIcon({ size = 12 }) {
|
|
19543
|
+
return (0, react_jsx_runtime.jsxs)("svg", {
|
|
19544
|
+
width: size,
|
|
19545
|
+
height: size,
|
|
19546
|
+
viewBox: "0 0 14 14",
|
|
19547
|
+
fill: "none",
|
|
19548
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
19549
|
+
"aria-hidden": "true",
|
|
19550
|
+
children: [(0, react_jsx_runtime.jsx)("path", {
|
|
19551
|
+
d: "M11.5 3.5 H4.5 V10.5",
|
|
19552
|
+
stroke: "currentColor",
|
|
19553
|
+
strokeWidth: "1.2",
|
|
19554
|
+
fill: "none"
|
|
19555
|
+
}), (0, react_jsx_runtime.jsx)("path", {
|
|
19556
|
+
d: "M2.5 8.5 L4.5 10.5 L6.5 8.5",
|
|
19557
|
+
stroke: "currentColor",
|
|
19558
|
+
strokeWidth: "1.2",
|
|
19559
|
+
fill: "none"
|
|
19560
|
+
})]
|
|
19561
|
+
});
|
|
19562
|
+
}
|
|
19288
19563
|
/** Total width of the two line-number gutters, subtracted from the code width
|
|
19289
|
-
*
|
|
19564
|
+
* when measuring wrapped line heights. */
|
|
19290
19565
|
const WRAP_GUTTERS_PX = 88;
|
|
19291
19566
|
/** How long a requested dock may take to actually show the panel before the
|
|
19292
19567
|
* overlay steps in. The tab body mounts a frame or two after the ask, so the
|
|
@@ -19424,11 +19699,27 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
19424
19699
|
if (font !== void 0) ctx.font = font;
|
|
19425
19700
|
return (text) => ctx.measureText(text).width;
|
|
19426
19701
|
}
|
|
19702
|
+
/** How long a question the session has let go stays "queued" before the block hands
|
|
19703
|
+
* its writing row back. The local submission echo and the host's queue row are a
|
|
19704
|
+
* round trip apart, so releasing on the first idle notification would take the row
|
|
19705
|
+
* back while the prompt is still on its way. */
|
|
19706
|
+
const DISCUSSION_RELEASE_GRACE_MS = 2500;
|
|
19427
19707
|
/** The overview ruler's width in px (mirrors `.overviewRuler`). The flash is
|
|
19428
19708
|
* kept off it even when the scroller has no vertical scrollbar. */
|
|
19429
19709
|
const OVERVIEW_RULER_WIDTH_PX = 4;
|
|
19710
|
+
/** The cap on a user bubble, as a share of the thread's width (mirrors
|
|
19711
|
+
* `.discussionUser`'s `max-width`, which is the chat's own `.userStack` cap). The
|
|
19712
|
+
* wrap measurement has to know it, since the bubble wraps at its cap, not at the
|
|
19713
|
+
* width of the block. */
|
|
19714
|
+
const DISCUSSION_BUBBLE_MAX_WIDTH = .82;
|
|
19715
|
+
/** The bubble's horizontal padding, as a share of a code row (mirrors
|
|
19716
|
+
* `.discussionUser`): its own 0.5 per side, and no margin outside it, so the fill is
|
|
19717
|
+
* flush with the thread's right column and this is what comes off the wrap width. */
|
|
19718
|
+
const DISCUSSION_BUBBLE_SIDE_PADDING_ROWS = .5;
|
|
19430
19719
|
/** Rows rendered beyond the visible window in each direction. */
|
|
19431
19720
|
const OVERSCAN_ROWS = 8;
|
|
19721
|
+
/** The identity a file with no discussions shares, so memos stay stable. */
|
|
19722
|
+
const EMPTY_DISCUSSIONS = [];
|
|
19432
19723
|
/** Height of the floating per-block Keep/Revert frame in px: 26px actions +
|
|
19433
19724
|
* 5px frame padding on each side + 1px border on each side, plus a little
|
|
19434
19725
|
* breathing room so the bottom padding never sits flush against it. */
|
|
@@ -19785,7 +20076,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
19785
20076
|
* is `wrappedLines.length * 22` by construction.
|
|
19786
20077
|
*/
|
|
19787
20078
|
const DiffRow = (0, react.memo)(function DiffRow(props) {
|
|
19788
|
-
const { index, row, runs, focused, searchHit, searchCurrent, searchQuery, searchOptions, onRowHover, wrappedLines } = props;
|
|
20079
|
+
const { index, row, runs, focused, discussed, searchHit, searchCurrent, searchQuery, searchOptions, onRowHover, wrappedLines } = props;
|
|
19789
20080
|
const lineNumber = row.kind === "del" ? row.oldLine : row.newLine;
|
|
19790
20081
|
const sideRuns = row.kind === "del" ? runs?.oldRuns : runs?.newRuns;
|
|
19791
20082
|
const lineRuns = lineNumber === void 0 ? void 0 : sideRuns?.[lineNumber - 1];
|
|
@@ -19804,9 +20095,10 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
19804
20095
|
});
|
|
19805
20096
|
}
|
|
19806
20097
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
19807
|
-
className: `${PendingPanel_module_css_default.line} ${ROW_CLASS[row.kind]}`,
|
|
20098
|
+
className: `${PendingPanel_module_css_default.line} ${ROW_CLASS[row.kind]}${discussed ? ` ${PendingPanel_module_css_default.rowDiscussed}` : ""}`,
|
|
19808
20099
|
"data-diff-line": row.kind,
|
|
19809
20100
|
"data-diff-row": index,
|
|
20101
|
+
"data-diff-discussion-band": discussed ? "" : void 0,
|
|
19810
20102
|
"data-diff-focused": focused ? "" : void 0,
|
|
19811
20103
|
"data-diff-search": searchHit ? searchCurrent ? "current" : "hit" : void 0,
|
|
19812
20104
|
onMouseEnter: () => {
|
|
@@ -20830,6 +21122,23 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20830
21122
|
};
|
|
20831
21123
|
}
|
|
20832
21124
|
/**
|
|
21125
|
+
* Convert row-run ruler markers to the preview's fraction-of-rows shape. The
|
|
21126
|
+
* preview has no discussion blocks (they are a code-view feature), so a fraction
|
|
21127
|
+
* of the row count is exact there and stays the cheap conversion.
|
|
21128
|
+
*
|
|
21129
|
+
* @param markers - row runs, as the shared computation returns them.
|
|
21130
|
+
* @param rowCount - how many rows the diff has.
|
|
21131
|
+
* @returns markers positioned as percentages of the row count.
|
|
21132
|
+
*/
|
|
21133
|
+
function previewRulerMarkersOf(markers, rowCount) {
|
|
21134
|
+
if (rowCount === 0) return [];
|
|
21135
|
+
return markers.map((marker) => ({
|
|
21136
|
+
top: marker.start / rowCount * 100,
|
|
21137
|
+
height: (marker.end - marker.start + 1) / rowCount * 100,
|
|
21138
|
+
kind: marker.kind
|
|
21139
|
+
}));
|
|
21140
|
+
}
|
|
21141
|
+
/**
|
|
20833
21142
|
* Measure the single-column preview's change blocks to position its ruler
|
|
20834
21143
|
* markers by RENDERED height, so a tall block (an inline image, a large code
|
|
20835
21144
|
* fence) is not miscounted by source-line fractions. `offsetTop`/`offsetHeight`
|
|
@@ -20901,7 +21210,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20901
21210
|
});
|
|
20902
21211
|
}
|
|
20903
21212
|
/** The selected file's diff, actions, jump controls, and copy toolbar. */
|
|
20904
|
-
function PendingDiff({ file, busy, workspacePath, jumpSignal, undoFlash, landingTop, landingTick, failedMessage, onPasteReference, onToast, t, onKeep, onRevert, onRefreshVcs, onBlockKeep, onBlockRevert, onOpen, onPreviewImage }) {
|
|
21213
|
+
function PendingDiff({ file, busy, workspacePath, jumpSignal, undoFlash, landingTop, landingTick, failedMessage, commentSkill, onPasteReference, onAskAgent, watchChat, onToast, t, onKeep, onRevert, onRefreshVcs, onBlockKeep, onBlockRevert, onOpen, onPreviewImage }) {
|
|
20905
21214
|
const [langOverride, setLangOverride] = (0, react.useState)(void 0);
|
|
20906
21215
|
const [langMenuOpen, setLangMenuOpen] = (0, react.useState)(false);
|
|
20907
21216
|
const langMenuItems = (0, react.useMemo)(() => [{
|
|
@@ -20986,16 +21295,14 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20986
21295
|
]);
|
|
20987
21296
|
const rulerMarkers = (0, react.useMemo)(() => {
|
|
20988
21297
|
const rows = model.diff.rows;
|
|
20989
|
-
|
|
20990
|
-
if (total === 0) return [];
|
|
21298
|
+
if (rows.length === 0) return [];
|
|
20991
21299
|
const markers = [];
|
|
20992
21300
|
let runStart = -1;
|
|
20993
21301
|
let runKind = "del";
|
|
20994
21302
|
const flush = (end) => {
|
|
20995
|
-
const span = end - runStart + 1;
|
|
20996
21303
|
markers.push({
|
|
20997
|
-
|
|
20998
|
-
|
|
21304
|
+
start: runStart,
|
|
21305
|
+
end,
|
|
20999
21306
|
kind: runKind
|
|
21000
21307
|
});
|
|
21001
21308
|
};
|
|
@@ -21024,7 +21331,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21024
21331
|
const body = mdPreviewBodyRef.current;
|
|
21025
21332
|
if (body === null) return;
|
|
21026
21333
|
const measured = markdownPreviewMarkers(body);
|
|
21027
|
-
setMdRulerMarkers(measured.length > 0 ? measured : rulerMarkers);
|
|
21334
|
+
setMdRulerMarkers(measured.length > 0 ? measured : previewRulerMarkersOf(rulerMarkers, model.diff.rows.length));
|
|
21028
21335
|
}, [
|
|
21029
21336
|
previewActive,
|
|
21030
21337
|
splitView,
|
|
@@ -21046,6 +21353,10 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21046
21353
|
]);
|
|
21047
21354
|
const [splitVisible, setSplitVisible] = (0, react.useState)(void 0);
|
|
21048
21355
|
const bodyRef = (0, react.useRef)(null);
|
|
21356
|
+
/** The scroll box's non-scrolling parent, which carries the chrome painted over
|
|
21357
|
+
* it (discussion blocks, action frames, the search bar) — see the wheel effect. */
|
|
21358
|
+
const bodyWrapRef = (0, react.useRef)(null);
|
|
21359
|
+
const frameRef = (0, react.useRef)(null);
|
|
21049
21360
|
const [focus, setFocus] = (0, react.useState)(0);
|
|
21050
21361
|
const [scrollTick, setScrollTick] = (0, react.useState)(0);
|
|
21051
21362
|
const [scrollTop, setScrollTop] = (0, react.useState)(0);
|
|
@@ -21054,6 +21365,47 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21054
21365
|
const [hScrollbarPx, setHScrollbarPx] = (0, react.useState)(0);
|
|
21055
21366
|
const [hoveredBlock, setHoveredBlock] = (0, react.useState)(void 0);
|
|
21056
21367
|
const [selection, setSelection] = (0, react.useState)(void 0);
|
|
21368
|
+
const [commentMode, setCommentMode] = (0, react.useState)(commentModeEnabled);
|
|
21369
|
+
const [discussionsByFile, setDiscussionsByFile] = (0, react.useState)({});
|
|
21370
|
+
const discussions = discussionsByFile[file.id] ?? EMPTY_DISCUSSIONS;
|
|
21371
|
+
const setDiscussions = (update) => {
|
|
21372
|
+
setDiscussionsByFile((all) => ({
|
|
21373
|
+
...all,
|
|
21374
|
+
[file.id]: update(all[file.id] ?? EMPTY_DISCUSSIONS)
|
|
21375
|
+
}));
|
|
21376
|
+
};
|
|
21377
|
+
/** Which block's overflow menu is open, if any. */
|
|
21378
|
+
const [discussionMenuFor, setDiscussionMenuFor] = (0, react.useState)(void 0);
|
|
21379
|
+
const discussionMenuItems = (0, react.useMemo)(() => [{
|
|
21380
|
+
id: "delete",
|
|
21381
|
+
label: t("action.delete")
|
|
21382
|
+
}], [t]);
|
|
21383
|
+
/** The session's chat, watched so a discussion can show the answer it asked for. */
|
|
21384
|
+
const [chat, setChat] = (0, react.useState)({
|
|
21385
|
+
running: false,
|
|
21386
|
+
nodes: [],
|
|
21387
|
+
partial: "",
|
|
21388
|
+
error: void 0,
|
|
21389
|
+
queued: void 0
|
|
21390
|
+
});
|
|
21391
|
+
/** The same view, readable from a timer callback (which closes over nothing fresh). */
|
|
21392
|
+
const chatRef = (0, react.useRef)(chat);
|
|
21393
|
+
chatRef.current = chat;
|
|
21394
|
+
/** The armed "the session let our prompt go" release, if any. */
|
|
21395
|
+
const releaseTimerRef = (0, react.useRef)(void 0);
|
|
21396
|
+
/** The discussion waiting for an answer, and the transcript length it started at. */
|
|
21397
|
+
const pendingAskRef = (0, react.useRef)(void 0);
|
|
21398
|
+
/** The compose inputs, so a freshly created block can take the caret. */
|
|
21399
|
+
const discussionInputEls = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
21400
|
+
/** The block whose input should be focused once it is on screen. */
|
|
21401
|
+
const focusPendingRef = (0, react.useRef)(void 0);
|
|
21402
|
+
/**
|
|
21403
|
+
* The block whose input should take the caret back when the compose row returns
|
|
21404
|
+
* after a send. The row is gone while the turn runs, so the caret has nowhere to
|
|
21405
|
+
* live; this is cleared by the first thing the user does anywhere, because that
|
|
21406
|
+
* means they moved on and the caret is not ours to move again.
|
|
21407
|
+
*/
|
|
21408
|
+
const discussionRefocusRef = (0, react.useRef)(void 0);
|
|
21057
21409
|
const [previewFrame, setPreviewFrame] = (0, react.useState)(void 0);
|
|
21058
21410
|
const [previewCovered, setPreviewCovered] = (0, react.useState)([]);
|
|
21059
21411
|
const [previewSelectionFrame, setPreviewSelectionFrame] = (0, react.useState)(void 0);
|
|
@@ -21586,15 +21938,133 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21586
21938
|
const tabPx = tabWidthSpaces * measure(" ");
|
|
21587
21939
|
return rows.map((row) => wrapInto(row.text, wrapping, measure, tabPx));
|
|
21588
21940
|
}, [
|
|
21589
|
-
langWrap,
|
|
21941
|
+
langWrap,
|
|
21942
|
+
bodyWidth,
|
|
21943
|
+
rows,
|
|
21944
|
+
tabWidthSpaces
|
|
21945
|
+
]);
|
|
21946
|
+
const discussionRightInsetPx = (() => {
|
|
21947
|
+
const scroller = bodyRef.current;
|
|
21948
|
+
if (scroller === null) return OVERVIEW_RULER_WIDTH_PX;
|
|
21949
|
+
return scroller.offsetWidth - scroller.clientWidth > 0 ? 0 : OVERVIEW_RULER_WIDTH_PX;
|
|
21950
|
+
})();
|
|
21951
|
+
/**
|
|
21952
|
+
* How many code rows one message occupies when the block renders it, at the code's
|
|
21953
|
+
* own font and the width that turn actually gets — the same canvas measurement the
|
|
21954
|
+
* diff's own wrap mode uses, so the block's height stays exact and the last line is
|
|
21955
|
+
* never clipped. A bubble's own padding counts too: half a row above and below add
|
|
21956
|
+
* up to a whole one.
|
|
21957
|
+
*
|
|
21958
|
+
* @param text - the message text.
|
|
21959
|
+
* @param role - who said it: the two sides wrap at different widths.
|
|
21960
|
+
* @returns the occupied row count (whole: a bubble's chrome is a whole row).
|
|
21961
|
+
*/
|
|
21962
|
+
const messageRowsOf = (0, react.useCallback)((text, role) => {
|
|
21963
|
+
const lines = text.split("\n");
|
|
21964
|
+
const bubble = role === "user";
|
|
21965
|
+
const chrome = bubble ? 1 : 0;
|
|
21966
|
+
const measure = makeMeasurer(codeFontOf());
|
|
21967
|
+
if (measure === void 0 || bodyWidth === 0) return lines.length + chrome;
|
|
21968
|
+
const body = Math.max(0, bodyWidth - discussionRightInsetPx - 3 - 24);
|
|
21969
|
+
const wrapping = (bubble ? body * DISCUSSION_BUBBLE_MAX_WIDTH - 2 * DISCUSSION_BUBBLE_SIDE_PADDING_ROWS * ROW_HEIGHT_PX : body) - measure("0");
|
|
21970
|
+
if (wrapping <= 0) return lines.length + chrome;
|
|
21971
|
+
const tabPx = tabWidthSpaces * measure(" ");
|
|
21972
|
+
return chrome + lines.reduce((rows, line) => rows + Math.max(1, wrapInto(line, wrapping, measure, tabPx).length), 0);
|
|
21973
|
+
}, [
|
|
21590
21974
|
bodyWidth,
|
|
21591
|
-
|
|
21592
|
-
|
|
21975
|
+
tabWidthSpaces,
|
|
21976
|
+
discussionRightInsetPx
|
|
21593
21977
|
]);
|
|
21978
|
+
/**
|
|
21979
|
+
* The size one rendered message needs in code rows: its wrapped lines plus its own
|
|
21980
|
+
* padding — which for a bubble is exactly one row (half a row above, half below).
|
|
21981
|
+
* Every turn is therefore a whole number of rows and the thread stays on the code's
|
|
21982
|
+
* own grid.
|
|
21983
|
+
*
|
|
21984
|
+
* @param message - the message to size.
|
|
21985
|
+
* @returns its size in code rows.
|
|
21986
|
+
*/
|
|
21987
|
+
const messageSizeOf = (0, react.useCallback)((message) => {
|
|
21988
|
+
return messageRowsOf(discussionText(message), message.role);
|
|
21989
|
+
}, [messageRowsOf]);
|
|
21990
|
+
/**
|
|
21991
|
+
* The thread as the block will render it, plus the body height that follows from
|
|
21992
|
+
* it: the newest turns that fit the cap, an optional "older" note, the answer in
|
|
21993
|
+
* flight (or the failure note), and the compose row the user writes in.
|
|
21994
|
+
*
|
|
21995
|
+
* @param discussion - the block to lay out.
|
|
21996
|
+
* @returns the messages to render, the hidden count, and the body height.
|
|
21997
|
+
*/
|
|
21998
|
+
const layoutDiscussion = (0, react.useCallback)((discussion) => {
|
|
21999
|
+
const answer = discussion.reply === void 0 ? void 0 : stripBlankLines(discussion.reply);
|
|
22000
|
+
const stoppedNote = discussion.stopped === true && (answer === void 0 || answer === "") && discussion.failed !== true;
|
|
22001
|
+
const trailing = discussion.lost === true ? 1 : answer !== void 0 && answer !== "" ? messageSizeOf({
|
|
22002
|
+
role: "assistant",
|
|
22003
|
+
text: answer
|
|
22004
|
+
}) : discussion.failed === true || discussion.asking === true ? 1 : 2 + (stoppedNote ? 1 : 0);
|
|
22005
|
+
const tailCap = 12 - trailing - (discussion.lost === true ? 1 : 0);
|
|
22006
|
+
const tail = discussionTail(discussion.messages, messageSizeOf, Math.max(1, tailCap));
|
|
22007
|
+
return {
|
|
22008
|
+
messages: tail.messages,
|
|
22009
|
+
hidden: tail.hidden,
|
|
22010
|
+
rows: Math.ceil(tail.rows + trailing)
|
|
22011
|
+
};
|
|
22012
|
+
}, [messageSizeOf]);
|
|
22013
|
+
/**
|
|
22014
|
+
* The discussions as the render will draw them: the body height the measurement
|
|
22015
|
+
* above arrived at, the turns it kept, and the text those turns actually show.
|
|
22016
|
+
* The text goes through `discussionText` here as well as in the measurement, so
|
|
22017
|
+
* an answer with a blank line is drawn without one AND counted without one — the
|
|
22018
|
+
* two can never disagree (see `stripBlankLines`).
|
|
22019
|
+
*/
|
|
22020
|
+
const laidDiscussions = (0, react.useMemo)(() => discussions.map((discussion) => {
|
|
22021
|
+
const laid = layoutDiscussion(discussion);
|
|
22022
|
+
return {
|
|
22023
|
+
...discussion,
|
|
22024
|
+
bodyRows: laid.rows,
|
|
22025
|
+
hidden: laid.hidden,
|
|
22026
|
+
messages: laid.messages.map((message) => ({
|
|
22027
|
+
...message,
|
|
22028
|
+
text: discussionText(message)
|
|
22029
|
+
})),
|
|
22030
|
+
...discussion.reply === void 0 ? {} : { reply: stripBlankLines(discussion.reply) }
|
|
22031
|
+
};
|
|
22032
|
+
}), [discussions, layoutDiscussion]);
|
|
22033
|
+
const discussionExtras = (0, react.useMemo)(() => discussionRowExtras(laidDiscussions, rows.length), [laidDiscussions, rows.length]);
|
|
22034
|
+
const discussionsAtRow = (0, react.useMemo)(() => {
|
|
22035
|
+
const byRow = /* @__PURE__ */ new Map();
|
|
22036
|
+
for (const discussion of laidDiscussions) {
|
|
22037
|
+
const row = Math.max(0, Math.min(discussion.anchor.end, Math.max(0, rows.length - 1)));
|
|
22038
|
+
const list = byRow.get(row);
|
|
22039
|
+
if (list === void 0) byRow.set(row, [discussion]);
|
|
22040
|
+
else list.push(discussion);
|
|
22041
|
+
}
|
|
22042
|
+
return byRow;
|
|
22043
|
+
}, [laidDiscussions, rows.length]);
|
|
22044
|
+
/**
|
|
22045
|
+
* The rows a discussion annotates. They carry their own wash, so the mark scrolls with
|
|
22046
|
+
* the code in both axes with no positioning at all — the overlay this replaces had to
|
|
22047
|
+
* be counter-translated on every horizontal scroll and trailed the text.
|
|
22048
|
+
*/
|
|
22049
|
+
const discussedRows = (0, react.useMemo)(() => {
|
|
22050
|
+
const set = /* @__PURE__ */ new Set();
|
|
22051
|
+
for (const discussion of laidDiscussions) for (let row = Math.max(0, discussion.anchor.start); row <= Math.min(discussion.anchor.end, rowCount - 1); row++) set.add(row);
|
|
22052
|
+
return set;
|
|
22053
|
+
}, [laidDiscussions, rowCount]);
|
|
21594
22054
|
const rowHeights = (0, react.useMemo)(() => {
|
|
21595
|
-
|
|
21596
|
-
|
|
21597
|
-
|
|
22055
|
+
const wrapped = rowWrapped === null ? null : rowWrapped.map((lines) => lines.length * ROW_HEIGHT_PX);
|
|
22056
|
+
if (discussionExtras.size === 0) return wrapped;
|
|
22057
|
+
const heights = wrapped === null ? new Array(rows.length).fill(ROW_HEIGHT_PX) : [...wrapped];
|
|
22058
|
+
for (const [after, extra] of discussionExtras) {
|
|
22059
|
+
const index = Math.max(0, Math.min(after, heights.length - 1));
|
|
22060
|
+
heights[index] = (heights[index] ?? ROW_HEIGHT_PX) + extra * ROW_HEIGHT_PX;
|
|
22061
|
+
}
|
|
22062
|
+
return heights;
|
|
22063
|
+
}, [
|
|
22064
|
+
rowWrapped,
|
|
22065
|
+
discussionExtras,
|
|
22066
|
+
rows.length
|
|
22067
|
+
]);
|
|
21598
22068
|
const rowOffsets = (0, react.useMemo)(() => {
|
|
21599
22069
|
if (rowHeights === null) return null;
|
|
21600
22070
|
const offs = new Array(rowHeights.length + 1);
|
|
@@ -21611,6 +22081,377 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21611
22081
|
if (rowOffsets === null) return (to - from + 1) * ROW_HEIGHT_PX;
|
|
21612
22082
|
return Math.max(0, offsetOf(to + 1) - offsetOf(from));
|
|
21613
22083
|
};
|
|
22084
|
+
/**
|
|
22085
|
+
* Whether the height table carries measured (wrapped) row heights. It is the
|
|
22086
|
+
* signal the landing effect waits for; a discussion's reserved rows are a table
|
|
22087
|
+
* of their own and must not read as "the measurement just became ready".
|
|
22088
|
+
*/
|
|
22089
|
+
const offsetsFromWrap = rowWrapped !== null;
|
|
22090
|
+
const rulerMarkersNow = totalHeight <= 0 ? [] : rowOffsets === null ? previewRulerMarkersOf(rulerMarkers, rowCount) : rulerMarkers.map((marker) => ({
|
|
22091
|
+
top: offsetOf(marker.start) / totalHeight * 100,
|
|
22092
|
+
height: (offsetOf(marker.end + 1) - offsetOf(marker.start)) / totalHeight * 100,
|
|
22093
|
+
kind: marker.kind
|
|
22094
|
+
}));
|
|
22095
|
+
const pendingScrollShiftRef = (0, react.useRef)(0);
|
|
22096
|
+
(0, react.useLayoutEffect)(() => {
|
|
22097
|
+
const shift = pendingScrollShiftRef.current;
|
|
22098
|
+
pendingScrollShiftRef.current = 0;
|
|
22099
|
+
const body = bodyRef.current;
|
|
22100
|
+
if (shift === 0 || body === null) return;
|
|
22101
|
+
body.scrollTop += shift;
|
|
22102
|
+
setScrollTop(body.scrollTop);
|
|
22103
|
+
}, [discussions]);
|
|
22104
|
+
/** Patch one discussion in place, without touching the others or the file key. */
|
|
22105
|
+
const updateDiscussion = (0, react.useCallback)((id, patch) => {
|
|
22106
|
+
setDiscussionsByFile((all) => {
|
|
22107
|
+
const list = all[file.id] ?? EMPTY_DISCUSSIONS;
|
|
22108
|
+
return {
|
|
22109
|
+
...all,
|
|
22110
|
+
[file.id]: list.map((entry) => entry.id === id ? {
|
|
22111
|
+
...entry,
|
|
22112
|
+
...patch
|
|
22113
|
+
} : entry)
|
|
22114
|
+
};
|
|
22115
|
+
});
|
|
22116
|
+
}, [file.id]);
|
|
22117
|
+
const watchChatRef = (0, react.useRef)(watchChat);
|
|
22118
|
+
watchChatRef.current = watchChat;
|
|
22119
|
+
(0, react.useEffect)(() => {
|
|
22120
|
+
let stop;
|
|
22121
|
+
try {
|
|
22122
|
+
stop = watchChatRef.current(file.sessionId, setChat);
|
|
22123
|
+
} catch {}
|
|
22124
|
+
return () => {
|
|
22125
|
+
stop?.();
|
|
22126
|
+
};
|
|
22127
|
+
}, [file.sessionId]);
|
|
22128
|
+
(0, react.useEffect)(() => {
|
|
22129
|
+
const pending = pendingAskRef.current;
|
|
22130
|
+
if (pending === void 0) return;
|
|
22131
|
+
let asked = -1;
|
|
22132
|
+
for (let index = chat.nodes.length - 1; index >= pending.baseline; index--) {
|
|
22133
|
+
const node = chat.nodes[index];
|
|
22134
|
+
if (node.kind === "user" && node.text.includes(pending.needle)) {
|
|
22135
|
+
asked = index;
|
|
22136
|
+
break;
|
|
22137
|
+
}
|
|
22138
|
+
}
|
|
22139
|
+
const ours = asked >= 0;
|
|
22140
|
+
const held = chat.queued === void 0 ? void 0 : chat.queued.some((text) => text.includes(pending.needle));
|
|
22141
|
+
let segmentEnd = chat.nodes.length;
|
|
22142
|
+
for (let index = Math.max(0, asked + 1); index < chat.nodes.length; index++) if (chat.nodes[index]?.kind === "user") {
|
|
22143
|
+
segmentEnd = index;
|
|
22144
|
+
break;
|
|
22145
|
+
}
|
|
22146
|
+
const tail = asked >= 0 ? chat.nodes.slice(asked + 1, segmentEnd) : [];
|
|
22147
|
+
const settled = tail.filter((node) => node.kind === "assistant" && node.text !== "").at(-1)?.text ?? "";
|
|
22148
|
+
const stopped = ours && tail.some((node) => node.kind === "assistant" && node.interrupted === true);
|
|
22149
|
+
const closeOut = () => {
|
|
22150
|
+
const current = pendingAskRef.current;
|
|
22151
|
+
if (current === void 0 || current.id !== pending.id) return;
|
|
22152
|
+
const view = chatRef.current;
|
|
22153
|
+
if (view.running) return;
|
|
22154
|
+
let found = -1;
|
|
22155
|
+
for (let index = view.nodes.length - 1; index >= current.baseline; index--) {
|
|
22156
|
+
const node = view.nodes[index];
|
|
22157
|
+
if (node !== void 0 && node.kind === "user" && node.text.includes(current.needle)) {
|
|
22158
|
+
found = index;
|
|
22159
|
+
break;
|
|
22160
|
+
}
|
|
22161
|
+
}
|
|
22162
|
+
if (found < 0) {
|
|
22163
|
+
if (view.queued === void 0 || view.queued.some((text) => text.includes(current.needle))) return;
|
|
22164
|
+
} else if (view.nodes.slice(found + 1).some((node) => node.kind === "assistant" && node.text !== "")) return;
|
|
22165
|
+
pendingAskRef.current = void 0;
|
|
22166
|
+
updateDiscussion(current.id, found >= 0 ? {
|
|
22167
|
+
asking: false,
|
|
22168
|
+
queued: false,
|
|
22169
|
+
failed: false,
|
|
22170
|
+
reply: "",
|
|
22171
|
+
stopped: true
|
|
22172
|
+
} : {
|
|
22173
|
+
asking: false,
|
|
22174
|
+
queued: false,
|
|
22175
|
+
failed: false,
|
|
22176
|
+
reply: ""
|
|
22177
|
+
});
|
|
22178
|
+
};
|
|
22179
|
+
const clearRelease = () => {
|
|
22180
|
+
if (releaseTimerRef.current === void 0) return;
|
|
22181
|
+
window.clearTimeout(releaseTimerRef.current);
|
|
22182
|
+
releaseTimerRef.current = void 0;
|
|
22183
|
+
};
|
|
22184
|
+
/** Arm the one "no answer is coming" timer, if it is not already running. */
|
|
22185
|
+
const armCloseOut = () => {
|
|
22186
|
+
if (releaseTimerRef.current !== void 0) return;
|
|
22187
|
+
releaseTimerRef.current = window.setTimeout(() => {
|
|
22188
|
+
releaseTimerRef.current = void 0;
|
|
22189
|
+
closeOut();
|
|
22190
|
+
}, DISCUSSION_RELEASE_GRACE_MS);
|
|
22191
|
+
};
|
|
22192
|
+
if (chat.error !== void 0) {
|
|
22193
|
+
clearRelease();
|
|
22194
|
+
pendingAskRef.current = void 0;
|
|
22195
|
+
updateDiscussion(pending.id, {
|
|
22196
|
+
asking: false,
|
|
22197
|
+
queued: false,
|
|
22198
|
+
failed: true,
|
|
22199
|
+
reply: ""
|
|
22200
|
+
});
|
|
22201
|
+
return;
|
|
22202
|
+
}
|
|
22203
|
+
if (chat.running) {
|
|
22204
|
+
if (!ours) {
|
|
22205
|
+
updateDiscussion(pending.id, {
|
|
22206
|
+
asking: true,
|
|
22207
|
+
queued: true,
|
|
22208
|
+
failed: false,
|
|
22209
|
+
reply: ""
|
|
22210
|
+
});
|
|
22211
|
+
return;
|
|
22212
|
+
}
|
|
22213
|
+
clearRelease();
|
|
22214
|
+
const streaming = chat.partial !== "" ? chat.partial : settled;
|
|
22215
|
+
if (streaming !== "") updateDiscussion(pending.id, {
|
|
22216
|
+
asking: true,
|
|
22217
|
+
queued: false,
|
|
22218
|
+
failed: false,
|
|
22219
|
+
reply: streaming
|
|
22220
|
+
});
|
|
22221
|
+
return;
|
|
22222
|
+
}
|
|
22223
|
+
if (settled === "") {
|
|
22224
|
+
if (stopped) {
|
|
22225
|
+
clearRelease();
|
|
22226
|
+
closeOut();
|
|
22227
|
+
return;
|
|
22228
|
+
}
|
|
22229
|
+
if (!ours) {
|
|
22230
|
+
if (held === false) armCloseOut();
|
|
22231
|
+
else clearRelease();
|
|
22232
|
+
updateDiscussion(pending.id, {
|
|
22233
|
+
asking: true,
|
|
22234
|
+
queued: true,
|
|
22235
|
+
failed: false,
|
|
22236
|
+
reply: ""
|
|
22237
|
+
});
|
|
22238
|
+
return;
|
|
22239
|
+
}
|
|
22240
|
+
armCloseOut();
|
|
22241
|
+
return;
|
|
22242
|
+
}
|
|
22243
|
+
clearRelease();
|
|
22244
|
+
pendingAskRef.current = void 0;
|
|
22245
|
+
setDiscussionsByFile((all) => {
|
|
22246
|
+
const list = all[file.id] ?? EMPTY_DISCUSSIONS;
|
|
22247
|
+
return {
|
|
22248
|
+
...all,
|
|
22249
|
+
[file.id]: list.map((entry) => entry.id === pending.id ? {
|
|
22250
|
+
...entry,
|
|
22251
|
+
asking: false,
|
|
22252
|
+
queued: false,
|
|
22253
|
+
failed: false,
|
|
22254
|
+
reply: "",
|
|
22255
|
+
stopped,
|
|
22256
|
+
messages: [...entry.messages, {
|
|
22257
|
+
role: "assistant",
|
|
22258
|
+
text: settled
|
|
22259
|
+
}]
|
|
22260
|
+
} : entry)
|
|
22261
|
+
};
|
|
22262
|
+
});
|
|
22263
|
+
}, [
|
|
22264
|
+
chat,
|
|
22265
|
+
updateDiscussion,
|
|
22266
|
+
file.id
|
|
22267
|
+
]);
|
|
22268
|
+
/**
|
|
22269
|
+
* Re-anchor every block whenever the rows are rebuilt (a keep/revert or an edit
|
|
22270
|
+
* rewrites them). The anchor's new-file lines are what survive; a block whose
|
|
22271
|
+
* lines are all gone keeps the rows it last matched and is marked lost, so it
|
|
22272
|
+
* stays where the user last saw it.
|
|
22273
|
+
*/
|
|
22274
|
+
(0, react.useEffect)(() => {
|
|
22275
|
+
setDiscussionsByFile((all) => {
|
|
22276
|
+
const list = all[file.id] ?? EMPTY_DISCUSSIONS;
|
|
22277
|
+
const next = list.map((discussion) => remapDiscussion(discussion, (row) => {
|
|
22278
|
+
const entry = model.diff.rows[row];
|
|
22279
|
+
return entry?.newLine ?? entry?.oldLine;
|
|
22280
|
+
}, model.diff.rows.length));
|
|
22281
|
+
return next.some((discussion, index) => discussion !== list[index]) ? {
|
|
22282
|
+
...all,
|
|
22283
|
+
[file.id]: next
|
|
22284
|
+
} : all;
|
|
22285
|
+
});
|
|
22286
|
+
}, [model, file.id]);
|
|
22287
|
+
(0, react.useEffect)(() => {
|
|
22288
|
+
const fresh = focusPendingRef.current;
|
|
22289
|
+
const id = fresh ?? discussionRefocusRef.current;
|
|
22290
|
+
if (id === void 0) return;
|
|
22291
|
+
const input = discussionInputEls.current.get(id);
|
|
22292
|
+
if (input === void 0) return;
|
|
22293
|
+
if (fresh !== void 0) focusPendingRef.current = void 0;
|
|
22294
|
+
else discussionRefocusRef.current = void 0;
|
|
22295
|
+
input.focus();
|
|
22296
|
+
try {
|
|
22297
|
+
input.setSelectionRange(input.value.length, input.value.length);
|
|
22298
|
+
} catch {}
|
|
22299
|
+
}, [laidDiscussions]);
|
|
22300
|
+
(0, react.useEffect)(() => {
|
|
22301
|
+
const drop = () => {
|
|
22302
|
+
discussionRefocusRef.current = void 0;
|
|
22303
|
+
};
|
|
22304
|
+
document.addEventListener("pointerdown", drop, true);
|
|
22305
|
+
document.addEventListener("keydown", drop, true);
|
|
22306
|
+
return () => {
|
|
22307
|
+
document.removeEventListener("pointerdown", drop, true);
|
|
22308
|
+
document.removeEventListener("keydown", drop, true);
|
|
22309
|
+
};
|
|
22310
|
+
}, []);
|
|
22311
|
+
(0, react.useEffect)(() => {
|
|
22312
|
+
const wrap = bodyWrapRef.current;
|
|
22313
|
+
if (wrap === null) return;
|
|
22314
|
+
const onWheel = (event) => {
|
|
22315
|
+
const body = bodyRef.current;
|
|
22316
|
+
const target = event.target;
|
|
22317
|
+
if (body === null || !(target instanceof Element)) return;
|
|
22318
|
+
if (target.closest("[data-diff-body]") !== null) return;
|
|
22319
|
+
const per = event.deltaMode === 1 ? ROW_HEIGHT_PX : event.deltaMode === 2 ? body.clientHeight : 1;
|
|
22320
|
+
const top = body.scrollTop;
|
|
22321
|
+
const left = body.scrollLeft;
|
|
22322
|
+
body.scrollTop = top + event.deltaY * per;
|
|
22323
|
+
body.scrollLeft = left + event.deltaX * per;
|
|
22324
|
+
if (body.scrollTop !== top || body.scrollLeft !== left) event.preventDefault();
|
|
22325
|
+
};
|
|
22326
|
+
wrap.addEventListener("wheel", onWheel, { passive: false });
|
|
22327
|
+
return () => {
|
|
22328
|
+
wrap.removeEventListener("wheel", onWheel);
|
|
22329
|
+
};
|
|
22330
|
+
}, [ROW_HEIGHT_PX]);
|
|
22331
|
+
/** Start a discussion on the current selection (no-op on a range that has one). */
|
|
22332
|
+
const addDiscussion = () => {
|
|
22333
|
+
if (!commentMode) return;
|
|
22334
|
+
if (selection === void 0) return;
|
|
22335
|
+
if (discussionOverlapping(discussions, selection) !== void 0) return;
|
|
22336
|
+
const first = model.diff.rows[selection.start];
|
|
22337
|
+
const last = model.diff.rows[selection.end] ?? first;
|
|
22338
|
+
const startLine = first?.newLine ?? first?.oldLine;
|
|
22339
|
+
if (startLine === void 0) return;
|
|
22340
|
+
const endLine = last?.newLine ?? last?.oldLine ?? startLine;
|
|
22341
|
+
const body = bodyRef.current;
|
|
22342
|
+
if (body !== null && offsetOf(selection.start) - body.scrollTop < 0) pendingScrollShiftRef.current += 3 * ROW_HEIGHT_PX;
|
|
22343
|
+
const id = `discussion-${Date.now().toString(36)}-${discussions.length}`;
|
|
22344
|
+
setDiscussions((current) => [...current, {
|
|
22345
|
+
id,
|
|
22346
|
+
anchor: {
|
|
22347
|
+
start: selection.start,
|
|
22348
|
+
end: selection.end,
|
|
22349
|
+
startLine,
|
|
22350
|
+
endLine
|
|
22351
|
+
},
|
|
22352
|
+
messages: [],
|
|
22353
|
+
draft: "",
|
|
22354
|
+
collapsed: false
|
|
22355
|
+
}]);
|
|
22356
|
+
focusPendingRef.current = id;
|
|
22357
|
+
const live = window.getSelection();
|
|
22358
|
+
if (typeof live?.removeAllRanges === "function") live.removeAllRanges();
|
|
22359
|
+
selectionTextRef.current = "";
|
|
22360
|
+
setSelection(void 0);
|
|
22361
|
+
};
|
|
22362
|
+
const addDiscussionRef = (0, react.useRef)(addDiscussion);
|
|
22363
|
+
addDiscussionRef.current = addDiscussion;
|
|
22364
|
+
/**
|
|
22365
|
+
* Fold or unfold one block, keeping the code the user is reading in place.
|
|
22366
|
+
* @param id - the block to fold.
|
|
22367
|
+
* @param collapsed - the state to set (defaults to the opposite of the current).
|
|
22368
|
+
*/
|
|
22369
|
+
const setDiscussionCollapsed = (id, collapsed) => {
|
|
22370
|
+
const discussion = discussions.find((entry) => entry.id === id);
|
|
22371
|
+
if (discussion === void 0) return;
|
|
22372
|
+
const next = collapsed ?? !discussion.collapsed;
|
|
22373
|
+
if (next === discussion.collapsed) return;
|
|
22374
|
+
const shift = ((next ? 1 : discussionRows(discussion)) - discussionRows(discussion)) * ROW_HEIGHT_PX;
|
|
22375
|
+
const body = bodyRef.current;
|
|
22376
|
+
if (body !== null && offsetOf(discussion.anchor.start) - body.scrollTop < 0) pendingScrollShiftRef.current += shift;
|
|
22377
|
+
setDiscussions((current) => current.map((entry) => entry.id === id ? {
|
|
22378
|
+
...entry,
|
|
22379
|
+
collapsed: next
|
|
22380
|
+
} : entry));
|
|
22381
|
+
};
|
|
22382
|
+
/** Fold or unfold one block from its header arrow. */
|
|
22383
|
+
const toggleDiscussion = (id) => {
|
|
22384
|
+
setDiscussionCollapsed(id);
|
|
22385
|
+
};
|
|
22386
|
+
/**
|
|
22387
|
+
* Send one turn of a discussion to the agent.
|
|
22388
|
+
*
|
|
22389
|
+
* The first turn is the annotation: the `(path:lines)` reference, the user's
|
|
22390
|
+
* words and the length policy. Later turns are follow-ups in the same thread -
|
|
22391
|
+
* the reference rides along so the agent keeps answering about these rows, and
|
|
22392
|
+
* the answer is appended rather than replacing the previous one. When this build
|
|
22393
|
+
* has no send verb, the text goes to the composer instead (the route the copy
|
|
22394
|
+
* reference already used).
|
|
22395
|
+
*
|
|
22396
|
+
* @param id - the discussion to ask in.
|
|
22397
|
+
*/
|
|
22398
|
+
const sendDiscussion = (id) => {
|
|
22399
|
+
const discussion = discussions.find((entry) => entry.id === id);
|
|
22400
|
+
if (discussion === void 0 || discussion.lost === true) return;
|
|
22401
|
+
const text = discussion.draft.trim();
|
|
22402
|
+
if (text === "") return;
|
|
22403
|
+
const reference = `(${discussionLineRange(discussion.anchor)})`;
|
|
22404
|
+
const marker = `${t("discussion.marker")} ${reference}`;
|
|
22405
|
+
const needle = `${marker}\n${text.split("\n")[0] ?? ""}`;
|
|
22406
|
+
const prompt = `${marker}\n${text}\n\n${commentSkill === void 0 ? t("discussion.promptRule") : t("discussion.promptRuleSkill", { skill: commentSkill })}`;
|
|
22407
|
+
const asked = {
|
|
22408
|
+
role: "user",
|
|
22409
|
+
text
|
|
22410
|
+
};
|
|
22411
|
+
if (!onAskAgent(file.sessionId, prompt)) {
|
|
22412
|
+
onPasteReference(file.sessionId, `${reference}\n${text}`);
|
|
22413
|
+
setDiscussions((current) => current.map((entry) => entry.id === id ? {
|
|
22414
|
+
...entry,
|
|
22415
|
+
messages: [...entry.messages, asked],
|
|
22416
|
+
draft: ""
|
|
22417
|
+
} : entry));
|
|
22418
|
+
return;
|
|
22419
|
+
}
|
|
22420
|
+
pendingAskRef.current = {
|
|
22421
|
+
id,
|
|
22422
|
+
baseline: chat.nodes.length,
|
|
22423
|
+
needle
|
|
22424
|
+
};
|
|
22425
|
+
discussionRefocusRef.current = id;
|
|
22426
|
+
setDiscussions((current) => current.map((entry) => entry.id === id ? {
|
|
22427
|
+
...entry,
|
|
22428
|
+
messages: [...entry.messages, asked],
|
|
22429
|
+
draft: "",
|
|
22430
|
+
asking: true,
|
|
22431
|
+
queued: false,
|
|
22432
|
+
failed: false,
|
|
22433
|
+
reply: "",
|
|
22434
|
+
collapsed: false
|
|
22435
|
+
} : entry));
|
|
22436
|
+
};
|
|
22437
|
+
/** Discard one block, keeping the code the user is reading in place. */
|
|
22438
|
+
const removeDiscussion = (id) => {
|
|
22439
|
+
const discussion = discussions.find((entry) => entry.id === id);
|
|
22440
|
+
if (discussion === void 0) return;
|
|
22441
|
+
const shift = discussionRows(discussion) * ROW_HEIGHT_PX * -1;
|
|
22442
|
+
const body = bodyRef.current;
|
|
22443
|
+
if (body !== null && offsetOf(discussion.anchor.start) - body.scrollTop < 0) pendingScrollShiftRef.current += shift;
|
|
22444
|
+
setDiscussions((current) => current.filter((entry) => entry.id !== id));
|
|
22445
|
+
};
|
|
22446
|
+
/**
|
|
22447
|
+
* The commented rows as a `path:lines` label - the same reference vocabulary the
|
|
22448
|
+
* copy control uses, so a discussion names where it sits in the file. It reads
|
|
22449
|
+
* the stored lines rather than the current rows, so a block whose lines are gone
|
|
22450
|
+
* still says what it was about.
|
|
22451
|
+
* @param anchor - the discussion's anchor.
|
|
22452
|
+
* @returns the reference label.
|
|
22453
|
+
*/
|
|
22454
|
+
const discussionLineRange = (anchor) => referenceLabelOf(file.path, workspacePath, anchor.startLine, anchor.endLine);
|
|
21614
22455
|
const rowAtY = (y) => {
|
|
21615
22456
|
if (rowOffsets === null) return Math.floor(y / ROW_HEIGHT_PX);
|
|
21616
22457
|
if (y <= 0) return 0;
|
|
@@ -21653,15 +22494,17 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21653
22494
|
newRange: splitView ? splitVisible?.newRange : newWindow,
|
|
21654
22495
|
live: splitView ? splitVisible?.live ?? false : viewportHeight > 0
|
|
21655
22496
|
});
|
|
21656
|
-
const
|
|
21657
|
-
const blockActionsTop = blockEnd === void 0 ? 0 : Math.max(0, Math.min(offsetOf(blockEnd + 1) - scrollTop - 2, Math.max(0, viewportHeight - BLOCK_ACTIONS_FRAME_PX)));
|
|
22497
|
+
const hoveredBlockEnd = hoveredBlock === void 0 ? void 0 : model.blocks[hoveredBlock]?.end;
|
|
21658
22498
|
const selectionBlockEnd = (() => {
|
|
21659
|
-
if (coveredBlockIndices.length
|
|
21660
|
-
|
|
21661
|
-
|
|
21662
|
-
|
|
22499
|
+
if (coveredBlockIndices.length > 0) {
|
|
22500
|
+
const lastIndex = coveredBlockIndices[coveredBlockIndices.length - 1];
|
|
22501
|
+
if (lastIndex !== void 0) {
|
|
22502
|
+
const end = model.blocks[lastIndex]?.end;
|
|
22503
|
+
if (end !== void 0) return end;
|
|
22504
|
+
}
|
|
22505
|
+
}
|
|
22506
|
+
return selection?.end;
|
|
21663
22507
|
})();
|
|
21664
|
-
const selectionActionsTop = selectionBlockEnd === void 0 ? 0 : Math.max(0, Math.min(offsetOf(selectionBlockEnd + 1) - scrollTop - 2, Math.max(0, viewportHeight - BLOCK_ACTIONS_FRAME_PX)));
|
|
21665
22508
|
const widestLine = (0, react.useMemo)(() => {
|
|
21666
22509
|
let widest = 0;
|
|
21667
22510
|
for (const row of model.diff.rows) if (row.text.length > widest) widest = row.text.length;
|
|
@@ -21700,7 +22543,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21700
22543
|
}, [
|
|
21701
22544
|
file.id,
|
|
21702
22545
|
langWrap,
|
|
21703
|
-
previewActive
|
|
22546
|
+
previewActive,
|
|
22547
|
+
splitView
|
|
21704
22548
|
]);
|
|
21705
22549
|
(0, react.useLayoutEffect)(() => {
|
|
21706
22550
|
if (rowCount === 0) return;
|
|
@@ -21735,7 +22579,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21735
22579
|
setScrollTop(clamped);
|
|
21736
22580
|
}, [
|
|
21737
22581
|
scrollTick,
|
|
21738
|
-
|
|
22582
|
+
offsetsFromWrap,
|
|
21739
22583
|
previewActive
|
|
21740
22584
|
]);
|
|
21741
22585
|
const wrapArmedRef = (0, react.useRef)(0);
|
|
@@ -21955,6 +22799,34 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21955
22799
|
window.removeEventListener("keydown", onKeyDown, true);
|
|
21956
22800
|
};
|
|
21957
22801
|
}, [copySelection]);
|
|
22802
|
+
(0, react.useEffect)(() => {
|
|
22803
|
+
const onCommentMode = () => {
|
|
22804
|
+
setCommentMode(commentModeEnabled());
|
|
22805
|
+
};
|
|
22806
|
+
window.addEventListener(COMMENT_MODE_CHANGED_EVENT, onCommentMode);
|
|
22807
|
+
return () => {
|
|
22808
|
+
window.removeEventListener(COMMENT_MODE_CHANGED_EVENT, onCommentMode);
|
|
22809
|
+
};
|
|
22810
|
+
}, []);
|
|
22811
|
+
const frameForSelection = !splitView && selection !== void 0 ? selectionFrame({
|
|
22812
|
+
coversBlocks: selectionRange !== void 0,
|
|
22813
|
+
hasDiscussion: discussionOverlapping(discussions, selection) !== void 0
|
|
22814
|
+
}) : void 0;
|
|
22815
|
+
const selectionCommentOffered = commentMode && frameForSelection?.comment === true;
|
|
22816
|
+
const selectionFrameVisible = frameForSelection !== void 0 && (frameForSelection.keepRevert || selectionCommentOffered);
|
|
22817
|
+
(0, react.useEffect)(() => {
|
|
22818
|
+
if (!selectionCommentOffered) return;
|
|
22819
|
+
const onKeyDown = (event) => {
|
|
22820
|
+
if (!matchesShortcut(event, keybindingOf("addComment"))) return;
|
|
22821
|
+
if (isTextFieldEvent(event) || pathPickerOpen()) return;
|
|
22822
|
+
event.preventDefault();
|
|
22823
|
+
addDiscussionRef.current();
|
|
22824
|
+
};
|
|
22825
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
22826
|
+
return () => {
|
|
22827
|
+
window.removeEventListener("keydown", onKeyDown, true);
|
|
22828
|
+
};
|
|
22829
|
+
}, [selectionCommentOffered]);
|
|
21958
22830
|
(0, react.useEffect)(() => {
|
|
21959
22831
|
const onKeyDown = (event) => {
|
|
21960
22832
|
if (!matchesShortcut(event, keybindingOf("openSearch"))) return;
|
|
@@ -22195,6 +23067,35 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22195
23067
|
})
|
|
22196
23068
|
]
|
|
22197
23069
|
}) : null;
|
|
23070
|
+
const frameAnchorEnd = selectionFrameVisible ? selectionBlockEnd : hoveredBlockEnd;
|
|
23071
|
+
const frameAnchorTop = frameAnchorEnd === void 0 ? 0 : offsetOf(frameAnchorEnd + 1) - 2;
|
|
23072
|
+
const frameLimit = Math.max(0, viewportHeight - BLOCK_ACTIONS_FRAME_PX);
|
|
23073
|
+
const maxScroll = Math.max(0, totalHeight - viewportHeight);
|
|
23074
|
+
const frameFollowsScroll = frameFollowIsAnimated(typeof ScrollTimeline !== "undefined", viewportHeight, maxScroll);
|
|
23075
|
+
const frameTop = frameFollowsScroll ? 0 : Math.max(0, Math.min(frameAnchorTop - scrollTop, frameLimit));
|
|
23076
|
+
(0, react.useLayoutEffect)(() => {
|
|
23077
|
+
const element = frameRef.current;
|
|
23078
|
+
const body = bodyRef.current;
|
|
23079
|
+
if (!frameFollowsScroll || frameAnchorEnd === void 0 || element === null || body === null) return;
|
|
23080
|
+
const keyframes = frameFollowKeyframes(frameAnchorTop, maxScroll, viewportHeight, BLOCK_ACTIONS_FRAME_PX).map((stop) => ({
|
|
23081
|
+
offset: stop.offset,
|
|
23082
|
+
transform: `translateY(${stop.y}px)`
|
|
23083
|
+
}));
|
|
23084
|
+
const animation = element.animate(keyframes, {
|
|
23085
|
+
duration: 1e3,
|
|
23086
|
+
fill: "both"
|
|
23087
|
+
});
|
|
23088
|
+
animation.timeline = new ScrollTimeline({ source: body });
|
|
23089
|
+
return () => {
|
|
23090
|
+
animation.cancel();
|
|
23091
|
+
};
|
|
23092
|
+
}, [
|
|
23093
|
+
frameFollowsScroll,
|
|
23094
|
+
frameAnchorEnd,
|
|
23095
|
+
frameAnchorTop,
|
|
23096
|
+
maxScroll,
|
|
23097
|
+
viewportHeight
|
|
23098
|
+
]);
|
|
22198
23099
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
22199
23100
|
className: PendingPanel_module_css_default.diff,
|
|
22200
23101
|
"data-diff-approval-diff": true,
|
|
@@ -22539,6 +23440,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22539
23440
|
onVisibleLines: onSplitVisibleLines
|
|
22540
23441
|
}) : (0, react_jsx_runtime.jsxs)("div", {
|
|
22541
23442
|
className: PendingPanel_module_css_default.diffBodyWrap,
|
|
23443
|
+
ref: bodyWrapRef,
|
|
22542
23444
|
onMouseLeave: () => {
|
|
22543
23445
|
setHoveredBlock(void 0);
|
|
22544
23446
|
},
|
|
@@ -22564,18 +23466,176 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22564
23466
|
}),
|
|
22565
23467
|
visibleRows.map((row, offset) => {
|
|
22566
23468
|
const index = start + offset;
|
|
22567
|
-
|
|
23469
|
+
const blocks = discussionsAtRow.get(index) ?? [];
|
|
23470
|
+
return (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [(0, react_jsx_runtime.jsx)(DiffRow, {
|
|
22568
23471
|
index,
|
|
22569
23472
|
row,
|
|
22570
23473
|
runs,
|
|
22571
23474
|
focused: inFocusedBlock(index),
|
|
23475
|
+
discussed: discussedRows.has(index),
|
|
22572
23476
|
searchHit: searchHitSet.has(index),
|
|
22573
23477
|
searchCurrent: index === currentSearchRow,
|
|
22574
23478
|
searchQuery,
|
|
22575
23479
|
searchOptions: search.options,
|
|
22576
23480
|
onRowHover,
|
|
22577
23481
|
wrappedLines: rowWrapped?.[index]
|
|
22578
|
-
},
|
|
23482
|
+
}), blocks.map((discussion) => {
|
|
23483
|
+
const rows = discussionRows(discussion);
|
|
23484
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
23485
|
+
className: PendingPanel_module_css_default.discussionRow,
|
|
23486
|
+
"data-diff-discussion-space": rows,
|
|
23487
|
+
style: { height: rows * ROW_HEIGHT_PX },
|
|
23488
|
+
children: [
|
|
23489
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
23490
|
+
className: PendingPanel_module_css_default.gutter,
|
|
23491
|
+
"aria-hidden": "true"
|
|
23492
|
+
}),
|
|
23493
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
23494
|
+
className: PendingPanel_module_css_default.gutter,
|
|
23495
|
+
"aria-hidden": "true"
|
|
23496
|
+
}),
|
|
23497
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
23498
|
+
className: PendingPanel_module_css_default.discussionCell,
|
|
23499
|
+
children: (0, react_jsx_runtime.jsx)("div", {
|
|
23500
|
+
className: PendingPanel_module_css_default.discussionPin,
|
|
23501
|
+
style: { marginLeft: -88 },
|
|
23502
|
+
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
23503
|
+
className: PendingPanel_module_css_default.discussion,
|
|
23504
|
+
"data-diff-discussion": true,
|
|
23505
|
+
"data-lost": discussion.lost === true ? "" : void 0,
|
|
23506
|
+
style: {
|
|
23507
|
+
width: Math.max(0, bodyWidth - discussionRightInsetPx),
|
|
23508
|
+
height: rows * ROW_HEIGHT_PX
|
|
23509
|
+
},
|
|
23510
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
23511
|
+
className: PendingPanel_module_css_default.discussionHead,
|
|
23512
|
+
children: [
|
|
23513
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
23514
|
+
type: "button",
|
|
23515
|
+
className: PendingPanel_module_css_default.discussionToggle,
|
|
23516
|
+
"data-diff-discussion-toggle": true,
|
|
23517
|
+
"aria-expanded": !discussion.collapsed,
|
|
23518
|
+
"aria-label": t(discussion.collapsed ? "action.discussionExpand" : "action.discussionCollapse"),
|
|
23519
|
+
onClick: () => {
|
|
23520
|
+
toggleDiscussion(discussion.id);
|
|
23521
|
+
},
|
|
23522
|
+
children: discussion.collapsed ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { size: 12 }) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronUpOutline14, { size: 12 })
|
|
23523
|
+
}),
|
|
23524
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
23525
|
+
className: PendingPanel_module_css_default.discussionRangeWrap,
|
|
23526
|
+
children: (0, react_jsx_runtime.jsx)("span", {
|
|
23527
|
+
className: PendingPanel_module_css_default.discussionRange,
|
|
23528
|
+
"data-diff-discussion-range": true,
|
|
23529
|
+
children: discussionLineRange(discussion.anchor)
|
|
23530
|
+
})
|
|
23531
|
+
}),
|
|
23532
|
+
(0, react_jsx_runtime.jsx)("span", { className: PendingPanel_module_css_default.flexSpacer }),
|
|
23533
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
23534
|
+
open: discussionMenuFor === discussion.id,
|
|
23535
|
+
portal: true,
|
|
23536
|
+
compact: true,
|
|
23537
|
+
align: "end",
|
|
23538
|
+
items: discussionMenuItems,
|
|
23539
|
+
onSelect: (id) => {
|
|
23540
|
+
if (id === "delete") removeDiscussion(discussion.id);
|
|
23541
|
+
setDiscussionMenuFor(void 0);
|
|
23542
|
+
},
|
|
23543
|
+
onClose: () => {
|
|
23544
|
+
setDiscussionMenuFor(void 0);
|
|
23545
|
+
},
|
|
23546
|
+
anchor: (0, react_jsx_runtime.jsx)("button", {
|
|
23547
|
+
type: "button",
|
|
23548
|
+
className: PendingPanel_module_css_default.discussionToggle,
|
|
23549
|
+
"data-diff-discussion-menu": true,
|
|
23550
|
+
"aria-label": t("action.more"),
|
|
23551
|
+
onClick: () => {
|
|
23552
|
+
setDiscussionMenuFor((current) => current === discussion.id ? void 0 : discussion.id);
|
|
23553
|
+
},
|
|
23554
|
+
children: "⋯"
|
|
23555
|
+
})
|
|
23556
|
+
})
|
|
23557
|
+
]
|
|
23558
|
+
}), !discussion.collapsed && (0, react_jsx_runtime.jsxs)("div", {
|
|
23559
|
+
className: PendingPanel_module_css_default.discussionBody,
|
|
23560
|
+
children: [
|
|
23561
|
+
discussion.lost === true && (0, react_jsx_runtime.jsx)("p", {
|
|
23562
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
23563
|
+
"data-diff-discussion-lost": true,
|
|
23564
|
+
children: t("discussion.lost")
|
|
23565
|
+
}),
|
|
23566
|
+
discussion.hidden !== void 0 && discussion.hidden > 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
23567
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
23568
|
+
"data-diff-discussion-hidden": true,
|
|
23569
|
+
children: t("discussion.hidden", { count: discussion.hidden })
|
|
23570
|
+
}),
|
|
23571
|
+
discussion.stopped === true && (discussion.reply === void 0 || discussion.reply === "") && discussion.failed !== true && (0, react_jsx_runtime.jsx)("p", {
|
|
23572
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
23573
|
+
"data-diff-discussion-stopped": true,
|
|
23574
|
+
children: t("discussion.stopped")
|
|
23575
|
+
}),
|
|
23576
|
+
discussion.messages.map((message, index) => message.role === "user" ? (0, react_jsx_runtime.jsx)("p", {
|
|
23577
|
+
className: PendingPanel_module_css_default.discussionUser,
|
|
23578
|
+
"data-diff-discussion-user": true,
|
|
23579
|
+
children: message.text
|
|
23580
|
+
}, `u${index}`) : (0, react_jsx_runtime.jsx)("p", {
|
|
23581
|
+
className: PendingPanel_module_css_default.discussionAnswer,
|
|
23582
|
+
"data-diff-discussion-reply": true,
|
|
23583
|
+
children: message.text
|
|
23584
|
+
}, `a${index}`)),
|
|
23585
|
+
discussion.reply !== void 0 && discussion.reply !== "" ? (0, react_jsx_runtime.jsx)("p", {
|
|
23586
|
+
className: PendingPanel_module_css_default.discussionAnswer,
|
|
23587
|
+
"data-diff-discussion-reply": true,
|
|
23588
|
+
children: discussion.reply
|
|
23589
|
+
}) : discussion.lost === true ? null : discussion.failed === true ? (0, react_jsx_runtime.jsx)("p", {
|
|
23590
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
23591
|
+
"data-diff-discussion-failed": true,
|
|
23592
|
+
children: t("discussion.failed")
|
|
23593
|
+
}) : discussion.asking === true ? (0, react_jsx_runtime.jsx)("p", {
|
|
23594
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
23595
|
+
"data-diff-discussion-asking": true,
|
|
23596
|
+
children: discussion.queued === true ? t("discussion.queued") : t("discussion.thinking")
|
|
23597
|
+
}) : (0, react_jsx_runtime.jsxs)("div", {
|
|
23598
|
+
className: PendingPanel_module_css_default.discussionCompose,
|
|
23599
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
23600
|
+
className: PendingPanel_module_css_default.discussionInput,
|
|
23601
|
+
"data-diff-discussion-input": true,
|
|
23602
|
+
ref: (element) => {
|
|
23603
|
+
if (element === null) discussionInputEls.current.delete(discussion.id);
|
|
23604
|
+
else discussionInputEls.current.set(discussion.id, element);
|
|
23605
|
+
},
|
|
23606
|
+
value: discussion.draft,
|
|
23607
|
+
placeholder: t("discussion.placeholder"),
|
|
23608
|
+
onChange: (event) => {
|
|
23609
|
+
const value = event.target.value;
|
|
23610
|
+
setDiscussions((current) => current.map((entry) => entry.id === discussion.id ? {
|
|
23611
|
+
...entry,
|
|
23612
|
+
draft: value
|
|
23613
|
+
} : entry));
|
|
23614
|
+
},
|
|
23615
|
+
onKeyDown: (event) => {
|
|
23616
|
+
if (event.key !== "Enter") return;
|
|
23617
|
+
if (event.nativeEvent.isComposing || event.keyCode === 229) return;
|
|
23618
|
+
event.preventDefault();
|
|
23619
|
+
sendDiscussion(discussion.id);
|
|
23620
|
+
}
|
|
23621
|
+
}), (0, react_jsx_runtime.jsxs)("button", {
|
|
23622
|
+
type: "button",
|
|
23623
|
+
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionPrimary} ${PendingPanel_module_css_default.discussionSend}`,
|
|
23624
|
+
"data-diff-discussion-send": true,
|
|
23625
|
+
onClick: () => {
|
|
23626
|
+
sendDiscussion(discussion.id);
|
|
23627
|
+
},
|
|
23628
|
+
children: [t("action.comment"), (0, react_jsx_runtime.jsx)(ReturnIcon, {})]
|
|
23629
|
+
})]
|
|
23630
|
+
})
|
|
23631
|
+
]
|
|
23632
|
+
})]
|
|
23633
|
+
}, discussion.id)
|
|
23634
|
+
})
|
|
23635
|
+
})
|
|
23636
|
+
]
|
|
23637
|
+
}, discussion.id);
|
|
23638
|
+
})] }, index);
|
|
22579
23639
|
}),
|
|
22580
23640
|
end < rowCount && (0, react_jsx_runtime.jsx)("div", {
|
|
22581
23641
|
className: PendingPanel_module_css_default.vSpacer,
|
|
@@ -22585,33 +23645,57 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22585
23645
|
]
|
|
22586
23646
|
})
|
|
22587
23647
|
}),
|
|
22588
|
-
|
|
23648
|
+
selectionFrameVisible ? (0, react_jsx_runtime.jsxs)("div", {
|
|
23649
|
+
ref: frameRef,
|
|
22589
23650
|
className: PendingPanel_module_css_default.blockActions,
|
|
22590
23651
|
"data-diff-selection-actions": true,
|
|
22591
|
-
style: { top:
|
|
22592
|
-
children: [
|
|
22593
|
-
|
|
22594
|
-
|
|
22595
|
-
|
|
22596
|
-
|
|
22597
|
-
|
|
22598
|
-
|
|
22599
|
-
|
|
22600
|
-
|
|
22601
|
-
|
|
22602
|
-
|
|
22603
|
-
|
|
22604
|
-
"
|
|
22605
|
-
|
|
22606
|
-
|
|
22607
|
-
|
|
22608
|
-
|
|
22609
|
-
|
|
22610
|
-
|
|
23652
|
+
style: { top: frameTop },
|
|
23653
|
+
children: [
|
|
23654
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
23655
|
+
type: "button",
|
|
23656
|
+
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionPrimary}`,
|
|
23657
|
+
"data-diff-selection-keep": true,
|
|
23658
|
+
hidden: selectionRange === void 0,
|
|
23659
|
+
disabled: busy,
|
|
23660
|
+
onClick: () => {
|
|
23661
|
+
handleSelectionAction("keep");
|
|
23662
|
+
},
|
|
23663
|
+
children: t("action.keep")
|
|
23664
|
+
}),
|
|
23665
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
23666
|
+
type: "button",
|
|
23667
|
+
className: PendingPanel_module_css_default.action,
|
|
23668
|
+
"data-diff-selection-revert": true,
|
|
23669
|
+
hidden: selectionRange === void 0,
|
|
23670
|
+
disabled: busy,
|
|
23671
|
+
onClick: () => {
|
|
23672
|
+
handleSelectionAction("revert");
|
|
23673
|
+
},
|
|
23674
|
+
children: t("action.revert")
|
|
23675
|
+
}),
|
|
23676
|
+
selectionRange !== void 0 && selectionCommentOffered && (0, react_jsx_runtime.jsx)("span", {
|
|
23677
|
+
className: PendingPanel_module_css_default.blockActionsDivider,
|
|
23678
|
+
"data-diff-selection-divider": true,
|
|
23679
|
+
"aria-hidden": "true"
|
|
23680
|
+
}),
|
|
23681
|
+
selectionCommentOffered && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
23682
|
+
label: withChord(t("action.comment"), "addComment"),
|
|
23683
|
+
side: "bottom",
|
|
23684
|
+
delayMs: 500,
|
|
23685
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
23686
|
+
type: "button",
|
|
23687
|
+
className: PendingPanel_module_css_default.action,
|
|
23688
|
+
"data-diff-selection-comment": true,
|
|
23689
|
+
onClick: addDiscussion,
|
|
23690
|
+
children: t("action.comment")
|
|
23691
|
+
})
|
|
23692
|
+
})
|
|
23693
|
+
]
|
|
22611
23694
|
}) : hoveredBlock !== void 0 && model.blocks[hoveredBlock] !== void 0 ? (0, react_jsx_runtime.jsxs)("div", {
|
|
23695
|
+
ref: frameRef,
|
|
22612
23696
|
className: PendingPanel_module_css_default.blockActions,
|
|
22613
23697
|
"data-diff-block-actions": true,
|
|
22614
|
-
style: { top:
|
|
23698
|
+
style: { top: frameTop },
|
|
22615
23699
|
children: [
|
|
22616
23700
|
(0, react_jsx_runtime.jsx)("span", {
|
|
22617
23701
|
className: PendingPanel_module_css_default.blockPosition,
|
|
@@ -22680,7 +23764,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22680
23764
|
"data-diff-approval-ruler": true,
|
|
22681
23765
|
"aria-hidden": "true",
|
|
22682
23766
|
style: { bottom: hScrollbarPx },
|
|
22683
|
-
children:
|
|
23767
|
+
children: rulerMarkersNow.map((marker, index) => (0, react_jsx_runtime.jsx)("div", {
|
|
22684
23768
|
className: `${PendingPanel_module_css_default.overviewMarker} ${marker.kind === "del" ? PendingPanel_module_css_default.markerDel : PendingPanel_module_css_default.markerAdd}`,
|
|
22685
23769
|
"data-diff-ruler-marker": marker.kind,
|
|
22686
23770
|
style: {
|
|
@@ -22778,7 +23862,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22778
23862
|
});
|
|
22779
23863
|
}
|
|
22780
23864
|
/** Render the pending-edit review panel and its unified footer action. */
|
|
22781
|
-
function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPreviewImage, onPasteReference, onUndo, onRedo, onImportVcs, onRefreshVcs, onBrowse, onAddPath, onKeepAll, onRevertAll, onAckRedoCleared, collapseSidebar, t, docked = false, dockHost, onOpenDock, closeDock, useDock }) {
|
|
23865
|
+
function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPreviewImage, onPasteReference, onAskAgent, watchChat, onUndo, onRedo, onImportVcs, onRefreshVcs, onBrowse, onAddPath, onKeepAll, onRevertAll, onAckRedoCleared, collapseSidebar, t, docked = false, dockHost, onOpenDock, closeDock, useDock }) {
|
|
22782
23866
|
const current = useSessions((state) => state.current);
|
|
22783
23867
|
const currentBlank = useSessions((state) => {
|
|
22784
23868
|
const id = state.current;
|
|
@@ -22982,17 +24066,51 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22982
24066
|
* reader's choice always wins over the default.
|
|
22983
24067
|
*/
|
|
22984
24068
|
const startListOpenRef = (0, react.useRef)(false);
|
|
24069
|
+
const [floatClosing, setFloatClosing] = (0, react.useState)(false);
|
|
24070
|
+
const foldTimerRef = (0, react.useRef)(void 0);
|
|
24071
|
+
(0, react.useEffect)(() => () => {
|
|
24072
|
+
if (foldTimerRef.current !== void 0) window.clearTimeout(foldTimerRef.current);
|
|
24073
|
+
}, []);
|
|
24074
|
+
/** Fold the card away, giving the exit animation its `FILE_LIST_FOLD_MS` first; `then`
|
|
24075
|
+
* runs once it has gone, for callers with work to do the moment it is folded. */
|
|
24076
|
+
const foldCardAway = (then) => {
|
|
24077
|
+
if (foldTimerRef.current !== void 0) window.clearTimeout(foldTimerRef.current);
|
|
24078
|
+
setFloatClosing(true);
|
|
24079
|
+
foldTimerRef.current = window.setTimeout(() => {
|
|
24080
|
+
foldTimerRef.current = void 0;
|
|
24081
|
+
setFloatClosing(false);
|
|
24082
|
+
setFloatOpen(false);
|
|
24083
|
+
then?.();
|
|
24084
|
+
}, FILE_LIST_FOLD_MS);
|
|
24085
|
+
};
|
|
22985
24086
|
const toggleFileList = () => {
|
|
22986
24087
|
startListOpenRef.current = false;
|
|
22987
|
-
|
|
24088
|
+
if (floatClosing) {
|
|
24089
|
+
if (foldTimerRef.current !== void 0) window.clearTimeout(foldTimerRef.current);
|
|
24090
|
+
foldTimerRef.current = void 0;
|
|
24091
|
+
setFloatClosing(false);
|
|
24092
|
+
return;
|
|
24093
|
+
}
|
|
24094
|
+
if (floatOpen) {
|
|
24095
|
+
foldCardAway();
|
|
24096
|
+
return;
|
|
24097
|
+
}
|
|
24098
|
+
setFloatOpen(true);
|
|
22988
24099
|
};
|
|
22989
24100
|
/** Flip the always-fold preference, remembered for the next open. */
|
|
22990
24101
|
const toggleForceFloat = () => {
|
|
22991
24102
|
startListOpenRef.current = false;
|
|
22992
24103
|
const next = !forceFloat;
|
|
22993
|
-
|
|
22994
|
-
|
|
22995
|
-
|
|
24104
|
+
const apply = () => {
|
|
24105
|
+
setForceFloat(next);
|
|
24106
|
+
setFileListFloat(next);
|
|
24107
|
+
if (next) setFloatOpen(false);
|
|
24108
|
+
};
|
|
24109
|
+
if (next && floatOpen) {
|
|
24110
|
+
foldCardAway(apply);
|
|
24111
|
+
return;
|
|
24112
|
+
}
|
|
24113
|
+
apply();
|
|
22996
24114
|
};
|
|
22997
24115
|
(0, react.useEffect)(() => {
|
|
22998
24116
|
const onResize = () => {
|
|
@@ -23022,13 +24140,18 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23022
24140
|
const onPointerDown = (event) => {
|
|
23023
24141
|
const target = event.target;
|
|
23024
24142
|
if (target instanceof Element && (target.closest("[data-diff-floating-file-list]") !== null || target.closest("[data-diff-file-list-toggle]") !== null || target.closest("[data-diff-float-resize]") !== null)) return;
|
|
23025
|
-
|
|
24143
|
+
if (floatClosing) return;
|
|
24144
|
+
foldCardAway();
|
|
23026
24145
|
};
|
|
23027
24146
|
el.addEventListener("pointerdown", onPointerDown, true);
|
|
23028
24147
|
return () => {
|
|
23029
24148
|
el.removeEventListener("pointerdown", onPointerDown, true);
|
|
23030
24149
|
};
|
|
23031
|
-
}, [
|
|
24150
|
+
}, [
|
|
24151
|
+
floatMode,
|
|
24152
|
+
floatOpen,
|
|
24153
|
+
floatClosing
|
|
24154
|
+
]);
|
|
23032
24155
|
const measureFloatBox = () => {
|
|
23033
24156
|
if (!floatMode) return;
|
|
23034
24157
|
const panel = panelRef.current;
|
|
@@ -23880,6 +25003,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23880
25003
|
top: (floatBox?.top ?? 0) + FLOAT_LIST_MARGIN_PX
|
|
23881
25004
|
},
|
|
23882
25005
|
"data-diff-file-list-toggle": true,
|
|
25006
|
+
"data-open": floatOpen || void 0,
|
|
23883
25007
|
"aria-label": t(floatOpen ? "action.hideFileList" : "action.showFileList"),
|
|
23884
25008
|
"aria-expanded": floatOpen,
|
|
23885
25009
|
onClick: toggleFileList,
|
|
@@ -23912,7 +25036,10 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23912
25036
|
landingTop: landing !== void 0 && landing.fileId === selectedFile.id ? landing.top : void 0,
|
|
23913
25037
|
landingTick: landing !== void 0 && landing.fileId === selectedFile.id ? landing.n : 0,
|
|
23914
25038
|
failedMessage: failed.get(selectedFile.id),
|
|
25039
|
+
commentSkill: snapshot.commentSkill,
|
|
23915
25040
|
onPasteReference,
|
|
25041
|
+
onAskAgent,
|
|
25042
|
+
watchChat,
|
|
23916
25043
|
onToast: showCopyToast,
|
|
23917
25044
|
t,
|
|
23918
25045
|
onKeep: keepWithPrompt,
|
|
@@ -23927,7 +25054,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23927
25054
|
})
|
|
23928
25055
|
}),
|
|
23929
25056
|
floatCard !== void 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("div", {
|
|
23930
|
-
className: PendingPanel_module_css_default.fileListFloat,
|
|
25057
|
+
className: floatClosing ? `${PendingPanel_module_css_default.fileListFloat} ${PendingPanel_module_css_default.fileListFloatClosing}` : PendingPanel_module_css_default.fileListFloat,
|
|
23931
25058
|
style: {
|
|
23932
25059
|
left: floatCard.left,
|
|
23933
25060
|
top: floatCard.top,
|
|
@@ -24706,6 +25833,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
24706
25833
|
*/
|
|
24707
25834
|
function DiffApprovalSettingsTab({ t }) {
|
|
24708
25835
|
const [pasteOnCopy, setPasteOnCopyState] = (0, react.useState)(pasteOnCopyEnabled);
|
|
25836
|
+
const [commentMode, setCommentModeState] = (0, react.useState)(commentModeEnabled);
|
|
24709
25837
|
const [includeUntracked, setIncludeUntrackedState] = (0, react.useState)(includeUntrackedEnabled);
|
|
24710
25838
|
const [confirmFileRemove, setConfirmFileRemoveState] = (0, react.useState)(confirmFileRemoveEnabled);
|
|
24711
25839
|
const [tab, setTabState] = (0, react.useState)(tabWidth);
|
|
@@ -24762,6 +25890,10 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
24762
25890
|
setPasteOnCopyState(value);
|
|
24763
25891
|
setPasteOnCopyEnabled(value);
|
|
24764
25892
|
};
|
|
25893
|
+
const setCommentMode = (value) => {
|
|
25894
|
+
setCommentModeState(value);
|
|
25895
|
+
setCommentModeEnabled(value);
|
|
25896
|
+
};
|
|
24765
25897
|
const setIncludeUntracked = (value) => {
|
|
24766
25898
|
setIncludeUntrackedState(value);
|
|
24767
25899
|
setIncludeUntrackedEnabled(value);
|
|
@@ -24931,6 +26063,14 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
24931
26063
|
onSelect: setPasteOnCopy,
|
|
24932
26064
|
dataAttribute: "data-diff-paste-on-copy-select",
|
|
24933
26065
|
t
|
|
26066
|
+
}),
|
|
26067
|
+
(0, react_jsx_runtime.jsx)(PreferenceRow, {
|
|
26068
|
+
title: t("panel.commentMode"),
|
|
26069
|
+
description: t("panel.commentModeDesc"),
|
|
26070
|
+
value: commentMode,
|
|
26071
|
+
onSelect: setCommentMode,
|
|
26072
|
+
dataAttribute: "data-diff-comment-mode-select",
|
|
26073
|
+
t
|
|
24934
26074
|
})
|
|
24935
26075
|
]
|
|
24936
26076
|
})]
|
|
@@ -25202,13 +26342,18 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25202
26342
|
const file = pendingFileOf(row);
|
|
25203
26343
|
if (file !== void 0) files.push(file);
|
|
25204
26344
|
}
|
|
25205
|
-
|
|
26345
|
+
const redoCleared = value.redoCleared;
|
|
26346
|
+
const skill = value.commentSkill;
|
|
26347
|
+
const commentSkill = typeof skill === "string" && skill.length > 0 ? skill : void 0;
|
|
26348
|
+
return redoCleared === true ? {
|
|
25206
26349
|
files,
|
|
25207
26350
|
workspacePath,
|
|
25208
|
-
redoCleared: true
|
|
26351
|
+
redoCleared: true,
|
|
26352
|
+
commentSkill
|
|
25209
26353
|
} : {
|
|
25210
26354
|
files,
|
|
25211
|
-
workspacePath
|
|
26355
|
+
workspacePath,
|
|
26356
|
+
commentSkill
|
|
25212
26357
|
};
|
|
25213
26358
|
}
|
|
25214
26359
|
/** Narrow one action endpoint's value; a malformed wire value is an action failure. */
|
|
@@ -25463,12 +26608,13 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25463
26608
|
return;
|
|
25464
26609
|
}
|
|
25465
26610
|
try {
|
|
25466
|
-
const { files, workspacePath, redoCleared: cleared } = await port.list(sessionId);
|
|
26611
|
+
const { files, workspacePath, redoCleared: cleared, commentSkill } = await port.list(sessionId);
|
|
25467
26612
|
if (cleared) redoCleared = true;
|
|
25468
26613
|
publish({
|
|
25469
26614
|
read: true,
|
|
25470
26615
|
files,
|
|
25471
26616
|
workspacePath,
|
|
26617
|
+
commentSkill,
|
|
25472
26618
|
busy: EMPTY_BUSY,
|
|
25473
26619
|
failed: failedOf(snapshot)
|
|
25474
26620
|
});
|
|
@@ -25477,6 +26623,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25477
26623
|
read: true,
|
|
25478
26624
|
files: snapshot.files,
|
|
25479
26625
|
workspacePath: snapshot.workspacePath,
|
|
26626
|
+
commentSkill: snapshot.commentSkill,
|
|
25480
26627
|
error: error instanceof Error ? error.message : String(error),
|
|
25481
26628
|
busy: snapshot.busy,
|
|
25482
26629
|
failed: failedOf(snapshot)
|
|
@@ -25761,6 +26908,184 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25761
26908
|
};
|
|
25762
26909
|
}
|
|
25763
26910
|
//#endregion
|
|
26911
|
+
//#region lib/types/client/chat-bridge.js
|
|
26912
|
+
/**
|
|
26913
|
+
* The panel's one connection to the session's chat: send one prompt, and watch
|
|
26914
|
+
* the transcript so a discussion can show its answer where it was asked.
|
|
26915
|
+
*
|
|
26916
|
+
* Everything here is deliberately defensive. The surfaces it uses (the scoped
|
|
26917
|
+
* `conversation` input face, the `sessions` binding, the `chat` view target) are
|
|
26918
|
+
* public types but not plugin-documented API, so a build that lacks one reports
|
|
26919
|
+
* "unavailable" and the caller falls back to the composer route it already had.
|
|
26920
|
+
*
|
|
26921
|
+
* @module dsh-diff-approval/client/chat-bridge
|
|
26922
|
+
*/
|
|
26923
|
+
/** Join the text blocks of one message body. */
|
|
26924
|
+
function textOf(blocks) {
|
|
26925
|
+
if (!Array.isArray(blocks)) return "";
|
|
26926
|
+
return blocks.filter((block) => typeof block === "object" && block !== null && (block.kind === "text" || block.type === "text")).map((block) => typeof block.text === "string" ? block.text : "").filter((text) => text !== "").join("\n").trim();
|
|
26927
|
+
}
|
|
26928
|
+
/** The node kinds that carry a message the human sent. */
|
|
26929
|
+
const HUMAN_KINDS = /* @__PURE__ */ new Set(["user", "steering"]);
|
|
26930
|
+
/** Reduce the durable transcript to the nodes a discussion reads. */
|
|
26931
|
+
function nodesOf(nodes) {
|
|
26932
|
+
if (!Array.isArray(nodes)) return [];
|
|
26933
|
+
const views = [];
|
|
26934
|
+
for (const node of nodes) {
|
|
26935
|
+
if (typeof node !== "object" || node === null) continue;
|
|
26936
|
+
const record = node;
|
|
26937
|
+
const kind = typeof record.kind === "string" ? record.kind : "unknown";
|
|
26938
|
+
if (kind === "assistant") views.push(record.interrupted === true ? {
|
|
26939
|
+
kind,
|
|
26940
|
+
text: textOf(record.blocks),
|
|
26941
|
+
interrupted: true
|
|
26942
|
+
} : {
|
|
26943
|
+
kind,
|
|
26944
|
+
text: textOf(record.blocks)
|
|
26945
|
+
});
|
|
26946
|
+
else if (HUMAN_KINDS.has(kind)) views.push({
|
|
26947
|
+
kind: "user",
|
|
26948
|
+
text: textOf(record.content)
|
|
26949
|
+
});
|
|
26950
|
+
}
|
|
26951
|
+
return views;
|
|
26952
|
+
}
|
|
26953
|
+
/**
|
|
26954
|
+
* The prompts the session is still holding, from the two places that know: its inbox
|
|
26955
|
+
* queue (`QueuedMessage[]`, whose `text` is the prompt) and the local submission
|
|
26956
|
+
* echoes (`pendingSubmissions`, dropped only once the durable message is observed).
|
|
26957
|
+
* `undefined` when the snapshot does not publish a queue at all, so a caller can tell
|
|
26958
|
+
* "nothing is waiting" from "this build cannot say".
|
|
26959
|
+
*
|
|
26960
|
+
* @param session - the session-state snapshot, or undefined.
|
|
26961
|
+
* @returns the waiting prompt texts, or undefined on a build that cannot say.
|
|
26962
|
+
*/
|
|
26963
|
+
function queuedOf(session) {
|
|
26964
|
+
const queue = session?.queue;
|
|
26965
|
+
if (!Array.isArray(queue)) return void 0;
|
|
26966
|
+
const pending = Array.isArray(session?.pendingSubmissions) ? session.pendingSubmissions : [];
|
|
26967
|
+
const texts = [];
|
|
26968
|
+
for (const entry of [...queue, ...pending]) {
|
|
26969
|
+
if (typeof entry !== "object" || entry === null) continue;
|
|
26970
|
+
const record = entry;
|
|
26971
|
+
const text = typeof record.text === "string" && record.text !== "" ? record.text : typeof record.preview === "string" ? record.preview : "";
|
|
26972
|
+
if (text !== "") texts.push(text);
|
|
26973
|
+
}
|
|
26974
|
+
return texts;
|
|
26975
|
+
}
|
|
26976
|
+
/**
|
|
26977
|
+
* Build the bridge over the client context. Every verb takes the session it
|
|
26978
|
+
* addresses, so one bridge serves whichever session the panel is showing.
|
|
26979
|
+
* @param ctx - the plugin's client context.
|
|
26980
|
+
* @returns the bridge (its verbs report unavailability instead of throwing).
|
|
26981
|
+
*/
|
|
26982
|
+
function createChatBridge(ctx) {
|
|
26983
|
+
const scoped = (sessionId) => {
|
|
26984
|
+
try {
|
|
26985
|
+
const sessions = ctx.get("sessions");
|
|
26986
|
+
const actx = sessions?.scope?.(sessionId);
|
|
26987
|
+
if (actx === void 0) return void 0;
|
|
26988
|
+
return {
|
|
26989
|
+
actx,
|
|
26990
|
+
binding: sessions?.binding?.(sessionId)
|
|
26991
|
+
};
|
|
26992
|
+
} catch {
|
|
26993
|
+
return;
|
|
26994
|
+
}
|
|
26995
|
+
};
|
|
26996
|
+
const ask = (sessionId, text) => {
|
|
26997
|
+
const target = scoped(sessionId);
|
|
26998
|
+
if (target === void 0) return false;
|
|
26999
|
+
try {
|
|
27000
|
+
const conversation = target.actx.get("conversation");
|
|
27001
|
+
if (typeof conversation?.send === "function") {
|
|
27002
|
+
Promise.resolve(conversation.send(text)).catch(() => {});
|
|
27003
|
+
return true;
|
|
27004
|
+
}
|
|
27005
|
+
const input = conversation?.input?.for?.(target.actx);
|
|
27006
|
+
if (typeof input?.setDraft !== "function" || typeof input.submit !== "function") return false;
|
|
27007
|
+
const previous = (() => {
|
|
27008
|
+
try {
|
|
27009
|
+
const state = input.state?.getSnapshot?.();
|
|
27010
|
+
return typeof state?.draft === "string" ? state.draft : "";
|
|
27011
|
+
} catch {
|
|
27012
|
+
return "";
|
|
27013
|
+
}
|
|
27014
|
+
})();
|
|
27015
|
+
input.setDraft(text);
|
|
27016
|
+
input.submit("queue");
|
|
27017
|
+
if (previous !== "") window.setTimeout(() => {
|
|
27018
|
+
try {
|
|
27019
|
+
input.setDraft(previous);
|
|
27020
|
+
} catch {}
|
|
27021
|
+
}, 0);
|
|
27022
|
+
return true;
|
|
27023
|
+
} catch {
|
|
27024
|
+
return false;
|
|
27025
|
+
}
|
|
27026
|
+
};
|
|
27027
|
+
const currentView = (sessionId) => {
|
|
27028
|
+
const target = scoped(sessionId);
|
|
27029
|
+
if (target === void 0) return {
|
|
27030
|
+
running: false,
|
|
27031
|
+
nodes: [],
|
|
27032
|
+
partial: "",
|
|
27033
|
+
error: void 0,
|
|
27034
|
+
queued: void 0
|
|
27035
|
+
};
|
|
27036
|
+
const session = (() => {
|
|
27037
|
+
try {
|
|
27038
|
+
const snapshot = target.binding?.session?.getSnapshot?.();
|
|
27039
|
+
return typeof snapshot === "object" && snapshot !== null ? snapshot : void 0;
|
|
27040
|
+
} catch {
|
|
27041
|
+
return;
|
|
27042
|
+
}
|
|
27043
|
+
})();
|
|
27044
|
+
const legacy = (() => {
|
|
27045
|
+
try {
|
|
27046
|
+
const value = ctx.get("uiConversation")?.binding?.(sessionId)?.target?.("chat")?.getSnapshot?.();
|
|
27047
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
27048
|
+
} catch {
|
|
27049
|
+
return;
|
|
27050
|
+
}
|
|
27051
|
+
})()?.legacy ?? {};
|
|
27052
|
+
const partial = (() => {
|
|
27053
|
+
const value = legacy.partial;
|
|
27054
|
+
return value == null ? "" : textOf(value.blocks);
|
|
27055
|
+
})();
|
|
27056
|
+
const error = session?.promptError;
|
|
27057
|
+
return {
|
|
27058
|
+
running: session?.running === true,
|
|
27059
|
+
nodes: nodesOf(legacy.nodes),
|
|
27060
|
+
partial,
|
|
27061
|
+
error: error == null ? void 0 : String(error),
|
|
27062
|
+
queued: queuedOf(session)
|
|
27063
|
+
};
|
|
27064
|
+
};
|
|
27065
|
+
const watch = (sessionId, listener) => {
|
|
27066
|
+
if (scoped(sessionId) === void 0) {
|
|
27067
|
+
listener(currentView(sessionId));
|
|
27068
|
+
return () => {};
|
|
27069
|
+
}
|
|
27070
|
+
const unsubscribes = [];
|
|
27071
|
+
const notify = () => {
|
|
27072
|
+
listener(currentView(sessionId));
|
|
27073
|
+
};
|
|
27074
|
+
try {
|
|
27075
|
+
const stop = ctx.get("uiConversation")?.binding?.(sessionId)?.target?.("chat")?.subscribe?.(notify);
|
|
27076
|
+
if (typeof stop === "function") unsubscribes.push(stop);
|
|
27077
|
+
} catch {}
|
|
27078
|
+
notify();
|
|
27079
|
+
return () => {
|
|
27080
|
+
for (const stop of unsubscribes) stop();
|
|
27081
|
+
};
|
|
27082
|
+
};
|
|
27083
|
+
return {
|
|
27084
|
+
ask,
|
|
27085
|
+
watch
|
|
27086
|
+
};
|
|
27087
|
+
}
|
|
27088
|
+
//#endregion
|
|
25764
27089
|
//#region lib/types/client/header-entry.js
|
|
25765
27090
|
/**
|
|
25766
27091
|
* The pending-changes entry in the Session header.
|
|
@@ -25875,6 +27200,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25875
27200
|
"panel.diffDelColor": "删除颜色",
|
|
25876
27201
|
"panel.diffDelColorDesc": "删除行的基础色;行背景与逐词差异由它派生。默认色:{default}。",
|
|
25877
27202
|
"panel.quickSummon": "快速呼出",
|
|
27203
|
+
"panel.commentMode": "评论模式",
|
|
27204
|
+
"panel.commentModeDesc": "选中差异行后可以直接就这几行向智能体提问,回答就显示在这几行下方。",
|
|
25878
27205
|
"panel.quickSummonDesc": "用键盘快捷键打开/关闭差异面板。点击右侧按钮后按下新的按键组合即可修改。",
|
|
25879
27206
|
"panel.recordShortcut": "按下快捷键…",
|
|
25880
27207
|
"settings.keybindings": "快捷键",
|
|
@@ -25888,6 +27215,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25888
27215
|
"panel.key.jumpUp": "跳转到上一个差异块",
|
|
25889
27216
|
"panel.key.jumpDown": "跳转到下一个差异块",
|
|
25890
27217
|
"panel.key.copyRef": "复制引用",
|
|
27218
|
+
"panel.key.addComment": "在选中行上新增评论",
|
|
25891
27219
|
"panel.key.openSearch": "打开差异搜索",
|
|
25892
27220
|
"panel.key.searchNext": "下一个搜索结果",
|
|
25893
27221
|
"panel.key.searchPrev": "上一个搜索结果",
|
|
@@ -25908,6 +27236,20 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25908
27236
|
"row.added": "+{added}",
|
|
25909
27237
|
"row.removed": "-{removed}",
|
|
25910
27238
|
"action.keep": "保留",
|
|
27239
|
+
"action.comment": "评论",
|
|
27240
|
+
"action.more": "更多",
|
|
27241
|
+
"action.discussionExpand": "展开",
|
|
27242
|
+
"action.discussionCollapse": "收起",
|
|
27243
|
+
"discussion.placeholder": "写下你的评论…",
|
|
27244
|
+
"discussion.marker": "[评论]",
|
|
27245
|
+
"discussion.promptRule": "(回答只针对这几行,不超过 3 行;行与行之间不要留空行;用纯文本,不要 Markdown 装饰;要求详细时不受长度限制。细则见 dsh-diff-approval-comment skill。)",
|
|
27246
|
+
"discussion.promptRuleSkill": "(这是一条代码批注:先加载 {skill} skill,按它的规则回答。)",
|
|
27247
|
+
"discussion.thinking": "思考中…",
|
|
27248
|
+
"discussion.queued": "排队等待中…",
|
|
27249
|
+
"discussion.lost": "这段代码已经改动,批注的锚点找不到了(不能再评论,可删除)。",
|
|
27250
|
+
"discussion.hidden": "更早的 {count} 条已省略",
|
|
27251
|
+
"discussion.failed": "这次提问失败了,可以再试一次。",
|
|
27252
|
+
"discussion.stopped": "这次回答被停掉了,可以再问一次。",
|
|
25911
27253
|
"action.revert": "回退",
|
|
25912
27254
|
"action.delete": "删除",
|
|
25913
27255
|
"action.keepAll": "全部保留",
|
|
@@ -26059,6 +27401,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
26059
27401
|
"panel.diffDelColor": "Removed color",
|
|
26060
27402
|
"panel.diffDelColorDesc": "Base color for removed lines; the row background and intra-line diff are derived from it. Default: {default}.",
|
|
26061
27403
|
"panel.quickSummon": "Quick summon",
|
|
27404
|
+
"panel.commentMode": "Comment mode",
|
|
27405
|
+
"panel.commentModeDesc": "Ask the agent about the rows you select in the diff; the answer appears in a thread right below them.",
|
|
26062
27406
|
"panel.quickSummonDesc": "Open or close the diff panel with a keyboard shortcut. Click the button and press a new chord to change it.",
|
|
26063
27407
|
"panel.recordShortcut": "Press keys…",
|
|
26064
27408
|
"settings.keybindings": "Shortcuts",
|
|
@@ -26072,6 +27416,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
26072
27416
|
"panel.key.jumpUp": "Jump to the previous diff block",
|
|
26073
27417
|
"panel.key.jumpDown": "Jump to the next diff block",
|
|
26074
27418
|
"panel.key.copyRef": "Copy reference",
|
|
27419
|
+
"panel.key.addComment": "Comment on the selected rows",
|
|
26075
27420
|
"panel.key.openSearch": "Open diff search",
|
|
26076
27421
|
"panel.key.searchNext": "Next search result",
|
|
26077
27422
|
"panel.key.searchPrev": "Previous search result",
|
|
@@ -26092,6 +27437,20 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
26092
27437
|
"row.added": "+{added}",
|
|
26093
27438
|
"row.removed": "-{removed}",
|
|
26094
27439
|
"action.keep": "Keep",
|
|
27440
|
+
"action.comment": "Comment",
|
|
27441
|
+
"action.more": "More",
|
|
27442
|
+
"action.discussionExpand": "Expand",
|
|
27443
|
+
"action.discussionCollapse": "Collapse",
|
|
27444
|
+
"discussion.placeholder": "Write your comment…",
|
|
27445
|
+
"discussion.marker": "[Review]",
|
|
27446
|
+
"discussion.promptRule": "(Answer only about these lines, in at most 3 lines, with no blank line between them, as plain text without Markdown decoration; ignore the length limit if my annotation asks for detail. Full rules: the dsh-diff-approval-comment skill.)",
|
|
27447
|
+
"discussion.promptRuleSkill": "(This is a comment on a few diff lines: load the {skill} skill first and answer by its rules.)",
|
|
27448
|
+
"discussion.thinking": "Thinking…",
|
|
27449
|
+
"discussion.queued": "Queued…",
|
|
27450
|
+
"discussion.lost": "This code has changed and the annotation no longer anchors to it (it cannot be commented on again; delete it if it is done).",
|
|
27451
|
+
"discussion.hidden": "{count} earlier turns omitted",
|
|
27452
|
+
"discussion.failed": "That question failed; you can try again.",
|
|
27453
|
+
"discussion.stopped": "That answer was stopped; you can ask again.",
|
|
26095
27454
|
"action.revert": "Revert",
|
|
26096
27455
|
"action.delete": "Delete",
|
|
26097
27456
|
"action.keepAll": "Keep all",
|
|
@@ -26308,6 +27667,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
26308
27667
|
const t = ctx.locale.bind(NS);
|
|
26309
27668
|
const store = createPendingDiffStore(createDiffApprovalPort(ctx.get("connection").rpc));
|
|
26310
27669
|
let currentSessionId;
|
|
27670
|
+
const chat = createChatBridge(ctx);
|
|
26311
27671
|
let remapFile = () => {};
|
|
26312
27672
|
const access = conversationAccess(ctx, () => currentSessionId);
|
|
26313
27673
|
ctx.effect(() => {
|
|
@@ -26376,6 +27736,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
26376
27736
|
conversationAccess(ctx, () => sessionId).appendDraft(text);
|
|
26377
27737
|
}, reference);
|
|
26378
27738
|
},
|
|
27739
|
+
onAskAgent: (sessionId, text) => {
|
|
27740
|
+
currentSessionId = sessionId;
|
|
27741
|
+
return chat.ask(sessionId, text);
|
|
27742
|
+
},
|
|
27743
|
+
watchChat: (sessionId, listener) => chat.watch(sessionId, listener),
|
|
26379
27744
|
collapseSidebar
|
|
26380
27745
|
});
|
|
26381
27746
|
seat(ctx.slots, "sidebar.footer.action", () => ctx.slots.register({
|