dsh-diff-approval 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +1680 -551
- package/lib/index.js +23 -4
- package/lib/types/client/PendingPanel.d.ts +21 -0
- package/lib/types/client/discussion.d.ts +23 -2
- package/lib/types/client/dock.d.ts +10 -0
- package/lib/types/client/locales.d.ts +16 -0
- package/lib/types/client/panel-memory.d.ts +26 -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);-webkit-user-select:none;user-select:none;border-radius:12px;flex-direction:column;display:flex;position:fixed;inset:8px 8px 128px;overflow:hidden}.F1KBNa_panel .F1KBNa_code,.F1KBNa_panel .F1KBNa_mdPreviewBody,.F1KBNa_panel .F1KBNa_discussionUser,.F1KBNa_panel .F1KBNa_discussionAnswer,.F1KBNa_panel .F1KBNa_quoteText,.F1KBNa_panel .F1KBNa_diffPath,.F1KBNa_panel .F1KBNa_rowPath,.F1KBNa_panel input,.F1KBNa_panel textarea,.F1KBNa_panel [contenteditable]{-webkit-user-select:text;user-select:text}.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{overscroll-behavior:none;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{overscroll-behavior-x:none;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 0 10px 8px;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:auto}.F1KBNa_addPath{justify-content:center;align-items:center;gap:4px;display:inline-flex}.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;flex:none;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_listHead{flex:none;align-items:center;gap:4px;margin:8px 1px 2px;padding-right:8px;display:flex}.F1KBNa_action.F1KBNa_addButton.F1KBNa_listFold{width:26px;height:26px}.F1KBNa_listTitle{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;font-weight:500;line-height:16px}.F1KBNa_listTabs{background:var(--dsw-alias-interactive-bg-hover);border-radius:8px;flex:auto;gap:2px;min-width:0;padding:2px;display:flex}.F1KBNa_listTab{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:6px;flex:1;padding:3px 8px;font-size:12px;line-height:16px}.F1KBNa_listTab[aria-selected=true]{background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-primary)}.F1KBNa_commentRow{box-sizing:border-box;width:100%;color:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;padding:6px 8px;display:block}.F1KBNa_commentRow:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_commentHead{align-items:baseline;gap:6px;min-width:0;display:flex}.F1KBNa_commentLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-markdown-code-block);font-size:11px;line-height:16px;overflow:hidden}.F1KBNa_commentLost{color:var(--dsw-alias-label-tertiary);flex:none;font-size:11px;line-height:16px}.F1KBNa_commentTitle{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);font-size:12px;line-height:18px;display:block;overflow:hidden}.F1KBNa_listEmpty{color:var(--dsw-alias-label-tertiary);margin:8px 12px;font-size:12px;line-height:18px}.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_rowMenuAnchor{display:none}.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;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{appearance:none;min-width:0;font:inherit;text-overflow:ellipsis;color:var(--dsw-alias-label-primary);background:0 0;border:0;flex:1;margin-left:4px;padding:0;font-size:12px;line-height:18px;position:relative;top:1px}.F1KBNa_diffPath:focus{outline: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_actionChord{color:var(--dsw-alias-label-tertiary);margin-left:6px;font-size:11px}.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{overscroll-behavior:none;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:3;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{background:var(--dsw-alias-bg-base);display:table-row}.F1KBNa_discussionCell{display:table-cell}.F1KBNa_discussionPin{z-index:2;width:0;height:0;position:sticky;left:0}.F1KBNa_discussion{z-index:2;box-sizing:border-box;border-left:3px solid var(--dsw-alias-state-business-primary);box-shadow:inset 0 1px 0 0 color-mix(in srgb, var(--dsw-alias-label-secondary) 55%, transparent), inset 0 -1px 0 0 color-mix(in srgb, var(--dsw-alias-label-secondary) 55%, transparent), inset -1px 0 0 0 color-mix(in srgb, var(--dsw-alias-label-secondary) 55%, transparent);cursor:default;background:0 0;flex-direction:column;display:flex;position:absolute;top:0;left:0;overflow:hidden}.F1KBNa_discussionHead{font:var(--dsw-font-markdown-code-block)}.F1KBNa_discussionBody,.F1KBNa_threadFontProbe{font:var(--dsw-font-markdown-base);font-size:calc(var(--dsh-content-font-size,14px) - 2px)}.F1KBNa_threadFontProbe{visibility:hidden;pointer-events:none;width:0;height:0;position:absolute;overflow:hidden}.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-label-secondary);background:repeating-linear-gradient(135deg, var(--dsw-alias-interactive-bg-hover) 0 4px, transparent 4px 8px);background-origin:border-box}.F1KBNa_discussion[data-lost] .F1KBNa_discussionSend,.F1KBNa_discussion[data-lost] .F1KBNa_discussionSend:hover:not(:disabled),.F1KBNa_discussion[data-lost] .F1KBNa_discussionSend:disabled{background:var(--dsw-alias-label-secondary);border-color:var(--dsw-alias-label-secondary);color:var(--dsw-alias-label-primary-foreground)}.F1KBNa_discussion[data-lost] .F1KBNa_discussionUser{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 30%, transparent)}.F1KBNa_discussionAnswer{color:var(--dsw-alias-label-primary);white-space:pre-wrap;overflow-wrap:anywhere;cursor:text;margin:0;padding:0;font-family:inherit;line-height:22px}.F1KBNa_discussionUser{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);white-space:pre-wrap;overflow-wrap:anywhere;cursor:text;border-radius:8px 0 8px 8px;margin:6.6px 0 6.6px auto;padding:4.4px 11px;font-family:inherit;line-height:22px}.F1KBNa_discussionCode{box-sizing:border-box;font:var(--dsw-font-markdown-code);font-family:var(--ds-font-family-code);background:color-mix(in srgb, var(--dsw-alias-markdown-inline-code,var(--dsw-alias-interactive-bg-hover-solid)) 90%, var(--dsw-alias-label-secondary));border:.5px solid var(--dsw-alias-border-l1);border-radius:6px;align-items:center;padding:0 5px;font-size:.875em;line-height:16px;display:inline-flex}.F1KBNa_discussionBody strong{font-weight:700}.F1KBNa_discussionNote{color:var(--dsw-alias-label-secondary);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;padding:0;font-family:inherit;line-height:22px}.F1KBNa_discussionNote[data-diff-discussion-hidden]{color:var(--dsw-alias-label-tertiary)}.F1KBNa_discussionDots{margin-left:1px}.F1KBNa_discussionDots>span{animation:1.2s ease-in-out infinite F1KBNa_discussionDot}.F1KBNa_discussionDots>span:nth-child(2){animation-delay:.15s}.F1KBNa_discussionDots>span:nth-child(3){animation-delay:.3s}@keyframes F1KBNa_discussionDot{0%,60%,to{opacity:.25}30%{opacity:1}}.F1KBNa_quoteLines{table-layout:fixed;border-spacing:0;width:calc(100% + 27px);min-width:0;color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code-block);line-height:var(--dsh-diff-line-height,22px);background:color-mix(in srgb, var(--dsw-alias-interactive-bg-hover) 55%, transparent);margin:0 -12px 0 -15px;display:table}.F1KBNa_quoteAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 12%, transparent)}.F1KBNa_quoteDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 13%, transparent)}.F1KBNa_quoteLine{font-size:calc(1em * var(--dsh-diff-font-scale,1));height:var(--dsh-diff-line-height,22px);display:table-row}.F1KBNa_quoteCode{display:table-cell}.F1KBNa_quoteText{white-space:pre-wrap;overflow-wrap:anywhere;cursor:text;display:block}.F1KBNa_quoteNoWrap .F1KBNa_quoteText{white-space:pre;overflow-wrap:normal;overflow:hidden}.F1KBNa_quoteNoWrap .F1KBNa_quoteText:after{content:\"\";width:calc(var(--dsh-diff-quote-width,0px) + 100%);display:inline-block}.F1KBNa_discussionHead{box-sizing:border-box;flex:none;align-items:center;gap:8px;height:22px;padding:0 12px;font-size:12px;line-height:16px;display:flex}.F1KBNa_discussionCompose{box-sizing:border-box;flex:none;align-items:flex-end;gap:8px;height:44px;margin:auto -6px 0;padding:0 0 6.6px;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;height:26px;color:var(--dsw-alias-label-primary);cursor:text;border-radius:6px;flex:auto;padding:3px 8px;font-family:inherit;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}.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;height:26px;padding-left:9px;padding-right:9px;display:inline-flex}.F1KBNa_rowDiscussed{--diff-row-wash:color-mix(in srgb, var(--dsw-alias-label-secondary) 14%, transparent);background-image:linear-gradient(var(--diff-row-wash), var(--diff-row-wash))}@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_line>.F1KBNa_gutter{z-index:1;background-color:var(--dsw-alias-markdown-code-block);background-image:linear-gradient(var(--diff-row-tint,transparent), var(--diff-row-tint,transparent)), linear-gradient(var(--diff-row-wash,transparent), var(--diff-row-wash,transparent));position:sticky;left:0}.F1KBNa_line>.F1KBNa_gutter+.F1KBNa_gutter{left:44px}.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{--diff-row-tint:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 20%, transparent);background-color:var(--diff-row-tint)}.F1KBNa_add{--diff-row-tint:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 18%, transparent);background-color:var(--diff-row-tint)}.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{overscroll-behavior-x:none;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)) 20%, transparent)}.F1KBNa_splitLadd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 18%, transparent)}.F1KBNa_splitRdel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 20%, transparent)}.F1KBNa_splitRadd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 18%, transparent)}.F1KBNa_intraDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 34%, transparent);text-decoration:line-through}.F1KBNa_intraAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 32%, 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);-webkit-user-select:none;user-select:none;border-radius:12px;flex-direction:column;display:flex;position:fixed;inset:8px 8px 128px;overflow:hidden}.F1KBNa_panel .F1KBNa_code,.F1KBNa_panel .F1KBNa_mdPreviewBody,.F1KBNa_panel .F1KBNa_discussionUser,.F1KBNa_panel .F1KBNa_discussionAnswer,.F1KBNa_panel .F1KBNa_quoteText,.F1KBNa_panel .F1KBNa_diffPath,.F1KBNa_panel .F1KBNa_rowPath,.F1KBNa_panel input,.F1KBNa_panel textarea,.F1KBNa_panel [contenteditable]{-webkit-user-select:text;user-select:text}.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{overscroll-behavior:none;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{overscroll-behavior-x:none;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 0 10px 8px;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:260px;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:auto}.F1KBNa_addPath{justify-content:center;align-items:center;gap:4px;display:inline-flex}.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;flex:none;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_listHead{flex:none;align-items:center;gap:4px;margin:8px 1px 2px;padding-right:8px;display:flex}.F1KBNa_action.F1KBNa_addButton.F1KBNa_listFold{width:26px;height:26px}.F1KBNa_listTitle{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;font-weight:500;line-height:16px}.F1KBNa_listTabs{background:var(--dsw-alias-interactive-bg-hover);border-radius:8px;flex:auto;gap:2px;min-width:0;padding:2px;display:flex}.F1KBNa_listTab{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:6px;flex:1;justify-content:center;align-items:center;gap:6px;padding:3px 8px;font-size:12px;line-height:16px;display:inline-flex}.F1KBNa_tabCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums}.F1KBNa_listTab[aria-selected=true]{background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-primary)}.F1KBNa_commentRow{box-sizing:border-box;width:100%;color:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;padding:6px 8px;display:block}.F1KBNa_commentRow:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_commentHead{align-items:baseline;gap:6px;min-width:0;display:flex}.F1KBNa_commentLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-markdown-code-block);font-size:11px;line-height:16px;overflow:hidden}.F1KBNa_commentLost{color:var(--dsw-alias-label-tertiary);flex:none;font-size:11px;line-height:16px}.F1KBNa_commentTitle{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);font-size:12px;line-height:18px;display:block;overflow:hidden}.F1KBNa_listEmpty{color:var(--dsw-alias-label-tertiary);margin:8px 12px;font-size:12px;line-height:18px}.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_rowMenuAnchor{display:none}.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;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{appearance:none;min-width:0;font:inherit;text-overflow:ellipsis;color:var(--dsw-alias-label-primary);background:0 0;border:0;flex:1;margin-left:4px;padding:0;font-size:12px;line-height:18px;position:relative;top:1px}.F1KBNa_diffPath:focus{outline: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_gotoBox{background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv2);border-radius:12px;align-items:center;gap:8px;padding:12px;display:flex}.F1KBNa_gotoInput{border:1px solid var(--dsw-alias-border-l2);width:8em;color:inherit;font:inherit;background:0 0;border-radius:8px;padding:4px 8px}.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_actionChord{color:var(--dsw-alias-label-tertiary);margin-left:6px;font-size:11px}.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{overscroll-behavior:none;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:3;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{background:var(--dsw-alias-bg-base);display:table-row}.F1KBNa_discussionCell{display:table-cell}.F1KBNa_discussionPin{z-index:2;width:0;height:0;position:sticky;left:0}.F1KBNa_discussion{z-index:2;box-sizing:border-box;border-left:3px solid var(--dsw-alias-state-business-primary);box-shadow:inset 0 1px 0 0 color-mix(in srgb, var(--dsw-alias-label-secondary) 55%, transparent), inset 0 -1px 0 0 color-mix(in srgb, var(--dsw-alias-label-secondary) 55%, transparent), inset -1px 0 0 0 color-mix(in srgb, var(--dsw-alias-label-secondary) 55%, transparent);cursor:default;background:0 0;flex-direction:column;display:flex;position:absolute;top:0;left:0;overflow:hidden}.F1KBNa_discussionHead{font:var(--dsw-font-markdown-code-block)}.F1KBNa_discussionBody,.F1KBNa_threadFontProbe{font:var(--dsw-font-markdown-base);font-size:calc(var(--dsh-content-font-size,14px) - 2px)}.F1KBNa_threadFontProbe{visibility:hidden;pointer-events:none;width:0;height:0;position:absolute;overflow:hidden}.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-label-secondary);background:repeating-linear-gradient(135deg, var(--dsw-alias-interactive-bg-hover) 0 4px, transparent 4px 8px);background-origin:border-box}.F1KBNa_discussion[data-lost] .F1KBNa_discussionSend,.F1KBNa_discussion[data-lost] .F1KBNa_discussionSend:hover:not(:disabled),.F1KBNa_discussion[data-lost] .F1KBNa_discussionSend:disabled{background:var(--dsw-alias-label-secondary);border-color:var(--dsw-alias-label-secondary);color:var(--dsw-alias-label-primary-foreground)}.F1KBNa_discussion[data-lost] .F1KBNa_discussionUser{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 30%, transparent)}.F1KBNa_discussionAnswer{color:var(--dsw-alias-label-primary);white-space:pre-wrap;overflow-wrap:anywhere;cursor:text;margin:0;padding:0;font-family:inherit;line-height:22px}.F1KBNa_discussionUser{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);white-space:pre-wrap;overflow-wrap:anywhere;cursor:text;border-radius:8px 0 8px 8px;margin:6.6px 0 6.6px auto;padding:4.4px 11px;font-family:inherit;line-height:22px}.F1KBNa_discussionCode{box-sizing:border-box;font:var(--dsw-font-markdown-code);font-family:var(--ds-font-family-code);background:color-mix(in srgb, var(--dsw-alias-markdown-inline-code,var(--dsw-alias-interactive-bg-hover-solid)) 90%, var(--dsw-alias-label-secondary));border:.5px solid var(--dsw-alias-border-l1);border-radius:6px;align-items:center;padding:0 5px;font-size:.875em;line-height:16px;display:inline-flex}.F1KBNa_discussionBody strong{font-weight:700}.F1KBNa_discussionNote{color:var(--dsw-alias-label-secondary);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;padding:0;font-family:inherit;line-height:22px}.F1KBNa_discussionNote[data-diff-discussion-hidden]{color:var(--dsw-alias-label-tertiary)}.F1KBNa_discussionDots{margin-left:1px}.F1KBNa_discussionDots>span{animation:1.2s ease-in-out infinite F1KBNa_discussionDot}.F1KBNa_discussionDots>span:nth-child(2){animation-delay:.15s}.F1KBNa_discussionDots>span:nth-child(3){animation-delay:.3s}@keyframes F1KBNa_discussionDot{0%,60%,to{opacity:.25}30%{opacity:1}}.F1KBNa_quoteLines{table-layout:fixed;border-spacing:0;width:calc(100% + 27px);min-width:0;color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code-block);line-height:var(--dsh-diff-line-height,22px);background:color-mix(in srgb, var(--dsw-alias-interactive-bg-hover) 55%, transparent);margin:0 -12px 0 -15px;display:table}.F1KBNa_quoteAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 12%, transparent)}.F1KBNa_quoteDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 13%, transparent)}.F1KBNa_quoteLine{font-size:calc(1em * var(--dsh-diff-font-scale,1));height:var(--dsh-diff-line-height,22px);display:table-row}.F1KBNa_quoteCode{display:table-cell}.F1KBNa_quoteText{white-space:pre-wrap;overflow-wrap:anywhere;cursor:text;display:block}.F1KBNa_quoteNoWrap .F1KBNa_quoteText{white-space:pre;overflow-wrap:normal;overflow:hidden}.F1KBNa_quoteNoWrap .F1KBNa_quoteText:after{content:\"\";width:calc(var(--dsh-diff-quote-width,0px) + 100%);display:inline-block}.F1KBNa_quoteSplit{align-self:stretch;align-items:flex-start;margin:0 -12px;display:flex}.F1KBNa_quoteSplitSide{flex:1 1 0;min-width:0}.F1KBNa_quoteSplitSide+.F1KBNa_quoteSplitSide{border-left:1px solid var(--dsw-alias-border-l2)}.F1KBNa_quoteSplitTable{table-layout:fixed;border-spacing:0;width:100%;display:table}.F1KBNa_quoteNoWrap .F1KBNa_quoteSplit [data-diff-quote-side=left] .F1KBNa_quoteText:after{content:\"\";width:calc(var(--dsh-quote-width-left,0px) + 100%);display:inline-block}.F1KBNa_quoteNoWrap .F1KBNa_quoteSplit [data-diff-quote-side=right] .F1KBNa_quoteText:after{content:\"\";width:calc(var(--dsh-quote-width-right,0px) + 100%);display:inline-block}.F1KBNa_discussionHead{box-sizing:border-box;flex:none;align-items:center;gap:8px;height:22px;padding:0 12px;font-size:12px;line-height:16px;display:flex}.F1KBNa_discussionCompose{box-sizing:border-box;flex:none;align-items:flex-end;gap:8px;height:44px;margin:0 -6px;padding:0 0 6.6px;display:flex}.F1KBNa_discussionSlack{flex:1 1 0;min-height:0;max-height:22px}.F1KBNa_discussionInput{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);min-width:0;height:26px;color:var(--dsw-alias-label-primary);cursor:text;border-radius:6px;flex:auto;padding:3px 8px;font-family:inherit;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}.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;height:26px;padding-left:9px;padding-right:9px;display:inline-flex}.F1KBNa_rowDiscussed{--diff-row-wash:color-mix(in srgb, var(--dsw-alias-label-secondary) 14%, transparent);background-image:linear-gradient(var(--diff-row-wash), var(--diff-row-wash))}@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_line>.F1KBNa_gutter{z-index:1;background-color:var(--dsw-alias-markdown-code-block);background-image:linear-gradient(var(--diff-row-tint,transparent), var(--diff-row-tint,transparent)), linear-gradient(var(--diff-row-wash,transparent), var(--diff-row-wash,transparent));position:sticky;left:0}.F1KBNa_line>.F1KBNa_gutter+.F1KBNa_gutter{left:44px}.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{--diff-row-tint:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 20%, transparent);background-color:var(--diff-row-tint)}.F1KBNa_add{--diff-row-tint:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 18%, transparent);background-color:var(--diff-row-tint)}.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;min-height:100%;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_splitDiscussions{z-index:3;pointer-events:none;width:100%;height:0;position:absolute;top:0;left:0}.F1KBNa_splitDiscussion{box-sizing:border-box;pointer-events:auto;background:var(--dsw-alias-bg-base);position:absolute;left:0}.F1KBNa_splitSealed,.F1KBNa_splitSealed *{-webkit-user-select:none!important;user-select:none!important}.F1KBNa_splitSealedLeft [data-diff-split-side=left],.F1KBNa_splitSealedLeft [data-diff-split-side=left] *,.F1KBNa_splitSealedRight [data-diff-split-side=right],.F1KBNa_splitSealedRight [data-diff-split-side=right] *{-webkit-user-select:text!important;user-select:text!important}.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{overscroll-behavior-x:none;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)) 20%, transparent)}.F1KBNa_splitLadd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 18%, transparent)}.F1KBNa_splitRdel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 20%, transparent)}.F1KBNa_splitRadd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 18%, transparent)}.F1KBNa_intraDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 34%, transparent);text-decoration:line-through}.F1KBNa_intraAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 32%, 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,248 +31,260 @@ window.__ModuleLoader__.load({
|
|
|
31
31
|
document.head.appendChild(tag);
|
|
32
32
|
}
|
|
33
33
|
var PendingPanel_module_css_default = {
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"diffFlashFade": "F1KBNa_diffFlashFade",
|
|
43
|
-
"stepper": "F1KBNa_stepper",
|
|
44
|
-
"delCount": "F1KBNa_delCount",
|
|
45
|
-
"blockFlashShake": "F1KBNa_blockFlashShake",
|
|
46
|
-
"rowHead": "F1KBNa_rowHead",
|
|
47
|
-
"stepperValue": "F1KBNa_stepperValue",
|
|
48
|
-
"discussionRow": "F1KBNa_discussionRow",
|
|
49
|
-
"confirmText": "F1KBNa_confirmText",
|
|
50
|
-
"statusBar": "F1KBNa_statusBar",
|
|
51
|
-
"chip": "F1KBNa_chip",
|
|
52
|
-
"subline": "F1KBNa_subline",
|
|
53
|
-
"threadFontProbe": "F1KBNa_threadFontProbe",
|
|
54
|
-
"discussionDot": "F1KBNa_discussionDot",
|
|
55
|
-
"split": "F1KBNa_split",
|
|
56
|
-
"settingsGroupText": "F1KBNa_settingsGroupText",
|
|
57
|
-
"coverButton": "F1KBNa_coverButton",
|
|
58
|
-
"quoteNoWrap": "F1KBNa_quoteNoWrap",
|
|
59
|
-
"listTabs": "F1KBNa_listTabs",
|
|
60
|
-
"colorBackdrop": "F1KBNa_colorBackdrop",
|
|
61
|
-
"iconAction": "F1KBNa_iconAction",
|
|
62
|
-
"coverBackdrop": "F1KBNa_coverBackdrop",
|
|
34
|
+
"addCount": "F1KBNa_addCount",
|
|
35
|
+
"emptyState": "F1KBNa_emptyState",
|
|
36
|
+
"diff": "F1KBNa_diff",
|
|
37
|
+
"hint": "F1KBNa_hint",
|
|
38
|
+
"listScroll": "F1KBNa_listScroll",
|
|
39
|
+
"divergedHint": "F1KBNa_divergedHint",
|
|
40
|
+
"colorSv": "F1KBNa_colorSv",
|
|
41
|
+
"stepperButton": "F1KBNa_stepperButton",
|
|
63
42
|
"treeCaret": "F1KBNa_treeCaret",
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"rowMenuAnchor": "F1KBNa_rowMenuAnchor",
|
|
71
|
-
"pickerCheck": "F1KBNa_pickerCheck",
|
|
43
|
+
"blockActionsDivider": "F1KBNa_blockActionsDivider",
|
|
44
|
+
"discussionRangeWrap": "F1KBNa_discussionRangeWrap",
|
|
45
|
+
"pickerNote": "F1KBNa_pickerNote",
|
|
46
|
+
"quoteAdd": "F1KBNa_quoteAdd",
|
|
47
|
+
"colorPickerInput": "F1KBNa_colorPickerInput",
|
|
48
|
+
"gotoInput": "F1KBNa_gotoInput",
|
|
72
49
|
"chipLabel": "F1KBNa_chipLabel",
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"pickerName": "F1KBNa_pickerName",
|
|
77
|
-
"listTitle": "F1KBNa_listTitle",
|
|
78
|
-
"diffBody": "F1KBNa_diffBody",
|
|
79
|
-
"note": "F1KBNa_note",
|
|
80
|
-
"settingsPage": "F1KBNa_settingsPage",
|
|
81
|
-
"fileListKnob": "F1KBNa_fileListKnob",
|
|
82
|
-
"fileList": "F1KBNa_fileList",
|
|
83
|
-
"addCount": "F1KBNa_addCount",
|
|
84
|
-
"coverNoticeCard": "F1KBNa_coverNoticeCard",
|
|
85
|
-
"wrap": "F1KBNa_wrap",
|
|
86
|
-
"listEmpty": "F1KBNa_listEmpty",
|
|
87
|
-
"mdPreviewWrap": "F1KBNa_mdPreviewWrap",
|
|
50
|
+
"splitHScrollRow": "F1KBNa_splitHScrollRow",
|
|
51
|
+
"iconAction": "F1KBNa_iconAction",
|
|
52
|
+
"footerButtons": "F1KBNa_footerButtons",
|
|
88
53
|
"kindHint": "F1KBNa_kindHint",
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"
|
|
54
|
+
"del": "F1KBNa_del",
|
|
55
|
+
"missingHint": "F1KBNa_missingHint",
|
|
56
|
+
"rowDiscussed": "F1KBNa_rowDiscussed",
|
|
57
|
+
"tree": "F1KBNa_tree",
|
|
58
|
+
"states": "F1KBNa_states",
|
|
59
|
+
"diffPreviewScroll": "F1KBNa_diffPreviewScroll",
|
|
60
|
+
"settingsGroupDesc": "F1KBNa_settingsGroupDesc",
|
|
61
|
+
"confirmBackdrop": "F1KBNa_confirmBackdrop",
|
|
62
|
+
"rowMeta": "F1KBNa_rowMeta",
|
|
63
|
+
"blockActions": "F1KBNa_blockActions",
|
|
64
|
+
"markerDel": "F1KBNa_markerDel",
|
|
65
|
+
"subline": "F1KBNa_subline",
|
|
66
|
+
"confirmCard": "F1KBNa_confirmCard",
|
|
67
|
+
"searchMatch": "F1KBNa_searchMatch",
|
|
68
|
+
"badge": "F1KBNa_badge",
|
|
69
|
+
"mdPreviewBody": "F1KBNa_mdPreviewBody",
|
|
70
|
+
"blockPosition": "F1KBNa_blockPosition",
|
|
71
|
+
"splitSealedLeft": "F1KBNa_splitSealedLeft",
|
|
72
|
+
"rowMenuAnchor": "F1KBNa_rowMenuAnchor",
|
|
73
|
+
"rail": "F1KBNa_rail",
|
|
74
|
+
"colorPickerPopover": "F1KBNa_colorPickerPopover",
|
|
75
|
+
"settingsGroupText": "F1KBNa_settingsGroupText",
|
|
76
|
+
"badgeLabel": "F1KBNa_badgeLabel",
|
|
102
77
|
"lines": "F1KBNa_lines",
|
|
103
|
-
"
|
|
78
|
+
"fileListFloatClosing": "F1KBNa_fileListFloatClosing",
|
|
79
|
+
"group": "F1KBNa_group",
|
|
80
|
+
"groupHead": "F1KBNa_groupHead",
|
|
81
|
+
"quoteSplit": "F1KBNa_quoteSplit",
|
|
82
|
+
"splitCol": "F1KBNa_splitCol",
|
|
83
|
+
"expand": "F1KBNa_expand",
|
|
84
|
+
"chip": "F1KBNa_chip",
|
|
85
|
+
"discussionRange": "F1KBNa_discussionRange",
|
|
86
|
+
"mdPreviewDouble": "F1KBNa_mdPreviewDouble",
|
|
87
|
+
"coverCard": "F1KBNa_coverCard",
|
|
88
|
+
"fileListShrink": "F1KBNa_fileListShrink",
|
|
89
|
+
"confirmText": "F1KBNa_confirmText",
|
|
90
|
+
"discussionCode": "F1KBNa_discussionCode",
|
|
91
|
+
"stepperButtonUp": "F1KBNa_stepperButtonUp",
|
|
92
|
+
"listTab": "F1KBNa_listTab",
|
|
93
|
+
"colorSvCursor": "F1KBNa_colorSvCursor",
|
|
94
|
+
"diffHeader": "F1KBNa_diffHeader",
|
|
95
|
+
"detailEmpty": "F1KBNa_detailEmpty",
|
|
96
|
+
"blockFlash": "F1KBNa_blockFlash",
|
|
97
|
+
"settingsRow": "F1KBNa_settingsRow",
|
|
98
|
+
"kindTag": "F1KBNa_kindTag",
|
|
99
|
+
"splitSealedRight": "F1KBNa_splitSealedRight",
|
|
100
|
+
"context": "F1KBNa_context",
|
|
101
|
+
"pickerForm": "F1KBNa_pickerForm",
|
|
102
|
+
"importNote": "F1KBNa_importNote",
|
|
104
103
|
"searchBar": "F1KBNa_searchBar",
|
|
105
|
-
"
|
|
106
|
-
"
|
|
104
|
+
"langLabel": "F1KBNa_langLabel",
|
|
105
|
+
"toggleThumb": "F1KBNa_toggleThumb",
|
|
106
|
+
"bulkActions": "F1KBNa_bulkActions",
|
|
107
|
+
"noticeButton": "F1KBNa_noticeButton",
|
|
108
|
+
"discussionDot": "F1KBNa_discussionDot",
|
|
109
|
+
"listHead": "F1KBNa_listHead",
|
|
110
|
+
"gutter": "F1KBNa_gutter",
|
|
107
111
|
"rows": "F1KBNa_rows",
|
|
108
|
-
"
|
|
109
|
-
"
|
|
112
|
+
"settingsRowTitle": "F1KBNa_settingsRowTitle",
|
|
113
|
+
"action": "F1KBNa_action",
|
|
114
|
+
"panelFailureText": "F1KBNa_panelFailureText",
|
|
115
|
+
"layer": "F1KBNa_layer",
|
|
116
|
+
"mirrored": "F1KBNa_mirrored",
|
|
117
|
+
"toggleOn": "F1KBNa_toggleOn",
|
|
118
|
+
"actionPrimary": "F1KBNa_actionPrimary",
|
|
119
|
+
"note": "F1KBNa_note",
|
|
120
|
+
"rowHead": "F1KBNa_rowHead",
|
|
121
|
+
"threadFontProbe": "F1KBNa_threadFontProbe",
|
|
122
|
+
"settingsPage": "F1KBNa_settingsPage",
|
|
123
|
+
"colorSwatch": "F1KBNa_colorSwatch",
|
|
124
|
+
"pickerTitle": "F1KBNa_pickerTitle",
|
|
125
|
+
"discussionHead": "F1KBNa_discussionHead",
|
|
126
|
+
"quoteCode": "F1KBNa_quoteCode",
|
|
127
|
+
"settingsRowText": "F1KBNa_settingsRowText",
|
|
128
|
+
"discussionUser": "F1KBNa_discussionUser",
|
|
129
|
+
"readError": "F1KBNa_readError",
|
|
130
|
+
"panelFailureRetry": "F1KBNa_panelFailureRetry",
|
|
110
131
|
"coverNoticeGlyph": "F1KBNa_coverNoticeGlyph",
|
|
111
|
-
"
|
|
112
|
-
"markerDel": "F1KBNa_markerDel",
|
|
113
|
-
"colorPickerInput": "F1KBNa_colorPickerInput",
|
|
114
|
-
"treeRow": "F1KBNa_treeRow",
|
|
115
|
-
"blockPosition": "F1KBNa_blockPosition",
|
|
116
|
-
"discussionRangeWrap": "F1KBNa_discussionRangeWrap",
|
|
132
|
+
"fileListFloat": "F1KBNa_fileListFloat",
|
|
117
133
|
"coverNotice": "F1KBNa_coverNotice",
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"discussionCompose": "F1KBNa_discussionCompose",
|
|
125
|
-
"chipPresentation": "F1KBNa_chipPresentation",
|
|
126
|
-
"diffPreviewScroll": "F1KBNa_diffPreviewScroll",
|
|
134
|
+
"discussionAnswer": "F1KBNa_discussionAnswer",
|
|
135
|
+
"coverNoticeFade": "F1KBNa_coverNoticeFade",
|
|
136
|
+
"coverBackdrop": "F1KBNa_coverBackdrop",
|
|
137
|
+
"listEmpty": "F1KBNa_listEmpty",
|
|
138
|
+
"vSpacer": "F1KBNa_vSpacer",
|
|
139
|
+
"split": "F1KBNa_split",
|
|
127
140
|
"divider": "F1KBNa_divider",
|
|
128
|
-
"
|
|
129
|
-
"
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
"stepperButton": "F1KBNa_stepperButton",
|
|
139
|
-
"fileListKnobIn": "F1KBNa_fileListKnobIn",
|
|
141
|
+
"pickerIcon": "F1KBNa_pickerIcon",
|
|
142
|
+
"headerActions": "F1KBNa_headerActions",
|
|
143
|
+
"settingsReset": "F1KBNa_settingsReset",
|
|
144
|
+
"coverPopover": "F1KBNa_coverPopover",
|
|
145
|
+
"addButton": "F1KBNa_addButton",
|
|
146
|
+
"diffPath": "F1KBNa_diffPath",
|
|
147
|
+
"commentLost": "F1KBNa_commentLost",
|
|
148
|
+
"stepper": "F1KBNa_stepper",
|
|
149
|
+
"searchInput": "F1KBNa_searchInput",
|
|
150
|
+
"statusBar": "F1KBNa_statusBar",
|
|
140
151
|
"splitLdel": "F1KBNa_splitLdel",
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"
|
|
152
|
+
"colorPickerInputRow": "F1KBNa_colorPickerInputRow",
|
|
153
|
+
"listFold": "F1KBNa_listFold",
|
|
154
|
+
"quoteSplitSide": "F1KBNa_quoteSplitSide",
|
|
155
|
+
"markerAdd": "F1KBNa_markerAdd",
|
|
156
|
+
"overviewRuler": "F1KBNa_overviewRuler",
|
|
157
|
+
"badgeCount": "F1KBNa_badgeCount",
|
|
145
158
|
"settingsGroupBody": "F1KBNa_settingsGroupBody",
|
|
146
|
-
"diffStats": "F1KBNa_diffStats",
|
|
147
|
-
"coverHost": "F1KBNa_coverHost",
|
|
148
|
-
"settingsReset": "F1KBNa_settingsReset",
|
|
149
|
-
"mdPreviewFallback": "F1KBNa_mdPreviewFallback",
|
|
150
|
-
"confirmCard": "F1KBNa_confirmCard",
|
|
151
|
-
"discussionToggle": "F1KBNa_discussionToggle",
|
|
152
|
-
"rowDiscussed": "F1KBNa_rowDiscussed",
|
|
153
|
-
"coverCard": "F1KBNa_coverCard",
|
|
154
|
-
"settingsSelector": "F1KBNa_settingsSelector",
|
|
155
|
-
"pickerTitle": "F1KBNa_pickerTitle",
|
|
156
|
-
"colorPickerPreview": "F1KBNa_colorPickerPreview",
|
|
157
|
-
"headerEntry": "F1KBNa_headerEntry",
|
|
158
159
|
"panelDocked": "F1KBNa_panelDocked",
|
|
159
|
-
"listFold": "F1KBNa_listFold",
|
|
160
|
-
"rowPath": "F1KBNa_rowPath",
|
|
161
|
-
"toggleOn": "F1KBNa_toggleOn",
|
|
162
|
-
"missingHint": "F1KBNa_missingHint",
|
|
163
|
-
"rowFailed": "F1KBNa_rowFailed",
|
|
164
|
-
"mdPreviewDouble": "F1KBNa_mdPreviewDouble",
|
|
165
|
-
"discussionBody": "F1KBNa_discussionBody",
|
|
166
|
-
"detail": "F1KBNa_detail",
|
|
167
|
-
"splitCol": "F1KBNa_splitCol",
|
|
168
|
-
"code": "F1KBNa_code",
|
|
169
|
-
"mdPreviewContent": "F1KBNa_mdPreviewContent",
|
|
170
|
-
"diffPreview": "F1KBNa_diffPreview",
|
|
171
|
-
"quoteLine": "F1KBNa_quoteLine",
|
|
172
|
-
"colorSv": "F1KBNa_colorSv",
|
|
173
|
-
"mdPreviewBody": "F1KBNa_mdPreviewBody",
|
|
174
|
-
"discussionUser": "F1KBNa_discussionUser",
|
|
175
|
-
"addButton": "F1KBNa_addButton",
|
|
176
|
-
"discussionCode": "F1KBNa_discussionCode",
|
|
177
|
-
"headerEntryCount": "F1KBNa_headerEntryCount",
|
|
178
|
-
"settingsRowText": "F1KBNa_settingsRowText",
|
|
179
|
-
"panelFailure": "F1KBNa_panelFailure",
|
|
180
|
-
"pickerIcon": "F1KBNa_pickerIcon",
|
|
181
|
-
"rail": "F1KBNa_rail",
|
|
182
|
-
"pickerForm": "F1KBNa_pickerForm",
|
|
183
|
-
"langSelect": "F1KBNa_langSelect",
|
|
184
|
-
"discussionAnswer": "F1KBNa_discussionAnswer",
|
|
185
|
-
"fileListFloat": "F1KBNa_fileListFloat",
|
|
186
|
-
"diff": "F1KBNa_diff",
|
|
187
|
-
"panelFailureText": "F1KBNa_panelFailureText",
|
|
188
|
-
"splitCols": "F1KBNa_splitCols",
|
|
189
|
-
"intraAdd": "F1KBNa_intraAdd",
|
|
190
|
-
"colorPickerTrigger": "F1KBNa_colorPickerTrigger",
|
|
191
|
-
"divergedHint": "F1KBNa_divergedHint",
|
|
192
|
-
"intraDel": "F1KBNa_intraDel",
|
|
193
|
-
"panelFailureRetry": "F1KBNa_panelFailureRetry",
|
|
194
|
-
"diffPreviewTitle": "F1KBNa_diffPreviewTitle",
|
|
195
|
-
"kindTag": "F1KBNa_kindTag",
|
|
196
|
-
"context": "F1KBNa_context",
|
|
197
|
-
"groupHead": "F1KBNa_groupHead",
|
|
198
|
-
"panel": "F1KBNa_panel",
|
|
199
|
-
"bulkActions": "F1KBNa_bulkActions",
|
|
200
|
-
"group": "F1KBNa_group",
|
|
201
|
-
"resizeHandle": "F1KBNa_resizeHandle",
|
|
202
|
-
"actionError": "F1KBNa_actionError",
|
|
203
|
-
"searchMatch": "F1KBNa_searchMatch",
|
|
204
160
|
"colorPickerPanel": "F1KBNa_colorPickerPanel",
|
|
205
|
-
"
|
|
206
|
-
"markerAdd": "F1KBNa_markerAdd",
|
|
207
|
-
"states": "F1KBNa_states",
|
|
208
|
-
"actionPrimary": "F1KBNa_actionPrimary",
|
|
209
|
-
"discussionCell": "F1KBNa_discussionCell",
|
|
210
|
-
"dockHost": "F1KBNa_dockHost",
|
|
211
|
-
"del": "F1KBNa_del",
|
|
212
|
-
"quoteDel": "F1KBNa_quoteDel",
|
|
161
|
+
"pickerCheck": "F1KBNa_pickerCheck",
|
|
213
162
|
"searchCount": "F1KBNa_searchCount",
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
-
"
|
|
218
|
-
"
|
|
219
|
-
"emptyState": "F1KBNa_emptyState",
|
|
220
|
-
"tree": "F1KBNa_tree",
|
|
221
|
-
"pickerNote": "F1KBNa_pickerNote",
|
|
222
|
-
"title": "F1KBNa_title",
|
|
163
|
+
"splitHScrollFill": "F1KBNa_splitHScrollFill",
|
|
164
|
+
"settingsGroupHeader": "F1KBNa_settingsGroupHeader",
|
|
165
|
+
"expandExpanded": "F1KBNa_expandExpanded",
|
|
166
|
+
"searchToggle": "F1KBNa_searchToggle",
|
|
167
|
+
"presentationHost": "F1KBNa_presentationHost",
|
|
223
168
|
"line": "F1KBNa_line",
|
|
169
|
+
"close": "F1KBNa_close",
|
|
224
170
|
"discussionInput": "F1KBNa_discussionInput",
|
|
225
|
-
"colorSvCursor": "F1KBNa_colorSvCursor",
|
|
226
|
-
"confirmBackdrop": "F1KBNa_confirmBackdrop",
|
|
227
|
-
"blockActionsDivider": "F1KBNa_blockActionsDivider",
|
|
228
|
-
"colorValue": "F1KBNa_colorValue",
|
|
229
|
-
"badgeLabel": "F1KBNa_badgeLabel",
|
|
230
|
-
"diffHeader": "F1KBNa_diffHeader",
|
|
231
|
-
"diffActions": "F1KBNa_diffActions",
|
|
232
|
-
"noteCentered": "F1KBNa_noteCentered",
|
|
233
|
-
"diffBodySplit": "F1KBNa_diffBodySplit",
|
|
234
|
-
"pickerCard": "F1KBNa_pickerCard",
|
|
235
171
|
"settingsRowDesc": "F1KBNa_settingsRowDesc",
|
|
236
172
|
"treeName": "F1KBNa_treeName",
|
|
237
|
-
"
|
|
238
|
-
"
|
|
239
|
-
"
|
|
240
|
-
"
|
|
241
|
-
"
|
|
242
|
-
"
|
|
243
|
-
"
|
|
244
|
-
"
|
|
245
|
-
"
|
|
246
|
-
"
|
|
247
|
-
"
|
|
248
|
-
"
|
|
173
|
+
"quoteNoWrap": "F1KBNa_quoteNoWrap",
|
|
174
|
+
"splitDiscussions": "F1KBNa_splitDiscussions",
|
|
175
|
+
"fileListKnobIn": "F1KBNa_fileListKnobIn",
|
|
176
|
+
"splitDiscussion": "F1KBNa_splitDiscussion",
|
|
177
|
+
"listTitle": "F1KBNa_listTitle",
|
|
178
|
+
"commentTitle": "F1KBNa_commentTitle",
|
|
179
|
+
"detail": "F1KBNa_detail",
|
|
180
|
+
"colorPicker": "F1KBNa_colorPicker",
|
|
181
|
+
"diffPreviewTitle": "F1KBNa_diffPreviewTitle",
|
|
182
|
+
"colorHueCursor": "F1KBNa_colorHueCursor",
|
|
183
|
+
"discussionCompose": "F1KBNa_discussionCompose",
|
|
184
|
+
"coverButton": "F1KBNa_coverButton",
|
|
185
|
+
"discussionDots": "F1KBNa_discussionDots",
|
|
186
|
+
"discussionSlack": "F1KBNa_discussionSlack",
|
|
249
187
|
"mdPreviewSingle": "F1KBNa_mdPreviewSingle",
|
|
188
|
+
"colorPickerTrigger": "F1KBNa_colorPickerTrigger",
|
|
189
|
+
"searchMatchCurrent": "F1KBNa_searchMatchCurrent",
|
|
190
|
+
"confirmActions": "F1KBNa_confirmActions",
|
|
250
191
|
"presentationSelect": "F1KBNa_presentationSelect",
|
|
251
|
-
"
|
|
252
|
-
"
|
|
192
|
+
"panel": "F1KBNa_panel",
|
|
193
|
+
"noticeText": "F1KBNa_noticeText",
|
|
194
|
+
"diffFlashFade": "F1KBNa_diffFlashFade",
|
|
195
|
+
"splitHScroll": "F1KBNa_splitHScroll",
|
|
196
|
+
"resizeHandle": "F1KBNa_resizeHandle",
|
|
197
|
+
"stepperValue": "F1KBNa_stepperValue",
|
|
198
|
+
"colorBackdrop": "F1KBNa_colorBackdrop",
|
|
199
|
+
"quoteText": "F1KBNa_quoteText",
|
|
200
|
+
"coverNoticeCard": "F1KBNa_coverNoticeCard",
|
|
201
|
+
"coverNoticeText": "F1KBNa_coverNoticeText",
|
|
202
|
+
"notice": "F1KBNa_notice",
|
|
203
|
+
"settingsGroup": "F1KBNa_settingsGroup",
|
|
204
|
+
"pickerCard": "F1KBNa_pickerCard",
|
|
205
|
+
"splitRoot": "F1KBNa_splitRoot",
|
|
206
|
+
"listTabs": "F1KBNa_listTabs",
|
|
207
|
+
"splitCols": "F1KBNa_splitCols",
|
|
208
|
+
"delCount": "F1KBNa_delCount",
|
|
209
|
+
"splitSealed": "F1KBNa_splitSealed",
|
|
210
|
+
"actionQuietDisabled": "F1KBNa_actionQuietDisabled",
|
|
211
|
+
"quoteDel": "F1KBNa_quoteDel",
|
|
212
|
+
"discussionBody": "F1KBNa_discussionBody",
|
|
213
|
+
"diffStats": "F1KBNa_diffStats",
|
|
214
|
+
"intraDel": "F1KBNa_intraDel",
|
|
215
|
+
"colorPickerChevron": "F1KBNa_colorPickerChevron",
|
|
216
|
+
"dockHost": "F1KBNa_dockHost",
|
|
217
|
+
"gotoBox": "F1KBNa_gotoBox",
|
|
218
|
+
"splitDivider": "F1KBNa_splitDivider",
|
|
219
|
+
"discussionToggle": "F1KBNa_discussionToggle",
|
|
220
|
+
"diffBodySplit": "F1KBNa_diffBodySplit",
|
|
221
|
+
"discussionRow": "F1KBNa_discussionRow",
|
|
222
|
+
"commentLabel": "F1KBNa_commentLabel",
|
|
223
|
+
"settingsGroupChevron": "F1KBNa_settingsGroupChevron",
|
|
224
|
+
"splitLadd": "F1KBNa_splitLadd",
|
|
253
225
|
"diffBodyWrap": "F1KBNa_diffBodyWrap",
|
|
226
|
+
"colorValue": "F1KBNa_colorValue",
|
|
227
|
+
"overviewMarker": "F1KBNa_overviewMarker",
|
|
228
|
+
"rowFailed": "F1KBNa_rowFailed",
|
|
229
|
+
"searchToggleOn": "F1KBNa_searchToggleOn",
|
|
230
|
+
"actionChord": "F1KBNa_actionChord",
|
|
231
|
+
"mdPreviewWrap": "F1KBNa_mdPreviewWrap",
|
|
232
|
+
"mdPreviewFallback": "F1KBNa_mdPreviewFallback",
|
|
233
|
+
"wrapActive": "F1KBNa_wrapActive",
|
|
234
|
+
"mdPreviewContent": "F1KBNa_mdPreviewContent",
|
|
235
|
+
"pickerName": "F1KBNa_pickerName",
|
|
236
|
+
"rowPath": "F1KBNa_rowPath",
|
|
237
|
+
"fileList": "F1KBNa_fileList",
|
|
238
|
+
"settingsSelector": "F1KBNa_settingsSelector",
|
|
239
|
+
"commentRow": "F1KBNa_commentRow",
|
|
240
|
+
"commentHead": "F1KBNa_commentHead",
|
|
241
|
+
"treeRow": "F1KBNa_treeRow",
|
|
242
|
+
"diffActions": "F1KBNa_diffActions",
|
|
243
|
+
"diffBody": "F1KBNa_diffBody",
|
|
244
|
+
"actionError": "F1KBNa_actionError",
|
|
245
|
+
"importButton": "F1KBNa_importButton",
|
|
246
|
+
"pickerInput": "F1KBNa_pickerInput",
|
|
247
|
+
"splitRadd": "F1KBNa_splitRadd",
|
|
248
|
+
"code": "F1KBNa_code",
|
|
254
249
|
"floatResizeHandle": "F1KBNa_floatResizeHandle",
|
|
255
|
-
"
|
|
256
|
-
"
|
|
257
|
-
"
|
|
258
|
-
"actionChord": "F1KBNa_actionChord",
|
|
259
|
-
"fileListShrink": "F1KBNa_fileListShrink",
|
|
260
|
-
"commentTitle": "F1KBNa_commentTitle",
|
|
261
|
-
"importNote": "F1KBNa_importNote",
|
|
262
|
-
"confirmActions": "F1KBNa_confirmActions",
|
|
263
|
-
"footerButtons": "F1KBNa_footerButtons",
|
|
250
|
+
"blockFlashShake": "F1KBNa_blockFlashShake",
|
|
251
|
+
"discussionSend": "F1KBNa_discussionSend",
|
|
252
|
+
"noteCentered": "F1KBNa_noteCentered",
|
|
264
253
|
"header": "F1KBNa_header",
|
|
265
|
-
"
|
|
254
|
+
"add": "F1KBNa_add",
|
|
255
|
+
"chipPresentation": "F1KBNa_chipPresentation",
|
|
266
256
|
"toggle": "F1KBNa_toggle",
|
|
267
|
-
"discussion": "F1KBNa_discussion",
|
|
268
|
-
"headerActions": "F1KBNa_headerActions",
|
|
269
257
|
"statusAction": "F1KBNa_statusAction",
|
|
258
|
+
"intraAdd": "F1KBNa_intraAdd",
|
|
259
|
+
"title": "F1KBNa_title",
|
|
260
|
+
"row": "F1KBNa_row",
|
|
261
|
+
"headerEntryCount": "F1KBNa_headerEntryCount",
|
|
262
|
+
"settingsGroupTitle": "F1KBNa_settingsGroupTitle",
|
|
263
|
+
"flexSpacer": "F1KBNa_flexSpacer",
|
|
264
|
+
"discussionPin": "F1KBNa_discussionPin",
|
|
265
|
+
"discussionNote": "F1KBNa_discussionNote",
|
|
266
|
+
"discussionCell": "F1KBNa_discussionCell",
|
|
267
|
+
"quoteLine": "F1KBNa_quoteLine",
|
|
268
|
+
"splitRdel": "F1KBNa_splitRdel",
|
|
269
|
+
"langSelect": "F1KBNa_langSelect",
|
|
270
|
+
"coverHost": "F1KBNa_coverHost",
|
|
271
|
+
"headerEntry": "F1KBNa_headerEntry",
|
|
272
|
+
"discussion": "F1KBNa_discussion",
|
|
273
|
+
"quoteLines": "F1KBNa_quoteLines",
|
|
270
274
|
"treeNote": "F1KBNa_treeNote",
|
|
271
|
-
"
|
|
272
|
-
"
|
|
273
|
-
"
|
|
274
|
-
"
|
|
275
|
-
"
|
|
275
|
+
"colorHue": "F1KBNa_colorHue",
|
|
276
|
+
"addPath": "F1KBNa_addPath",
|
|
277
|
+
"wrap": "F1KBNa_wrap",
|
|
278
|
+
"colorPickerPreview": "F1KBNa_colorPickerPreview",
|
|
279
|
+
"pickerClose": "F1KBNa_pickerClose",
|
|
280
|
+
"quoteSplitTable": "F1KBNa_quoteSplitTable",
|
|
281
|
+
"diffFlashShake": "F1KBNa_diffFlashShake",
|
|
282
|
+
"emptyActions": "F1KBNa_emptyActions",
|
|
283
|
+
"missing": "F1KBNa_missing",
|
|
284
|
+
"diffPreview": "F1KBNa_diffPreview",
|
|
285
|
+
"tabCount": "F1KBNa_tabCount",
|
|
286
|
+
"panelFailure": "F1KBNa_panelFailure",
|
|
287
|
+
"fileListKnob": "F1KBNa_fileListKnob"
|
|
276
288
|
};
|
|
277
289
|
//#endregion
|
|
278
290
|
//#region lib/types/client/PathPicker.js
|
|
@@ -1188,6 +1200,7 @@ window.__ModuleLoader__.load({
|
|
|
1188
1200
|
jumpDown: "Ctrl+ArrowDown",
|
|
1189
1201
|
copyRef: "Ctrl+L",
|
|
1190
1202
|
addComment: "Ctrl+K",
|
|
1203
|
+
goto: "Ctrl+G",
|
|
1191
1204
|
openSearch: "Ctrl+F",
|
|
1192
1205
|
searchNext: "F3",
|
|
1193
1206
|
searchPrev: "Shift+F3",
|
|
@@ -2959,9 +2972,9 @@ window.__ModuleLoader__.load({
|
|
|
2959
2972
|
* @param rowCount - how many rows the current model has.
|
|
2960
2973
|
* @returns the re-anchored blocks, in the order they came in.
|
|
2961
2974
|
*/
|
|
2962
|
-
function remapDiscussions(discussions, lineOf, textOf, rowCount) {
|
|
2975
|
+
function remapDiscussions(discussions, lineOf, textOf, rowCount, hasNewLine = () => true) {
|
|
2963
2976
|
const windows = windowCache(textOf, rowCount);
|
|
2964
|
-
return discussions.map((discussion) => remapOne(discussion, lineOf, textOf, rowCount, windows));
|
|
2977
|
+
return discussions.map((discussion) => remapOne(discussion, lineOf, textOf, rowCount, windows, hasNewLine));
|
|
2965
2978
|
}
|
|
2966
2979
|
/** Every row window of one span, indexed by its text, in one pass over the rows. */
|
|
2967
2980
|
function windowIndex(textOf, rowCount, span) {
|
|
@@ -2989,7 +3002,7 @@ window.__ModuleLoader__.load({
|
|
|
2989
3002
|
};
|
|
2990
3003
|
}
|
|
2991
3004
|
/** The body both entry points share: one block, with the row windows read through `windows`. */
|
|
2992
|
-
function remapOne(discussion, lineOf, textOf, rowCount, windows) {
|
|
3005
|
+
function remapOne(discussion, lineOf, textOf, rowCount, windows, hasNewLine) {
|
|
2993
3006
|
const { startLine, endLine } = discussion.anchor;
|
|
2994
3007
|
let start = -1;
|
|
2995
3008
|
let end = -1;
|
|
@@ -3036,29 +3049,63 @@ window.__ModuleLoader__.load({
|
|
|
3036
3049
|
}
|
|
3037
3050
|
});
|
|
3038
3051
|
};
|
|
3039
|
-
|
|
3052
|
+
/** The block live again on `row`..`row + span` (the same object when it was already there). */
|
|
3053
|
+
const live = (row, last) => row === discussion.anchor.start && last === discussion.anchor.end ? clearOutdated(discussion) : clearOutdated({
|
|
3054
|
+
...discussion,
|
|
3055
|
+
anchor: {
|
|
3056
|
+
...discussion.anchor,
|
|
3057
|
+
start: row,
|
|
3058
|
+
end: last
|
|
3059
|
+
}
|
|
3060
|
+
});
|
|
3061
|
+
/**
|
|
3062
|
+
* The window's text with one line of context on each side, in the current model.
|
|
3063
|
+
*
|
|
3064
|
+
* Compared against the context the thread recorded when it was made (see `quoteContext`): that is
|
|
3065
|
+
* what tells a genuine move of the quoted code from another line elsewhere in the file that happens
|
|
3066
|
+
* to read the same.
|
|
3067
|
+
*/
|
|
3068
|
+
const contextAt = (row) => {
|
|
3069
|
+
const parts = [];
|
|
3070
|
+
for (let index = Math.max(0, row - 1); index <= Math.min(rowCount - 1, row + span + 1); index++) parts.push(textOf(index));
|
|
3071
|
+
return parts.join("\n");
|
|
3072
|
+
};
|
|
3073
|
+
if (quote === void 0) {
|
|
3040
3074
|
if (start === -1) return gone();
|
|
3041
|
-
|
|
3042
|
-
|
|
3075
|
+
return live(start, end);
|
|
3076
|
+
}
|
|
3077
|
+
if (start !== -1 && textAt(start) === quote) return live(start, end);
|
|
3078
|
+
if (start !== -1) {
|
|
3079
|
+
const fingerprint = discussion.quoteContext;
|
|
3080
|
+
let found = -1;
|
|
3081
|
+
for (const row of windows(span).get(quote) ?? []) {
|
|
3082
|
+
let current = false;
|
|
3083
|
+
for (let index = row; index <= row + span; index++) if (hasNewLine(index)) {
|
|
3084
|
+
current = true;
|
|
3085
|
+
break;
|
|
3086
|
+
}
|
|
3087
|
+
if (!current) continue;
|
|
3088
|
+
if (fingerprint !== void 0 && contextAt(row) !== fingerprint) continue;
|
|
3089
|
+
if (found === -1 || Math.abs(row - start) < Math.abs(found - start)) found = row;
|
|
3090
|
+
}
|
|
3091
|
+
if (found !== -1) return clearOutdated({
|
|
3043
3092
|
...discussion,
|
|
3044
3093
|
anchor: {
|
|
3045
3094
|
...discussion.anchor,
|
|
3046
|
-
start,
|
|
3047
|
-
end
|
|
3095
|
+
start: found,
|
|
3096
|
+
end: found + span,
|
|
3097
|
+
startLine: lineOf(found) ?? startLine,
|
|
3098
|
+
endLine: lineOf(found + span) ?? endLine
|
|
3048
3099
|
}
|
|
3049
3100
|
});
|
|
3050
3101
|
}
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
if (found === -1) return start === -1 ? gone() : markOutdated(discussion);
|
|
3054
|
-
return clearOutdated({
|
|
3102
|
+
if (start === -1) return gone();
|
|
3103
|
+
return markOutdated({
|
|
3055
3104
|
...discussion,
|
|
3056
3105
|
anchor: {
|
|
3057
3106
|
...discussion.anchor,
|
|
3058
|
-
start
|
|
3059
|
-
end
|
|
3060
|
-
startLine: lineOf(found) ?? startLine,
|
|
3061
|
-
endLine: lineOf(found + span) ?? endLine
|
|
3107
|
+
start,
|
|
3108
|
+
end
|
|
3062
3109
|
}
|
|
3063
3110
|
});
|
|
3064
3111
|
}
|
|
@@ -19364,7 +19411,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
19364
19411
|
guide: [{
|
|
19365
19412
|
order: DIFF_DOCK_GUIDE_ORDER,
|
|
19366
19413
|
title: () => copy.title(),
|
|
19367
|
-
description: () => copy.guideDescription()
|
|
19414
|
+
description: () => copy.guideDescription(),
|
|
19415
|
+
icon: _deepseek_ai_dsh_client_ui_primitives.IconListPenOutline16
|
|
19368
19416
|
}]
|
|
19369
19417
|
}), "diff-approval: right-sidebar tab type");
|
|
19370
19418
|
return true;
|
|
@@ -19449,6 +19497,59 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
19449
19497
|
if (typeof window === "undefined") return;
|
|
19450
19498
|
window.dispatchEvent(new CustomEvent(COMMENTS_CHANGED_EVENT, { detail: { sessionId } }));
|
|
19451
19499
|
}
|
|
19500
|
+
/**
|
|
19501
|
+
* End one comment, wherever it came from.
|
|
19502
|
+
*
|
|
19503
|
+
* The threads belong to the file detail, which writes them here on every change — but the list
|
|
19504
|
+
* pane shows them all and ends them too, and it has no way to reach into another component's
|
|
19505
|
+
* state. So the list asks the memory, and the detail reads the memory back on the event this
|
|
19506
|
+
* fires (see `COMMENTS_CHANGED_EVENT`): one record, one action, whichever pane the reader used.
|
|
19507
|
+
*
|
|
19508
|
+
* @param sessionId - the session the panel is reviewing; nothing is forgotten without one.
|
|
19509
|
+
* @param fileId - the pending entry the thread hangs in.
|
|
19510
|
+
* @param discussionId - the thread to end; an id that is not there changes nothing.
|
|
19511
|
+
*/
|
|
19512
|
+
function forgetDiscussion(sessionId, fileId, discussionId) {
|
|
19513
|
+
if (sessionId === void 0) return;
|
|
19514
|
+
const before = threads.get(sessionId);
|
|
19515
|
+
const list = before?.[fileId];
|
|
19516
|
+
if (list === void 0) return;
|
|
19517
|
+
const next = list.filter((entry) => entry.id !== discussionId);
|
|
19518
|
+
if (next.length === list.length) return;
|
|
19519
|
+
rememberDiscussions(sessionId, {
|
|
19520
|
+
...before,
|
|
19521
|
+
[fileId]: next
|
|
19522
|
+
});
|
|
19523
|
+
}
|
|
19524
|
+
/**
|
|
19525
|
+
* The files this page has been told to stop asking about, by session.
|
|
19526
|
+
*
|
|
19527
|
+
* Keeping or reverting a file asks whether the row should leave the list, and a reader working
|
|
19528
|
+
* through one file's blocks answers that the same way every time. Ticking the box in that prompt is
|
|
19529
|
+
* a fact about this visit rather than a preference — it is not the host's to keep, and a reload
|
|
19530
|
+
* starts clean, exactly like the threads above.
|
|
19531
|
+
*/
|
|
19532
|
+
const quietRemovals = /* @__PURE__ */ new Map();
|
|
19533
|
+
/**
|
|
19534
|
+
* Whether the reader asked not to be asked again about removing one file.
|
|
19535
|
+
* @param sessionId - the session the panel is reviewing; nothing is quiet without one.
|
|
19536
|
+
* @param fileId - the pending entry the question was about.
|
|
19537
|
+
* @returns true when the action should run without the question.
|
|
19538
|
+
*/
|
|
19539
|
+
function removalAskQuiet(sessionId, fileId) {
|
|
19540
|
+
return sessionId === void 0 ? false : quietRemovals.get(sessionId)?.has(fileId) === true;
|
|
19541
|
+
}
|
|
19542
|
+
/**
|
|
19543
|
+
* Stop asking whether one file should leave the list, for the rest of this page.
|
|
19544
|
+
* @param sessionId - the session the panel is reviewing; nothing is recorded without one.
|
|
19545
|
+
* @param fileId - the pending entry the question was about.
|
|
19546
|
+
*/
|
|
19547
|
+
function quietenRemovalAsk(sessionId, fileId) {
|
|
19548
|
+
if (sessionId === void 0) return;
|
|
19549
|
+
const files = quietRemovals.get(sessionId);
|
|
19550
|
+
if (files === void 0) quietRemovals.set(sessionId, /* @__PURE__ */ new Set([fileId]));
|
|
19551
|
+
else files.add(fileId);
|
|
19552
|
+
}
|
|
19452
19553
|
/** This session's record, created on first use. */
|
|
19453
19554
|
function viewOf(sessionId) {
|
|
19454
19555
|
let view = views.get(sessionId);
|
|
@@ -19677,8 +19778,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
19677
19778
|
const COMPOSER_HEIGHT_VAR = "--dsh-composer-height";
|
|
19678
19779
|
/** Seat counts as docked when its bottom is this close to the window bottom. */
|
|
19679
19780
|
const DOCKED_TOLERANCE_PX = 48;
|
|
19680
|
-
/** File-list pane width bounds for the manual split drag, in px. */
|
|
19681
|
-
const MIN_LIST_WIDTH_PX = 160;
|
|
19682
19781
|
const MAX_LIST_WIDTH_PX = 560;
|
|
19683
19782
|
/** Inset of the floating file-list card from the code scroll box, in px. */
|
|
19684
19783
|
const FLOAT_LIST_MARGIN_PX = 12;
|
|
@@ -19791,6 +19890,38 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
19791
19890
|
})] })]
|
|
19792
19891
|
});
|
|
19793
19892
|
}
|
|
19893
|
+
/** The go-to-line glyph: an arrow landing on a line of code, drawn on the same 14-grid as
|
|
19894
|
+
* `ViewModeIcon`, `MarkdownModeIcon` and `ReturnIcon` so a toolbar of these reads as one set. The
|
|
19895
|
+
* icon library has no "go to line" mark, and a bare `#` beside three line drawings read as a stray
|
|
19896
|
+
* key rather than a control. */
|
|
19897
|
+
function GotoLineIcon({ size = 14 }) {
|
|
19898
|
+
return (0, react_jsx_runtime.jsxs)("svg", {
|
|
19899
|
+
width: size,
|
|
19900
|
+
height: size,
|
|
19901
|
+
viewBox: "0 0 14 14",
|
|
19902
|
+
fill: "none",
|
|
19903
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
19904
|
+
"aria-hidden": "true",
|
|
19905
|
+
children: [
|
|
19906
|
+
(0, react_jsx_runtime.jsx)("path", {
|
|
19907
|
+
d: "M1.5 10.6h11",
|
|
19908
|
+
stroke: "currentColor",
|
|
19909
|
+
strokeWidth: "1.3"
|
|
19910
|
+
}),
|
|
19911
|
+
(0, react_jsx_runtime.jsx)("path", {
|
|
19912
|
+
d: "M7 1.9v5.9",
|
|
19913
|
+
stroke: "currentColor",
|
|
19914
|
+
strokeWidth: "1.3"
|
|
19915
|
+
}),
|
|
19916
|
+
(0, react_jsx_runtime.jsx)("path", {
|
|
19917
|
+
d: "M4.3 5.2 7 7.9l2.7-2.7",
|
|
19918
|
+
stroke: "currentColor",
|
|
19919
|
+
strokeWidth: "1.3",
|
|
19920
|
+
fill: "none"
|
|
19921
|
+
})
|
|
19922
|
+
]
|
|
19923
|
+
});
|
|
19924
|
+
}
|
|
19794
19925
|
/** Return/enter glyph for the comment button: the key's own corner arrow, drawn on
|
|
19795
19926
|
* MarkdownModeIcon's 14-grid so the two read at the same weight. It is what tells
|
|
19796
19927
|
* the user that Enter sends the comment, without spending a row on the hint. */
|
|
@@ -20333,30 +20464,99 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20333
20464
|
return run.text;
|
|
20334
20465
|
});
|
|
20335
20466
|
}
|
|
20336
|
-
function DiscussionQuote({ quote, lines, lang, wrap }) {
|
|
20467
|
+
function DiscussionQuote({ quote, lines, lang, wrap, split }) {
|
|
20337
20468
|
/** The diff's own wash for a quoted row, or nothing for context (and for older threads). */
|
|
20338
20469
|
const wash = (kind) => kind === "add" ? ` ${PendingPanel_module_css_default.quoteAdd}` : kind === "del" ? ` ${PendingPanel_module_css_default.quoteDel}` : "";
|
|
20339
|
-
const
|
|
20340
|
-
|
|
20341
|
-
|
|
20342
|
-
|
|
20343
|
-
|
|
20344
|
-
const
|
|
20345
|
-
if (lineRuns === void 0) content.push(text);
|
|
20346
|
-
else for (const run of lineRuns) content.push((0, react_jsx_runtime.jsx)("span", {
|
|
20347
|
-
style: run.style,
|
|
20348
|
-
children: run.text
|
|
20349
|
-
}, content.length));
|
|
20470
|
+
const texts = (0, react.useMemo)(() => quote.split("\n"), [quote]);
|
|
20471
|
+
/** The quoted lines paired the way the split view pairs the file's rows. */
|
|
20472
|
+
const pairs = (0, react.useMemo)(() => {
|
|
20473
|
+
if (!split) return void 0;
|
|
20474
|
+
return computeSideBySideDiff(texts.map((text, index) => {
|
|
20475
|
+
const line = lines?.[index];
|
|
20350
20476
|
return {
|
|
20351
|
-
|
|
20352
|
-
|
|
20477
|
+
text,
|
|
20478
|
+
kind: line?.kind ?? "context",
|
|
20479
|
+
oldLine: line?.old,
|
|
20480
|
+
newLine: line?.new
|
|
20353
20481
|
};
|
|
20354
|
-
});
|
|
20482
|
+
}), true).pairs;
|
|
20355
20483
|
}, [
|
|
20356
|
-
|
|
20484
|
+
split,
|
|
20485
|
+
texts,
|
|
20486
|
+
lines
|
|
20487
|
+
]);
|
|
20488
|
+
/**
|
|
20489
|
+
* One column's lines and the highlighted runs each draws. Highlighted per column rather than from
|
|
20490
|
+
* one window over the quoted rows: a multi-line construct must not light up across the divider,
|
|
20491
|
+
* which is also how the file's own two columns are lit.
|
|
20492
|
+
*/
|
|
20493
|
+
const sides = (0, react.useMemo)(() => {
|
|
20494
|
+
if (pairs === void 0) return void 0;
|
|
20495
|
+
const build = (which) => {
|
|
20496
|
+
const columnLines = pairs.map((pair) => pair[which]?.text ?? "");
|
|
20497
|
+
return {
|
|
20498
|
+
lines: columnLines,
|
|
20499
|
+
runs: highlightWindow(columnLines, lang, 0, columnLines.length)
|
|
20500
|
+
};
|
|
20501
|
+
};
|
|
20502
|
+
return {
|
|
20503
|
+
left: build("left"),
|
|
20504
|
+
right: build("right")
|
|
20505
|
+
};
|
|
20506
|
+
}, [pairs, lang]);
|
|
20507
|
+
/** One line's nodes: the highlighted runs it draws, or its own text when nothing highlighted it. */
|
|
20508
|
+
const nodesOf = (lineRuns, text) => {
|
|
20509
|
+
if (lineRuns === void 0) return [text];
|
|
20510
|
+
const content = [];
|
|
20511
|
+
for (const run of lineRuns) content.push((0, react_jsx_runtime.jsx)("span", {
|
|
20512
|
+
style: run.style,
|
|
20513
|
+
children: run.text
|
|
20514
|
+
}, content.length));
|
|
20515
|
+
return content;
|
|
20516
|
+
};
|
|
20517
|
+
const rows = (0, react.useMemo)(() => {
|
|
20518
|
+
const runs = highlightWindow(texts, lang, 0, texts.length)?.runs;
|
|
20519
|
+
return texts.map((text, index) => ({
|
|
20520
|
+
content: nodesOf(runs?.[index], text),
|
|
20521
|
+
gutter: lines?.[index]
|
|
20522
|
+
}));
|
|
20523
|
+
}, [
|
|
20524
|
+
texts,
|
|
20357
20525
|
lines,
|
|
20358
20526
|
lang
|
|
20359
20527
|
]);
|
|
20528
|
+
if (pairs !== void 0 && sides !== void 0) {
|
|
20529
|
+
/** The tint a pair's two cells wear, the same way the file's columns tint theirs. */
|
|
20530
|
+
const pairWash = (which, kind) => which === "left" ? wash(kind === "context" ? "context" : "del") : wash(kind === "context" ? "context" : "add");
|
|
20531
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
20532
|
+
className: `${PendingPanel_module_css_default.quoteLines} ${PendingPanel_module_css_default.quoteSplit}${wrap ? "" : " " + PendingPanel_module_css_default.quoteNoWrap}`,
|
|
20533
|
+
"data-diff-discussion-quote": true,
|
|
20534
|
+
children: ["left", "right"].map((which) => (0, react_jsx_runtime.jsx)("div", {
|
|
20535
|
+
className: PendingPanel_module_css_default.quoteSplitSide,
|
|
20536
|
+
"data-diff-quote-side": which,
|
|
20537
|
+
children: (0, react_jsx_runtime.jsx)("div", {
|
|
20538
|
+
className: PendingPanel_module_css_default.quoteSplitTable,
|
|
20539
|
+
children: pairs.map((pair, index) => (0, react_jsx_runtime.jsxs)("div", {
|
|
20540
|
+
className: `${PendingPanel_module_css_default.quoteLine} ${PendingPanel_module_css_default.quotePair}`,
|
|
20541
|
+
"data-diff-quote-pair": true,
|
|
20542
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
20543
|
+
className: PendingPanel_module_css_default.gutter,
|
|
20544
|
+
"data-diff-quote-gutter": true,
|
|
20545
|
+
children: pair[which]?.line ?? ""
|
|
20546
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
20547
|
+
className: `${PendingPanel_module_css_default.quoteCode}${pairWash(which, pair.kind)}`,
|
|
20548
|
+
children: (0, react_jsx_runtime.jsx)("span", {
|
|
20549
|
+
className: PendingPanel_module_css_default.quoteText,
|
|
20550
|
+
"data-diff-quote-text": true,
|
|
20551
|
+
"data-diff-quote-side": which,
|
|
20552
|
+
children: nodesOf(sides[which].runs?.runs?.[index], sides[which].lines[index] ?? "")
|
|
20553
|
+
})
|
|
20554
|
+
})]
|
|
20555
|
+
}, index))
|
|
20556
|
+
})
|
|
20557
|
+
}, which))
|
|
20558
|
+
});
|
|
20559
|
+
}
|
|
20360
20560
|
return (0, react_jsx_runtime.jsx)("div", {
|
|
20361
20561
|
className: `${PendingPanel_module_css_default.quoteLines}${wrap ? "" : " " + PendingPanel_module_css_default.quoteNoWrap}`,
|
|
20362
20562
|
"data-diff-discussion-quote": true,
|
|
@@ -20386,6 +20586,191 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20386
20586
|
}, index))
|
|
20387
20587
|
});
|
|
20388
20588
|
}
|
|
20589
|
+
/** How far outside the viewport a side-by-side thread's card is still drawn, in px: it is a pair's
|
|
20590
|
+
* hop from the edge before the scroll brings it in, and dropping it earlier would flash the card
|
|
20591
|
+
* away at the boundary. */
|
|
20592
|
+
const SPLIT_DISCUSSION_MARGIN_PX = 200;
|
|
20593
|
+
/**
|
|
20594
|
+
* A thread's card: the header (range, fold, ⋯), the quote when the code it was written about is
|
|
20595
|
+
* gone, the turns, and the writing row.
|
|
20596
|
+
*
|
|
20597
|
+
* Every view draws the same card — the single-column code view hangs it in a row of its own below
|
|
20598
|
+
* the rows the thread annotates, and whatever view comes next hangs it under whatever it draws that
|
|
20599
|
+
* anchor as — so it is a component rather than a piece of one view's row stream. What varies per
|
|
20600
|
+
* view is only the wrapper around it and the width it is given.
|
|
20601
|
+
*
|
|
20602
|
+
* @param props - the thread, where it hangs, and the panel's own callbacks.
|
|
20603
|
+
* @returns the card, sized to the rows the panel laid the thread out in.
|
|
20604
|
+
*/
|
|
20605
|
+
function DiscussionBlock({ discussion, label, bodyWidth, lang, menuOpen, asking, t, onToggle, onMenuOpen, onRemove, onDraft, onSend, registerInput, split }) {
|
|
20606
|
+
const rows = discussionRows(discussion);
|
|
20607
|
+
const writingNote = discussion.asking === true && discussion.reply !== void 0 && discussion.reply !== "";
|
|
20608
|
+
const menuItems = [{
|
|
20609
|
+
id: "delete",
|
|
20610
|
+
label: t("action.discussionEnd")
|
|
20611
|
+
}];
|
|
20612
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
20613
|
+
className: PendingPanel_module_css_default.discussion,
|
|
20614
|
+
"data-diff-discussion": true,
|
|
20615
|
+
"data-lost": discussion.lost === true ? "" : void 0,
|
|
20616
|
+
"data-diff-discussion-id": discussion.id,
|
|
20617
|
+
style: {
|
|
20618
|
+
width: Math.max(0, bodyWidth),
|
|
20619
|
+
height: rows * THREAD_ROW_PX
|
|
20620
|
+
},
|
|
20621
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
20622
|
+
className: PendingPanel_module_css_default.discussionHead,
|
|
20623
|
+
children: [
|
|
20624
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
20625
|
+
type: "button",
|
|
20626
|
+
className: PendingPanel_module_css_default.discussionToggle,
|
|
20627
|
+
"data-diff-discussion-toggle": true,
|
|
20628
|
+
"aria-expanded": !discussion.collapsed,
|
|
20629
|
+
"aria-label": t(discussion.collapsed ? "action.discussionExpand" : "action.discussionCollapse"),
|
|
20630
|
+
onClick: () => {
|
|
20631
|
+
onToggle(discussion.id);
|
|
20632
|
+
},
|
|
20633
|
+
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 })
|
|
20634
|
+
}),
|
|
20635
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
20636
|
+
className: PendingPanel_module_css_default.discussionRangeWrap,
|
|
20637
|
+
children: (0, react_jsx_runtime.jsx)("span", {
|
|
20638
|
+
className: PendingPanel_module_css_default.discussionRange,
|
|
20639
|
+
"data-diff-discussion-range": true,
|
|
20640
|
+
children: label
|
|
20641
|
+
})
|
|
20642
|
+
}),
|
|
20643
|
+
(0, react_jsx_runtime.jsx)("span", { className: PendingPanel_module_css_default.flexSpacer }),
|
|
20644
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
20645
|
+
open: menuOpen,
|
|
20646
|
+
portal: true,
|
|
20647
|
+
compact: true,
|
|
20648
|
+
align: "end",
|
|
20649
|
+
items: menuItems,
|
|
20650
|
+
onSelect: (id) => {
|
|
20651
|
+
if (id === "delete") onRemove(discussion.id);
|
|
20652
|
+
onMenuOpen(void 0);
|
|
20653
|
+
},
|
|
20654
|
+
onClose: () => {
|
|
20655
|
+
onMenuOpen(void 0);
|
|
20656
|
+
},
|
|
20657
|
+
anchor: (0, react_jsx_runtime.jsx)("button", {
|
|
20658
|
+
type: "button",
|
|
20659
|
+
className: PendingPanel_module_css_default.discussionToggle,
|
|
20660
|
+
"data-diff-discussion-menu": true,
|
|
20661
|
+
"aria-label": t("action.more"),
|
|
20662
|
+
onClick: () => {
|
|
20663
|
+
onMenuOpen(menuOpen ? void 0 : discussion.id);
|
|
20664
|
+
},
|
|
20665
|
+
children: "⋯"
|
|
20666
|
+
})
|
|
20667
|
+
})
|
|
20668
|
+
]
|
|
20669
|
+
}), !discussion.collapsed && (0, react_jsx_runtime.jsxs)("div", {
|
|
20670
|
+
className: PendingPanel_module_css_default.discussionBody,
|
|
20671
|
+
children: [
|
|
20672
|
+
discussion.lost === true && discussion.quote !== void 0 && discussion.quote !== "" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("p", {
|
|
20673
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
20674
|
+
"data-diff-discussion-quote-label": true,
|
|
20675
|
+
children: t("discussion.outdatedQuote")
|
|
20676
|
+
}), (0, react_jsx_runtime.jsx)(DiscussionQuote, {
|
|
20677
|
+
quote: discussion.quote,
|
|
20678
|
+
lines: discussion.quoteLines,
|
|
20679
|
+
lang,
|
|
20680
|
+
wrap: discussion.quoteWrap === true,
|
|
20681
|
+
split
|
|
20682
|
+
})] }),
|
|
20683
|
+
discussion.hidden !== void 0 && discussion.hidden > 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
20684
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
20685
|
+
"data-diff-discussion-hidden": true,
|
|
20686
|
+
children: t("discussion.hidden", { count: discussion.hidden })
|
|
20687
|
+
}),
|
|
20688
|
+
discussion.stopped === true && (discussion.reply === void 0 || discussion.reply === "") && discussion.failed !== true && (0, react_jsx_runtime.jsx)("p", {
|
|
20689
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
20690
|
+
"data-diff-discussion-stopped": true,
|
|
20691
|
+
children: t("discussion.stopped")
|
|
20692
|
+
}),
|
|
20693
|
+
discussion.messages.map((message, index) => message.role === "user" ? (0, react_jsx_runtime.jsx)("p", {
|
|
20694
|
+
className: PendingPanel_module_css_default.discussionUser,
|
|
20695
|
+
"data-diff-discussion-user": true,
|
|
20696
|
+
children: discussionNodes(message.text)
|
|
20697
|
+
}, `u${index}`) : (0, react_jsx_runtime.jsx)("p", {
|
|
20698
|
+
className: PendingPanel_module_css_default.discussionAnswer,
|
|
20699
|
+
"data-diff-discussion-reply": true,
|
|
20700
|
+
children: discussionNodes(message.text)
|
|
20701
|
+
}, `a${index}`)),
|
|
20702
|
+
discussion.reply !== void 0 && discussion.reply !== "" ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("p", {
|
|
20703
|
+
className: PendingPanel_module_css_default.discussionAnswer,
|
|
20704
|
+
"data-diff-discussion-reply": true,
|
|
20705
|
+
children: discussionNodes(discussion.reply)
|
|
20706
|
+
}), writingNote && (0, react_jsx_runtime.jsxs)("p", {
|
|
20707
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
20708
|
+
"data-diff-discussion-answering": true,
|
|
20709
|
+
children: [t("discussion.answering"), (0, react_jsx_runtime.jsxs)("span", {
|
|
20710
|
+
className: PendingPanel_module_css_default.discussionDots,
|
|
20711
|
+
"data-diff-discussion-dots": true,
|
|
20712
|
+
"aria-hidden": "true",
|
|
20713
|
+
children: [
|
|
20714
|
+
(0, react_jsx_runtime.jsx)("span", { children: "." }),
|
|
20715
|
+
(0, react_jsx_runtime.jsx)("span", { children: "." }),
|
|
20716
|
+
(0, react_jsx_runtime.jsx)("span", { children: "." })
|
|
20717
|
+
]
|
|
20718
|
+
})]
|
|
20719
|
+
})] }) : discussion.failed === true ? (0, react_jsx_runtime.jsx)("p", {
|
|
20720
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
20721
|
+
"data-diff-discussion-failed": true,
|
|
20722
|
+
children: t("discussion.failed")
|
|
20723
|
+
}) : discussion.asking === true ? (0, react_jsx_runtime.jsxs)("p", {
|
|
20724
|
+
className: PendingPanel_module_css_default.discussionNote,
|
|
20725
|
+
"data-diff-discussion-asking": true,
|
|
20726
|
+
children: [discussion.queued === true ? t("discussion.queued") : t("discussion.thinking"), (0, react_jsx_runtime.jsxs)("span", {
|
|
20727
|
+
className: PendingPanel_module_css_default.discussionDots,
|
|
20728
|
+
"data-diff-discussion-dots": true,
|
|
20729
|
+
"aria-hidden": "true",
|
|
20730
|
+
children: [
|
|
20731
|
+
(0, react_jsx_runtime.jsx)("span", { children: "." }),
|
|
20732
|
+
(0, react_jsx_runtime.jsx)("span", { children: "." }),
|
|
20733
|
+
(0, react_jsx_runtime.jsx)("span", { children: "." })
|
|
20734
|
+
]
|
|
20735
|
+
})]
|
|
20736
|
+
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("div", {
|
|
20737
|
+
className: PendingPanel_module_css_default.discussionSlack,
|
|
20738
|
+
"data-diff-discussion-slack": true,
|
|
20739
|
+
"aria-hidden": "true"
|
|
20740
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
20741
|
+
className: PendingPanel_module_css_default.discussionCompose,
|
|
20742
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
20743
|
+
className: PendingPanel_module_css_default.discussionInput,
|
|
20744
|
+
"data-diff-discussion-input": true,
|
|
20745
|
+
ref: (element) => {
|
|
20746
|
+
registerInput(discussion.id, element);
|
|
20747
|
+
},
|
|
20748
|
+
value: discussion.draft,
|
|
20749
|
+
placeholder: t("discussion.placeholder"),
|
|
20750
|
+
onChange: (event) => {
|
|
20751
|
+
onDraft(discussion.id, event.target.value);
|
|
20752
|
+
},
|
|
20753
|
+
onKeyDown: (event) => {
|
|
20754
|
+
if (event.key !== "Enter") return;
|
|
20755
|
+
if (event.nativeEvent.isComposing || event.keyCode === 229) return;
|
|
20756
|
+
event.preventDefault();
|
|
20757
|
+
onSend(discussion.id);
|
|
20758
|
+
}
|
|
20759
|
+
}), (0, react_jsx_runtime.jsxs)("button", {
|
|
20760
|
+
type: "button",
|
|
20761
|
+
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionPrimary} ${PendingPanel_module_css_default.discussionSend}`,
|
|
20762
|
+
"data-diff-discussion-send": true,
|
|
20763
|
+
disabled: asking,
|
|
20764
|
+
onClick: () => {
|
|
20765
|
+
onSend(discussion.id);
|
|
20766
|
+
},
|
|
20767
|
+
children: [t("action.comment"), (0, react_jsx_runtime.jsx)(ReturnIcon, {})]
|
|
20768
|
+
})]
|
|
20769
|
+
})] })
|
|
20770
|
+
]
|
|
20771
|
+
})]
|
|
20772
|
+
});
|
|
20773
|
+
}
|
|
20389
20774
|
/** Chip styling for each intra-line run: removed chars and added chars stand out. */
|
|
20390
20775
|
const INTRA_CLASS = {
|
|
20391
20776
|
same: void 0,
|
|
@@ -20517,6 +20902,40 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20517
20902
|
"[data-diff-copy]"
|
|
20518
20903
|
].join(", ");
|
|
20519
20904
|
/**
|
|
20905
|
+
* Whether a press landed on a row the live selection already covers — the highlighted text itself,
|
|
20906
|
+
* or the blank space beside it on the same line.
|
|
20907
|
+
*
|
|
20908
|
+
* Both are inside the code view, which `KEEPS_SELECTION` leaves to the browser, and the browser
|
|
20909
|
+
* keeps the selection for neither: inside the highlight is where a drag that extends it would
|
|
20910
|
+
* begin, and the blank beside it is chrome, which it never clears a selection from. So a plain
|
|
20911
|
+
* press there left the highlight and the frame standing over a gesture that plainly ended. This is
|
|
20912
|
+
* the one press in the content the panel has to end itself (see `onPanelMouseDown`).
|
|
20913
|
+
*
|
|
20914
|
+
* @param target - the element the press landed on.
|
|
20915
|
+
* @param live - the window's selection, still the one the reader had.
|
|
20916
|
+
* @returns whether that selection covers the pressed row.
|
|
20917
|
+
*/
|
|
20918
|
+
function pressOnSelectedRow(target, live) {
|
|
20919
|
+
if (live === null || live.isCollapsed) return false;
|
|
20920
|
+
const unified = rowRangeOf(live);
|
|
20921
|
+
const split = unified === void 0 ? splitRowRangeOf(live) : void 0;
|
|
20922
|
+
const range = unified ?? split;
|
|
20923
|
+
if (range === void 0) return false;
|
|
20924
|
+
const row = target.closest("[data-diff-row], [data-diff-split-row]");
|
|
20925
|
+
if (row === null) return false;
|
|
20926
|
+
let index;
|
|
20927
|
+
if (unified !== void 0) {
|
|
20928
|
+
const value = Number(row.dataset.diffRow);
|
|
20929
|
+
index = Number.isFinite(value) ? value : void 0;
|
|
20930
|
+
} else {
|
|
20931
|
+
const info = splitRowInfoAt(target);
|
|
20932
|
+
if (info === void 0 || range.side !== void 0 && info.side !== range.side) return false;
|
|
20933
|
+
index = info.pairIndex;
|
|
20934
|
+
}
|
|
20935
|
+
if (index === void 0) return false;
|
|
20936
|
+
return index >= range.start && index <= range.end;
|
|
20937
|
+
}
|
|
20938
|
+
/**
|
|
20520
20939
|
* Whether a key event came from a text field that owns its own keys (`Esc`,
|
|
20521
20940
|
* cursor moves). The chat composer is the one that matters: the panel leaves it
|
|
20522
20941
|
* alone even while its own search bar is open.
|
|
@@ -20726,12 +21145,13 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20726
21145
|
* one side is longer. The gutter and code are top-aligned so sub-lines line up
|
|
20727
21146
|
* across the divider.
|
|
20728
21147
|
*/
|
|
20729
|
-
function SplitSideRow({ index, side, wrapped, runs, kind, isLeft, height, focused, searchHit, searchCurrent, searchQuery, searchOptions, onHover, intra }) {
|
|
21148
|
+
function SplitSideRow({ index, side, wrapped, runs, kind, isLeft, height, focused, discussed, searchHit, searchCurrent, searchQuery, searchOptions, onHover, intra }) {
|
|
20730
21149
|
const tint = isLeft ? kind === "del" || kind === "replace" ? PendingPanel_module_css_default.splitLdel : "" : kind === "add" || kind === "replace" ? PendingPanel_module_css_default.splitRadd : "";
|
|
20731
21150
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
20732
|
-
className: PendingPanel_module_css_default.line
|
|
21151
|
+
className: `${PendingPanel_module_css_default.line}${discussed ? " " + PendingPanel_module_css_default.rowDiscussed : ""}`,
|
|
20733
21152
|
style: { height },
|
|
20734
21153
|
"data-diff-split-row": true,
|
|
21154
|
+
"data-diff-discussion-band": discussed ? "" : void 0,
|
|
20735
21155
|
"data-diff-split-index": index,
|
|
20736
21156
|
"data-diff-split-side": isLeft ? "left" : "right",
|
|
20737
21157
|
"data-diff-focused": focused ? "" : void 0,
|
|
@@ -20750,7 +21170,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20750
21170
|
});
|
|
20751
21171
|
}
|
|
20752
21172
|
/** The two-column (side-by-side) whole-file diff view. */
|
|
20753
|
-
const SplitDiff = (0, react.forwardRef)(function SplitDiff({ file, model, runs, langWrap, tabWidthSpaces, busy, t, selection, leadRows, onBlockKeep, onBlockRevert, onWrapToast, onVisibleLines }, ref) {
|
|
21173
|
+
const SplitDiff = (0, react.forwardRef)(function SplitDiff({ file, model, runs, langWrap, tabWidthSpaces, busy, t, selection, leadRows, onBlockKeep, onBlockRevert, onWrapToast, onVisibleLines, discussions, renderDiscussion, selectionComment }, ref) {
|
|
20754
21174
|
const ROW_HEIGHT_PX = diffLineHeight();
|
|
20755
21175
|
const NAV_ANCHOR_TOLERANCE_PX = ROW_HEIGHT_PX / 4;
|
|
20756
21176
|
const { pairs, pairOfRow } = (0, react.useMemo)(() => computeSideBySideDiff(model.diff.rows, true), [model]);
|
|
@@ -20768,6 +21188,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20768
21188
|
return map;
|
|
20769
21189
|
}, [model, pairOfRow]);
|
|
20770
21190
|
const bodyRef = (0, react.useRef)(null);
|
|
21191
|
+
const splitRootRef = (0, react.useRef)(null);
|
|
20771
21192
|
const [scrollTop, setScrollTop] = (0, react.useState)(0);
|
|
20772
21193
|
const [viewportH, setViewportH] = (0, react.useState)(0);
|
|
20773
21194
|
const [bodyWidth, setBodyWidth] = (0, react.useState)(0);
|
|
@@ -20868,13 +21289,63 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20868
21289
|
if (pairWrapped === null) return null;
|
|
20869
21290
|
return pairWrapped.map((w) => Math.max(w.left?.length ?? 1, w.right?.length ?? 1) * ROW_HEIGHT_PX);
|
|
20870
21291
|
}, [pairWrapped]);
|
|
21292
|
+
/** The model rows a thread annotates: the wash their halves wear (see `rowDiscussed`). */
|
|
21293
|
+
const discussedRows = (0, react.useMemo)(() => {
|
|
21294
|
+
const set = /* @__PURE__ */ new Set();
|
|
21295
|
+
for (const discussion of discussions ?? []) {
|
|
21296
|
+
if (discussion.lost === true) continue;
|
|
21297
|
+
for (let row = Math.max(0, discussion.anchor.start); row <= Math.min(discussion.anchor.end, model.diff.rows.length - 1); row++) set.add(row);
|
|
21298
|
+
}
|
|
21299
|
+
return set;
|
|
21300
|
+
}, [discussions, model]);
|
|
21301
|
+
/**
|
|
21302
|
+
* The pairs that wear the wash: a pair does when either of its rows is one a thread annotates. Per
|
|
21303
|
+
* pair rather than per half, because a commented ADDED line has no old-side row at all — asking each
|
|
21304
|
+
* half about its own row left the empty half bare, and the band is what says the pair carries a
|
|
21305
|
+
* thread. Both halves take it from either row, the way the single-column view washes the whole row.
|
|
21306
|
+
*/
|
|
21307
|
+
const discussedPairs = (0, react.useMemo)(() => {
|
|
21308
|
+
const set = /* @__PURE__ */ new Set();
|
|
21309
|
+
for (const [pair, rows] of pairRowIndices) {
|
|
21310
|
+
const left = rows.left === void 0 ? false : discussedRows.has(rows.left);
|
|
21311
|
+
const right = rows.right === void 0 ? false : discussedRows.has(rows.right);
|
|
21312
|
+
if (left || right) set.add(pair);
|
|
21313
|
+
}
|
|
21314
|
+
return set;
|
|
21315
|
+
}, [pairRowIndices, discussedRows]);
|
|
21316
|
+
/** The threads that hang under each pair, by the row their anchor ends in. */
|
|
21317
|
+
const pairDiscussions = (0, react.useMemo)(() => {
|
|
21318
|
+
const map = /* @__PURE__ */ new Map();
|
|
21319
|
+
for (const discussion of discussions ?? []) {
|
|
21320
|
+
const pair = pairOfRow.get(discussion.anchor.end) ?? pairOfRow.get(discussion.anchor.start);
|
|
21321
|
+
if (pair === void 0) continue;
|
|
21322
|
+
const list = map.get(pair);
|
|
21323
|
+
if (list === void 0) map.set(pair, [discussion]);
|
|
21324
|
+
else list.push(discussion);
|
|
21325
|
+
}
|
|
21326
|
+
return map;
|
|
21327
|
+
}, [discussions, pairOfRow]);
|
|
21328
|
+
/**
|
|
21329
|
+
* The height a pair holds for the threads hanging under it, in px.
|
|
21330
|
+
*
|
|
21331
|
+
* A thread's rows are the thread's own (see `THREAD_ROW_PX`), not the code's, so a block off the
|
|
21332
|
+
* code's grid still lands exactly where the height table says. Both columns reserve this much —
|
|
21333
|
+
* the cards themselves are drawn over both (see the layer below) — which is what keeps the two
|
|
21334
|
+
* halves from drifting apart under a thread either of them shows.
|
|
21335
|
+
*/
|
|
21336
|
+
const discussionPx = (0, react.useCallback)((k) => (pairDiscussions.get(k) ?? []).reduce((px, discussion) => px + discussionRows(discussion) * THREAD_ROW_PX, 0), [pairDiscussions]);
|
|
20871
21337
|
const pairOffsets = (0, react.useMemo)(() => {
|
|
20872
|
-
if (pairHeights === null) return null;
|
|
20873
|
-
const offs = new Array(
|
|
21338
|
+
if (pairHeights === null && pairDiscussions.size === 0) return null;
|
|
21339
|
+
const offs = new Array(pairCount + 1);
|
|
20874
21340
|
offs[0] = 0;
|
|
20875
|
-
for (let i = 0; i <
|
|
21341
|
+
for (let i = 0; i < pairCount; i++) offs[i + 1] = offs[i] + (pairHeights === null ? ROW_HEIGHT_PX : pairHeights[i] ?? ROW_HEIGHT_PX) + discussionPx(i);
|
|
20876
21342
|
return offs;
|
|
20877
|
-
}, [
|
|
21343
|
+
}, [
|
|
21344
|
+
pairHeights,
|
|
21345
|
+
pairCount,
|
|
21346
|
+
discussionPx,
|
|
21347
|
+
pairDiscussions
|
|
21348
|
+
]);
|
|
20878
21349
|
const totalHeight = pairOffsets === null ? pairCount * ROW_HEIGHT_PX : pairOffsets[pairCount] ?? 0;
|
|
20879
21350
|
const off = (k) => pairOffsets === null ? k * ROW_HEIGHT_PX : pairOffsets[Math.max(0, Math.min(k, pairCount))] ?? 0;
|
|
20880
21351
|
const pairHeightAt = (k) => pairHeights === null ? ROW_HEIGHT_PX : pairHeights[k] ?? ROW_HEIGHT_PX;
|
|
@@ -20915,6 +21386,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
20915
21386
|
const col = side === "left" ? leftColRef.current : rightColRef.current;
|
|
20916
21387
|
if (strip === null || col === null) return;
|
|
20917
21388
|
col.scrollLeft = strip.scrollLeft;
|
|
21389
|
+
const quotes = splitRootRef.current?.querySelectorAll(`[data-diff-quote-text][data-diff-quote-side="${side}"]`);
|
|
21390
|
+
for (const text of quotes ?? []) text.scrollLeft = strip.scrollLeft;
|
|
20918
21391
|
}, []);
|
|
20919
21392
|
const searchMatches = (0, react.useMemo)(() => searchPairs(pairs, searchQuery, search.options), [
|
|
20920
21393
|
pairs,
|
|
@@ -21091,8 +21564,30 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21091
21564
|
goSearch(direction);
|
|
21092
21565
|
return true;
|
|
21093
21566
|
};
|
|
21567
|
+
/**
|
|
21568
|
+
* The row this view was asked to land on — the comments list's jump into a file that is already open —
|
|
21569
|
+
* and whether it is a thread's own BOX rather than a place in the code. The centering effect below
|
|
21570
|
+
* lands it at the pair that row is in (or at the box hanging under that pair) rather than at its
|
|
21571
|
+
* block's first pair, which is the precision the single-column view has; spent once, like every
|
|
21572
|
+
* landing.
|
|
21573
|
+
*/
|
|
21574
|
+
const landingRowRef = (0, react.useRef)(void 0);
|
|
21575
|
+
/** A row this view was asked to frame and land on rather than a whole block (a go-to-line). */
|
|
21576
|
+
const flashRowRef = (0, react.useRef)(void 0);
|
|
21577
|
+
const land = (0, react.useCallback)((row, toCard = false, rowFlash = false) => {
|
|
21578
|
+
landingRowRef.current = {
|
|
21579
|
+
row,
|
|
21580
|
+
toCard
|
|
21581
|
+
};
|
|
21582
|
+
const pair = pairOfRow.get(row);
|
|
21583
|
+
const block = pair === void 0 ? void 0 : blockIndexByPair.get(pair);
|
|
21584
|
+
if (block !== void 0) setFocus(block);
|
|
21585
|
+
flashRowRef.current = rowFlash ? row : void 0;
|
|
21586
|
+
setFlashKey((key) => key + 1);
|
|
21587
|
+
}, [pairOfRow, blockIndexByPair]);
|
|
21094
21588
|
(0, react.useImperativeHandle)(ref, () => ({
|
|
21095
21589
|
jump,
|
|
21590
|
+
land,
|
|
21096
21591
|
openSearch,
|
|
21097
21592
|
toggleSearch,
|
|
21098
21593
|
closeSearch,
|
|
@@ -21101,6 +21596,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21101
21596
|
toggleMatchWholeWord
|
|
21102
21597
|
}), [
|
|
21103
21598
|
jump,
|
|
21599
|
+
land,
|
|
21104
21600
|
openSearch,
|
|
21105
21601
|
toggleSearch,
|
|
21106
21602
|
closeSearch,
|
|
@@ -21114,7 +21610,10 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21114
21610
|
if (block === void 0) return;
|
|
21115
21611
|
const body = bodyRef.current;
|
|
21116
21612
|
if (body === null) return;
|
|
21117
|
-
const
|
|
21613
|
+
const landed = landingRowRef.current;
|
|
21614
|
+
landingRowRef.current = void 0;
|
|
21615
|
+
const from = landed === void 0 ? block.start : pairOfRow.get(landed.row) ?? block.start;
|
|
21616
|
+
const target = off(from) + (landed?.toCard === true ? pairHeightAt(from) : 0) - leadRows * ROW_HEIGHT_PX;
|
|
21118
21617
|
const clamped = Math.max(0, Math.min(target, body.scrollHeight - body.clientHeight));
|
|
21119
21618
|
if (body.scrollTop !== clamped) body.scrollTop = clamped;
|
|
21120
21619
|
setScrollTop(clamped);
|
|
@@ -21143,22 +21642,186 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21143
21642
|
};
|
|
21144
21643
|
const blockRanges = (0, react.useMemo)(() => model.blocks.map((block) => blockRangesOf(model.diff.rows, block)), [model]);
|
|
21145
21644
|
const focusedBlock = blockOfPair[focus];
|
|
21146
|
-
const
|
|
21147
|
-
const
|
|
21645
|
+
const flashRow = flashRowRef.current;
|
|
21646
|
+
const flashTop = flashRow !== void 0 ? Math.max(0, off(pairOfRow.get(flashRow) ?? flashRow) - scrollTop) : focusedBlock === void 0 ? 0 : Math.max(0, off(focusedBlock.start) - scrollTop);
|
|
21647
|
+
const flashBottom = flashRow !== void 0 ? Math.min(viewportH > 0 ? viewportH : Number.POSITIVE_INFINITY, off((pairOfRow.get(flashRow) ?? flashRow) + 1) - scrollTop) : focusedBlock === void 0 ? 0 : Math.min(viewportH > 0 ? viewportH : Number.POSITIVE_INFINITY, off(focusedBlock.end + 1) - scrollTop);
|
|
21148
21648
|
const flashHeight = Math.max(0, flashBottom - flashTop);
|
|
21149
21649
|
const blockActionsTop = hoveredBlock === void 0 || blockOfPair[hoveredBlock] === void 0 ? 0 : Math.max(0, Math.min(off(blockOfPair[hoveredBlock].end + 1) - scrollTop, Math.max(0, viewportH - BLOCK_ACTIONS_FRAME_PX)));
|
|
21650
|
+
/**
|
|
21651
|
+
* How a press in the side-by-side view makes a selection. Left to the browser, a drag that crosses
|
|
21652
|
+
* the divider takes in the rest of the column it began in and then the other one upwards — the
|
|
21653
|
+
* pointer's own position decides that, and the selection cannot be written to stop it (a write under
|
|
21654
|
+
* a live drag makes the browser drop the drag instead). An editor has no such problem because a
|
|
21655
|
+
* pointer there is only ever a coordinate: it computes the position inside the editor, so a drag
|
|
21656
|
+
* cannot leave it, which is how VS Code's own text keeps a selection inside its box. The same is
|
|
21657
|
+
* done here for the column the press began in: x is taken inside that column's code cell, so
|
|
21658
|
+
* dragging past the divider keeps the row the pointer is on and the line numbers never join the
|
|
21659
|
+
* selection, and y is taken inside the scroller, which is scrolled here when the pointer leaves it.
|
|
21660
|
+
* Double and triple clicks are still the browser's (`detail` above one), so word and line selection
|
|
21661
|
+
* are unchanged.
|
|
21662
|
+
*
|
|
21663
|
+
* Touch cannot be driven this way — the platform owns the long press, and preventing the touch would
|
|
21664
|
+
* take the scroll with it — so there the other column is simply made unselectable while the press
|
|
21665
|
+
* lasts (see `.splitSealed`), which stops the caret from entering it at all; the cost is that the
|
|
21666
|
+
* caret then resolves to the nearest selectable position rather than to the row under the finger.
|
|
21667
|
+
*/
|
|
21668
|
+
(0, react.useEffect)(() => {
|
|
21669
|
+
const root = splitRootRef.current;
|
|
21670
|
+
const scroller = bodyRef.current;
|
|
21671
|
+
if (root === null || scroller === null) return;
|
|
21672
|
+
const caretApi = document;
|
|
21673
|
+
const canDrive = caretApi.caretRangeFromPoint !== void 0 || caretApi.caretPositionFromPoint !== void 0;
|
|
21674
|
+
let drag = null;
|
|
21675
|
+
let frame = 0;
|
|
21676
|
+
let point = {
|
|
21677
|
+
x: 0,
|
|
21678
|
+
y: 0
|
|
21679
|
+
};
|
|
21680
|
+
let pointerType;
|
|
21681
|
+
/** The position a point names inside `column`: its row for y, and that row's code cell for x. */
|
|
21682
|
+
const positionIn = (column, clientX, clientY) => {
|
|
21683
|
+
const rows = column.querySelectorAll("[data-diff-split-row]");
|
|
21684
|
+
if (rows.length === 0) return void 0;
|
|
21685
|
+
let row = rows[rows.length - 1];
|
|
21686
|
+
for (const candidate of rows) if (clientY < candidate.getBoundingClientRect().bottom) {
|
|
21687
|
+
row = candidate;
|
|
21688
|
+
break;
|
|
21689
|
+
}
|
|
21690
|
+
const box = row.getBoundingClientRect();
|
|
21691
|
+
const y = Math.min(Math.max(clientY, box.top + 1), box.bottom - 1);
|
|
21692
|
+
const code = row.querySelector("[data-diff-code]");
|
|
21693
|
+
if (code === null) return void 0;
|
|
21694
|
+
const cell = code.getBoundingClientRect();
|
|
21695
|
+
const x = Math.min(Math.max(clientX, cell.left + 1), cell.right - 1);
|
|
21696
|
+
const found = caretAtPoint(x, y);
|
|
21697
|
+
if (found !== void 0 && code.contains(found.node)) return found;
|
|
21698
|
+
const edges = textEdgesOf(code);
|
|
21699
|
+
if (edges === void 0) return void 0;
|
|
21700
|
+
return x < (cell.left + cell.right) / 2 ? {
|
|
21701
|
+
node: edges.first,
|
|
21702
|
+
offset: 0
|
|
21703
|
+
} : {
|
|
21704
|
+
node: edges.last,
|
|
21705
|
+
offset: edges.last.length
|
|
21706
|
+
};
|
|
21707
|
+
};
|
|
21708
|
+
const apply = () => {
|
|
21709
|
+
if (drag === null) return;
|
|
21710
|
+
const selection = window.getSelection();
|
|
21711
|
+
const extent = positionIn(drag.column, point.x, point.y);
|
|
21712
|
+
if (selection === null || extent === void 0) return;
|
|
21713
|
+
selection.setBaseAndExtent(drag.anchor.node, drag.anchor.offset, extent.node, extent.offset);
|
|
21714
|
+
};
|
|
21715
|
+
/** One pass per frame: the position first, then a scroll if the pointer is outside the scroller. */
|
|
21716
|
+
const tick = () => {
|
|
21717
|
+
frame = 0;
|
|
21718
|
+
if (drag === null) return;
|
|
21719
|
+
const box = scroller.getBoundingClientRect();
|
|
21720
|
+
const out = point.y < box.top ? point.y - box.top : point.y > box.bottom ? point.y - box.bottom : 0;
|
|
21721
|
+
if (out !== 0) {
|
|
21722
|
+
const step = Math.min(ROW_HEIGHT_PX * 3, Math.max(ROW_HEIGHT_PX, Math.abs(out) / 3));
|
|
21723
|
+
scroller.scrollTop += Math.sign(out) * step;
|
|
21724
|
+
}
|
|
21725
|
+
apply();
|
|
21726
|
+
if (out !== 0) frame = window.requestAnimationFrame(tick);
|
|
21727
|
+
};
|
|
21728
|
+
/** The column a node sits in, or undefined for anything else in the view (a card, a frame). */
|
|
21729
|
+
const columnOf = (target) => {
|
|
21730
|
+
const row = target.closest("[data-diff-split-row]");
|
|
21731
|
+
if (row === null) return void 0;
|
|
21732
|
+
const left = leftColRef.current;
|
|
21733
|
+
const right = rightColRef.current;
|
|
21734
|
+
if (left !== null && left.contains(row)) return left;
|
|
21735
|
+
return right !== null && right.contains(row) ? right : void 0;
|
|
21736
|
+
};
|
|
21737
|
+
const onPointerDown = (event) => {
|
|
21738
|
+
pointerType = event.pointerType;
|
|
21739
|
+
if (event.pointerType === "mouse") return;
|
|
21740
|
+
const target = event.target;
|
|
21741
|
+
if (!(target instanceof Element) || columnOf(target) === void 0) return;
|
|
21742
|
+
const sealed = PendingPanel_module_css_default.splitSealed;
|
|
21743
|
+
const side = PendingPanel_module_css_default.splitSealedLeft;
|
|
21744
|
+
const other = PendingPanel_module_css_default.splitSealedRight;
|
|
21745
|
+
if (sealed === void 0 || side === void 0 || other === void 0) return;
|
|
21746
|
+
document.body.classList.add(sealed, target.closest("[data-diff-split-side=\"left\"]") !== null ? side : other);
|
|
21747
|
+
};
|
|
21748
|
+
const onMouseDown = (event) => {
|
|
21749
|
+
if (!canDrive) return;
|
|
21750
|
+
if (pointerType !== void 0 && pointerType !== "mouse") return;
|
|
21751
|
+
if (event.button !== 0 || event.detail !== 1 || event.shiftKey || event.ctrlKey || event.metaKey || event.altKey) return;
|
|
21752
|
+
const target = event.target;
|
|
21753
|
+
if (!(target instanceof Element)) return;
|
|
21754
|
+
const column = columnOf(target);
|
|
21755
|
+
if (column === void 0) return;
|
|
21756
|
+
const anchor = positionIn(column, event.clientX, event.clientY);
|
|
21757
|
+
if (anchor === void 0) return;
|
|
21758
|
+
event.preventDefault();
|
|
21759
|
+
scroller.focus();
|
|
21760
|
+
point = {
|
|
21761
|
+
x: event.clientX,
|
|
21762
|
+
y: event.clientY
|
|
21763
|
+
};
|
|
21764
|
+
drag = {
|
|
21765
|
+
column,
|
|
21766
|
+
anchor
|
|
21767
|
+
};
|
|
21768
|
+
apply();
|
|
21769
|
+
};
|
|
21770
|
+
const onMove = (event) => {
|
|
21771
|
+
if (drag === null) return;
|
|
21772
|
+
point = {
|
|
21773
|
+
x: event.clientX,
|
|
21774
|
+
y: event.clientY
|
|
21775
|
+
};
|
|
21776
|
+
if (frame === 0) frame = window.requestAnimationFrame(tick);
|
|
21777
|
+
};
|
|
21778
|
+
const release = () => {
|
|
21779
|
+
const sealed = PendingPanel_module_css_default.splitSealed;
|
|
21780
|
+
const side = PendingPanel_module_css_default.splitSealedLeft;
|
|
21781
|
+
const other = PendingPanel_module_css_default.splitSealedRight;
|
|
21782
|
+
if (sealed !== void 0 && side !== void 0 && other !== void 0) document.body.classList.remove(sealed, side, other);
|
|
21783
|
+
};
|
|
21784
|
+
const stop = () => {
|
|
21785
|
+
drag = null;
|
|
21786
|
+
release();
|
|
21787
|
+
if (frame !== 0) {
|
|
21788
|
+
window.cancelAnimationFrame(frame);
|
|
21789
|
+
frame = 0;
|
|
21790
|
+
}
|
|
21791
|
+
};
|
|
21792
|
+
root.addEventListener("pointerdown", onPointerDown, true);
|
|
21793
|
+
root.addEventListener("mousedown", onMouseDown, true);
|
|
21794
|
+
document.addEventListener("pointermove", onMove, true);
|
|
21795
|
+
document.addEventListener("pointerup", stop, true);
|
|
21796
|
+
document.addEventListener("pointercancel", stop, true);
|
|
21797
|
+
document.addEventListener("touchend", release, true);
|
|
21798
|
+
document.addEventListener("touchcancel", release, true);
|
|
21799
|
+
window.addEventListener("blur", stop);
|
|
21800
|
+
return () => {
|
|
21801
|
+
root.removeEventListener("pointerdown", onPointerDown, true);
|
|
21802
|
+
root.removeEventListener("mousedown", onMouseDown, true);
|
|
21803
|
+
document.removeEventListener("pointermove", onMove, true);
|
|
21804
|
+
document.removeEventListener("pointerup", stop, true);
|
|
21805
|
+
document.removeEventListener("pointercancel", stop, true);
|
|
21806
|
+
document.removeEventListener("touchend", release, true);
|
|
21807
|
+
document.removeEventListener("touchcancel", release, true);
|
|
21808
|
+
window.removeEventListener("blur", stop);
|
|
21809
|
+
stop();
|
|
21810
|
+
};
|
|
21811
|
+
}, []);
|
|
21150
21812
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
21151
21813
|
className: PendingPanel_module_css_default.splitRoot,
|
|
21814
|
+
ref: splitRootRef,
|
|
21152
21815
|
onMouseLeave: () => setHoveredBlock(void 0),
|
|
21153
21816
|
children: [
|
|
21154
|
-
(0, react_jsx_runtime.
|
|
21817
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
21155
21818
|
className: `${PendingPanel_module_css_default.diffBody} ${PendingPanel_module_css_default.diffBodySplit}`,
|
|
21156
21819
|
ref: bodyRef,
|
|
21157
21820
|
tabIndex: 0,
|
|
21158
21821
|
onScroll,
|
|
21159
21822
|
style: { tabSize: tabWidthSpaces },
|
|
21160
21823
|
"data-diff-body": true,
|
|
21161
|
-
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
21824
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
21162
21825
|
className: PendingPanel_module_css_default.splitCols,
|
|
21163
21826
|
children: [
|
|
21164
21827
|
(0, react_jsx_runtime.jsx)("div", {
|
|
@@ -21178,7 +21841,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21178
21841
|
const index = start + offset;
|
|
21179
21842
|
const leftRuns = pair.left === void 0 ? void 0 : runs?.oldRuns?.[(pair.left.line ?? 0) - 1];
|
|
21180
21843
|
const sideIndex = pairRowIndices.get(index);
|
|
21181
|
-
return (0, react_jsx_runtime.jsx)(SplitSideRow, {
|
|
21844
|
+
return (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [(0, react_jsx_runtime.jsx)(SplitSideRow, {
|
|
21182
21845
|
index,
|
|
21183
21846
|
side: pair.left,
|
|
21184
21847
|
wrapped: pairWrapped?.[index]?.left,
|
|
@@ -21192,8 +21855,14 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21192
21855
|
searchQuery,
|
|
21193
21856
|
searchOptions: search.options,
|
|
21194
21857
|
onHover: () => onPairHover(index),
|
|
21195
|
-
intra: sideIndex?.left === void 0 ? void 0 : model.intra.get(sideIndex.left)
|
|
21196
|
-
|
|
21858
|
+
intra: sideIndex?.left === void 0 ? void 0 : model.intra.get(sideIndex.left),
|
|
21859
|
+
discussed: discussedPairs.has(index)
|
|
21860
|
+
}), discussionPx(index) > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
21861
|
+
className: PendingPanel_module_css_default.vSpacer,
|
|
21862
|
+
"data-diff-discussion-space": discussionPx(index),
|
|
21863
|
+
style: { height: discussionPx(index) },
|
|
21864
|
+
"aria-hidden": "true"
|
|
21865
|
+
})] }, index);
|
|
21197
21866
|
}),
|
|
21198
21867
|
end < pairCount && (0, react_jsx_runtime.jsx)("div", {
|
|
21199
21868
|
className: PendingPanel_module_css_default.vSpacer,
|
|
@@ -21221,7 +21890,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21221
21890
|
const index = start + offset;
|
|
21222
21891
|
const rightRuns = pair.right === void 0 ? void 0 : runs?.newRuns?.[(pair.right.line ?? 0) - 1];
|
|
21223
21892
|
const sideIndex = pairRowIndices.get(index);
|
|
21224
|
-
return (0, react_jsx_runtime.jsx)(SplitSideRow, {
|
|
21893
|
+
return (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [(0, react_jsx_runtime.jsx)(SplitSideRow, {
|
|
21225
21894
|
index,
|
|
21226
21895
|
side: pair.right,
|
|
21227
21896
|
wrapped: pairWrapped?.[index]?.right,
|
|
@@ -21235,8 +21904,14 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21235
21904
|
searchQuery,
|
|
21236
21905
|
searchOptions: search.options,
|
|
21237
21906
|
onHover: () => onPairHover(index),
|
|
21238
|
-
intra: sideIndex?.right === void 0 ? void 0 : model.intra.get(sideIndex.right)
|
|
21239
|
-
|
|
21907
|
+
intra: sideIndex?.right === void 0 ? void 0 : model.intra.get(sideIndex.right),
|
|
21908
|
+
discussed: discussedPairs.has(index)
|
|
21909
|
+
}), discussionPx(index) > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
21910
|
+
className: PendingPanel_module_css_default.vSpacer,
|
|
21911
|
+
"data-diff-discussion-space": discussionPx(index),
|
|
21912
|
+
style: { height: discussionPx(index) },
|
|
21913
|
+
"aria-hidden": "true"
|
|
21914
|
+
})] }, index);
|
|
21240
21915
|
}),
|
|
21241
21916
|
end < pairCount && (0, react_jsx_runtime.jsx)("div", {
|
|
21242
21917
|
className: PendingPanel_module_css_default.vSpacer,
|
|
@@ -21247,7 +21922,35 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21247
21922
|
})
|
|
21248
21923
|
})
|
|
21249
21924
|
]
|
|
21250
|
-
})
|
|
21925
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
21926
|
+
className: PendingPanel_module_css_default.splitDiscussions,
|
|
21927
|
+
"data-diff-split-discussions": true,
|
|
21928
|
+
style: {
|
|
21929
|
+
"--dsh-quote-width-left": `${widestSide.left}ch`,
|
|
21930
|
+
"--dsh-quote-width-right": `${widestSide.right}ch`
|
|
21931
|
+
},
|
|
21932
|
+
children: [...pairDiscussions.entries()].map(([pair, list]) => {
|
|
21933
|
+
const top = off(pair) + pairHeightAt(pair);
|
|
21934
|
+
const height = discussionPx(pair);
|
|
21935
|
+
if (top - scrollTop > viewportH + SPLIT_DISCUSSION_MARGIN_PX || top + height - scrollTop < -200) return null;
|
|
21936
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
21937
|
+
className: PendingPanel_module_css_default.splitDiscussion,
|
|
21938
|
+
"data-discussion-pair": pair,
|
|
21939
|
+
style: {
|
|
21940
|
+
top,
|
|
21941
|
+
width: bodyWidth,
|
|
21942
|
+
height
|
|
21943
|
+
},
|
|
21944
|
+
children: list.map((discussion) => (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderDiscussion?.(discussion, bodyWidth, true) }, discussion.id))
|
|
21945
|
+
}, pair);
|
|
21946
|
+
})
|
|
21947
|
+
})]
|
|
21948
|
+
}),
|
|
21949
|
+
selectionComment !== void 0 && selection !== void 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
21950
|
+
className: PendingPanel_module_css_default.blockActions,
|
|
21951
|
+
"data-diff-selection-actions": true,
|
|
21952
|
+
style: { top: Math.max(0, Math.min(off(selection.end + 1) - scrollTop, Math.max(0, viewportH - 32))) },
|
|
21953
|
+
children: selectionComment
|
|
21251
21954
|
}),
|
|
21252
21955
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
21253
21956
|
className: PendingPanel_module_css_default.splitHScrollRow,
|
|
@@ -21492,10 +22195,48 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21492
22195
|
side: side === "left" ? "old" : "new"
|
|
21493
22196
|
};
|
|
21494
22197
|
}
|
|
22198
|
+
/** The first and last text node inside `root`, or undefined when it holds no text. */
|
|
22199
|
+
function textEdgesOf(root) {
|
|
22200
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
22201
|
+
const first = walker.nextNode();
|
|
22202
|
+
if (!(first instanceof Text)) return void 0;
|
|
22203
|
+
let last = first;
|
|
22204
|
+
for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) if (node instanceof Text) last = node;
|
|
22205
|
+
return {
|
|
22206
|
+
first,
|
|
22207
|
+
last
|
|
22208
|
+
};
|
|
22209
|
+
}
|
|
22210
|
+
/**
|
|
22211
|
+
* The text position a point names, in whichever of the two spellings the browser has — or undefined
|
|
22212
|
+
* when it has neither, which is when the panel has to leave the selection to the browser (see the
|
|
22213
|
+
* split view's own drag).
|
|
22214
|
+
* @param x - client X of the point.
|
|
22215
|
+
* @param y - client Y of the point.
|
|
22216
|
+
* @returns the position, or undefined when the browser cannot resolve one.
|
|
22217
|
+
*/
|
|
22218
|
+
function caretAtPoint(x, y) {
|
|
22219
|
+
const api = document;
|
|
22220
|
+
const range = api.caretRangeFromPoint?.(x, y);
|
|
22221
|
+
if (range !== void 0 && range !== null) return {
|
|
22222
|
+
node: range.startContainer,
|
|
22223
|
+
offset: range.startOffset
|
|
22224
|
+
};
|
|
22225
|
+
const position = api.caretPositionFromPoint?.(x, y);
|
|
22226
|
+
return position === void 0 || position === null ? void 0 : {
|
|
22227
|
+
node: position.offsetNode,
|
|
22228
|
+
offset: position.offset
|
|
22229
|
+
};
|
|
22230
|
+
}
|
|
21495
22231
|
/**
|
|
21496
22232
|
* Derive the selected split pair range per side (a left-column selection
|
|
21497
|
-
* references the old file, a right-column selection the new file).
|
|
21498
|
-
*
|
|
22233
|
+
* references the old file, a right-column selection the new file). The two ends
|
|
22234
|
+
* can only disagree about the side when the selection was not made by the split
|
|
22235
|
+
* view's own drag, which cannot leave its column (see `SplitDiff`) — a keyboard
|
|
22236
|
+
* selection onto the neighbouring column, say, or a touch press. The range then
|
|
22237
|
+
* belongs to the column the selection began in and covers the pairs both ends
|
|
22238
|
+
* name: the pairs are the same list in both halves, so that is the range a
|
|
22239
|
+
* selection that stayed in that half would have made.
|
|
21499
22240
|
*/
|
|
21500
22241
|
function splitRowRangeOf(selection) {
|
|
21501
22242
|
if (selection === null || selection.isCollapsed || selection.rangeCount === 0) return void 0;
|
|
@@ -21503,7 +22244,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21503
22244
|
const startInfo = splitRowInfoAt(range.startContainer);
|
|
21504
22245
|
const endInfo = splitRowInfoAt(range.endContainer);
|
|
21505
22246
|
if (startInfo === void 0 || endInfo === void 0) return void 0;
|
|
21506
|
-
if (startInfo.side !== endInfo.side) return void 0;
|
|
21507
22247
|
let start = startInfo.pairIndex;
|
|
21508
22248
|
let end = endInfo.pairIndex;
|
|
21509
22249
|
if (lineOffsetAt(range.startContainer, range.startOffset) >= lineLengthAt(range.startContainer)) start += 1;
|
|
@@ -21512,7 +22252,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21512
22252
|
return {
|
|
21513
22253
|
start,
|
|
21514
22254
|
end,
|
|
21515
|
-
side: startInfo.side
|
|
22255
|
+
side: splitRowInfoAt(selection.anchorNode)?.side ?? startInfo.side
|
|
21516
22256
|
};
|
|
21517
22257
|
}
|
|
21518
22258
|
/** The code cell in `node`'s visual row, a sibling of its gutter cells. A
|
|
@@ -21726,7 +22466,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21726
22466
|
});
|
|
21727
22467
|
}
|
|
21728
22468
|
/** The selected file's diff, actions, jump controls, and copy toolbar. */
|
|
21729
|
-
function PendingDiff({ file, busy, workspacePath, jumpSignal, undoFlash, landingTop, landingTick, landingRow, failedMessage, commentSkill, onPasteReference, onAskAgent, watchChat, onToast, t, onAddTypedPath, onKeep, onRevert, onRefreshVcs, onBlockKeep, onBlockRevert, onOpen, onPreviewImage }) {
|
|
22469
|
+
function PendingDiff({ file, busy, workspacePath, jumpSignal, undoFlash, landingTop, landingTick, landingRow, landingCard, onLanded, failedMessage, commentSkill, onPasteReference, onAskAgent, watchChat, onToast, t, onAddTypedPath, onKeep, onRevert, onRefreshVcs, onBlockKeep, onBlockRevert, onOpen, onPreviewImage }) {
|
|
21730
22470
|
/** The path being typed into the header field; null shows the open file's own path. */
|
|
21731
22471
|
const [pathDraft, setPathDraft] = (0, react.useState)(null);
|
|
21732
22472
|
const [langOverride, setLangOverride] = (0, react.useState)(void 0);
|
|
@@ -21797,7 +22537,52 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21797
22537
|
file.newText,
|
|
21798
22538
|
splitView
|
|
21799
22539
|
]);
|
|
21800
|
-
const
|
|
22540
|
+
const splitModel = (0, react.useMemo)(() => splitView ? computeSideBySideDiff(model.diff.rows, true) : null, [splitView, model]);
|
|
22541
|
+
const splitPairs = splitModel?.pairs ?? null;
|
|
22542
|
+
/**
|
|
22543
|
+
* Which model row each pair holds on each side: the side-by-side view selects PAIRS and names one
|
|
22544
|
+
* column (see `splitRowRangeOf`), while everything that reads a selection as lines — the anchor a
|
|
22545
|
+
* comment is written to, and the "this range already has a thread" test — speaks rows.
|
|
22546
|
+
*/
|
|
22547
|
+
const pairRows = (0, react.useMemo)(() => {
|
|
22548
|
+
const map = /* @__PURE__ */ new Map();
|
|
22549
|
+
if (splitModel === null) return map;
|
|
22550
|
+
model.diff.rows.forEach((row, rowIndex) => {
|
|
22551
|
+
const pair = splitModel.pairOfRow.get(rowIndex);
|
|
22552
|
+
if (pair === void 0) return;
|
|
22553
|
+
const entry = map.get(pair) ?? {};
|
|
22554
|
+
if (row.kind !== "add") entry.old = rowIndex;
|
|
22555
|
+
if (row.kind !== "del") entry.new = rowIndex;
|
|
22556
|
+
map.set(pair, entry);
|
|
22557
|
+
});
|
|
22558
|
+
return map;
|
|
22559
|
+
}, [splitModel, model]);
|
|
22560
|
+
/**
|
|
22561
|
+
* The rows a selection names, whichever view made it: the pair range of a side-by-side selection
|
|
22562
|
+
* mapped to that column's rows, and a single-column range left as it is.
|
|
22563
|
+
*
|
|
22564
|
+
* Only the NEW side can be named. A thread is anchored to new-file lines — those are what survive
|
|
22565
|
+
* the model being rebuilt, and what its reference label shows — so a left-column selection (the
|
|
22566
|
+
* old file, code that may not exist any more) has nothing to anchor to: it reads as no rows, and
|
|
22567
|
+
* the comment is not offered on it.
|
|
22568
|
+
*
|
|
22569
|
+
* @param range - the selection to read.
|
|
22570
|
+
* @returns the same lines as a row range, or undefined when the view named none.
|
|
22571
|
+
*/
|
|
22572
|
+
const selectionRows = (range) => {
|
|
22573
|
+
if (range === void 0) return void 0;
|
|
22574
|
+
if (!splitView || range.side === void 0 || splitModel === null) return range;
|
|
22575
|
+
if (range.side !== "new") return void 0;
|
|
22576
|
+
const rows = [];
|
|
22577
|
+
for (let index = range.start; index <= range.end; index++) {
|
|
22578
|
+
const row = pairRows.get(index)?.new;
|
|
22579
|
+
if (row !== void 0) rows.push(row);
|
|
22580
|
+
}
|
|
22581
|
+
return rows.length === 0 ? void 0 : {
|
|
22582
|
+
start: Math.min(...rows),
|
|
22583
|
+
end: Math.max(...rows)
|
|
22584
|
+
};
|
|
22585
|
+
};
|
|
21801
22586
|
(0, react.useEffect)(() => {
|
|
21802
22587
|
if (!previewActive) return;
|
|
21803
22588
|
const body = mdPreviewBodyRef.current;
|
|
@@ -21880,6 +22665,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21880
22665
|
const [scrollTop, setScrollTop] = (0, react.useState)(0);
|
|
21881
22666
|
const [viewportHeight, setViewportHeight] = (0, react.useState)(0);
|
|
21882
22667
|
const [bodyWidth, setBodyWidth] = (0, react.useState)(0);
|
|
22668
|
+
/** The go-to-line dialog: whether it is up, and what has been typed into it. */
|
|
22669
|
+
const [gotoOpen, setGotoOpen] = (0, react.useState)(false);
|
|
22670
|
+
const [gotoDraft, setGotoDraft] = (0, react.useState)("");
|
|
22671
|
+
/** The row a go-to-line flashed: its box frames that one row instead of the block around it. */
|
|
22672
|
+
const flashRowRef = (0, react.useRef)(void 0);
|
|
21883
22673
|
const [hScrollbarPx, setHScrollbarPx] = (0, react.useState)(0);
|
|
21884
22674
|
const [hoveredBlock, setHoveredBlock] = (0, react.useState)(void 0);
|
|
21885
22675
|
const [selection, setSelection] = (0, react.useState)(void 0);
|
|
@@ -21898,12 +22688,9 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21898
22688
|
[file.id]: update(all[file.id] ?? EMPTY_DISCUSSIONS)
|
|
21899
22689
|
}));
|
|
21900
22690
|
};
|
|
21901
|
-
/** Which block's overflow menu is open, if any.
|
|
22691
|
+
/** Which block's overflow menu is open, if any. The card builds the menu's own row (see
|
|
22692
|
+
* `DiscussionBlock`): finishing a thread takes the block, and its rows, away. */
|
|
21902
22693
|
const [discussionMenuFor, setDiscussionMenuFor] = (0, react.useState)(void 0);
|
|
21903
|
-
const discussionMenuItems = (0, react.useMemo)(() => [{
|
|
21904
|
-
id: "delete",
|
|
21905
|
-
label: t("action.discussionEnd")
|
|
21906
|
-
}], [t]);
|
|
21907
22694
|
/** The session's chat, watched so a discussion can show the answer it asked for. */
|
|
21908
22695
|
const [chat, setChat] = (0, react.useState)({
|
|
21909
22696
|
running: false,
|
|
@@ -21947,6 +22734,14 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21947
22734
|
const landingTopRef = (0, react.useRef)(void 0);
|
|
21948
22735
|
/** The model row a jump to a comment asked for, spent the same way and by the same effect. */
|
|
21949
22736
|
const landingRowRef = (0, react.useRef)(void 0);
|
|
22737
|
+
/** Whether that row is a thread's own box rather than a place in the code (see `landingCard`). */
|
|
22738
|
+
const landingCardRef = (0, react.useRef)(false);
|
|
22739
|
+
/** The latest `onLanded`, for the landing effect: it says the ask has been taken, and the panel
|
|
22740
|
+
* then spends it so a pane that mounts later cannot take it again. Read through a ref because the
|
|
22741
|
+
* panel hands a fresh closure on every render, and re-running the landing effect for that would
|
|
22742
|
+
* place the file twice. */
|
|
22743
|
+
const onLandedRef = (0, react.useRef)(onLanded);
|
|
22744
|
+
onLandedRef.current = onLanded;
|
|
21950
22745
|
const selectionTextRef = (0, react.useRef)("");
|
|
21951
22746
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
21952
22747
|
const [searchOpen, setSearchOpen] = (0, react.useState)(false);
|
|
@@ -21962,16 +22757,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21962
22757
|
previewFlashPendingRef.current = true;
|
|
21963
22758
|
};
|
|
21964
22759
|
(0, react.useEffect)(() => {
|
|
21965
|
-
landingTopRef.current = landingTop;
|
|
21966
|
-
landingRowRef.current = landingRow;
|
|
21967
|
-
if (landingRow !== void 0) {
|
|
21968
|
-
setFocus(blockIndexAtOffset(offsetOf(landingRow)));
|
|
21969
|
-
bumpFlash(false);
|
|
21970
|
-
} else if (landingTop === void 0) {
|
|
21971
|
-
setFocus(0);
|
|
21972
|
-
bumpFlash(false);
|
|
21973
|
-
} else setFocus(blockIndexAtOffset(landingTop));
|
|
21974
|
-
setScrollTick((tick) => tick + 1);
|
|
21975
22760
|
bodyRef.current?.focus();
|
|
21976
22761
|
setHoveredBlock(void 0);
|
|
21977
22762
|
setSelection(void 0);
|
|
@@ -21981,11 +22766,44 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
21981
22766
|
setSearchOpen(false);
|
|
21982
22767
|
setSearchQuery("");
|
|
21983
22768
|
setSearchIndex(0);
|
|
22769
|
+
}, [file.id]);
|
|
22770
|
+
const landedFileRef = (0, react.useRef)(void 0);
|
|
22771
|
+
/** The file the placement effect below has decided the opening place for (see `placedFileRef`). */
|
|
22772
|
+
const placedFileRef = (0, react.useRef)(void 0);
|
|
22773
|
+
(0, react.useEffect)(() => {
|
|
22774
|
+
const landing = (landingTick ?? 0) > 0;
|
|
22775
|
+
const opened = landedFileRef.current !== file.id;
|
|
22776
|
+
landedFileRef.current = file.id;
|
|
22777
|
+
placedFileRef.current = file.id;
|
|
22778
|
+
if (!landing && !opened) return;
|
|
22779
|
+
if (landing) {
|
|
22780
|
+
landingTopRef.current = landingTop;
|
|
22781
|
+
landingRowRef.current = landingRow;
|
|
22782
|
+
landingCardRef.current = landingCard === true;
|
|
22783
|
+
if (landingRow !== void 0) {
|
|
22784
|
+
setFocus(blockIndexAtOffset(offsetOf(landingRow)));
|
|
22785
|
+
bumpFlash(false);
|
|
22786
|
+
} else if (landingTop === void 0) {
|
|
22787
|
+
setFocus(0);
|
|
22788
|
+
bumpFlash(false);
|
|
22789
|
+
} else setFocus(blockIndexAtOffset(landingTop));
|
|
22790
|
+
setScrollTick((tick) => tick + 1);
|
|
22791
|
+
onLandedRef.current?.();
|
|
22792
|
+
return;
|
|
22793
|
+
}
|
|
22794
|
+
landingRowRef.current = void 0;
|
|
22795
|
+
landingCardRef.current = false;
|
|
22796
|
+
const offset = panelFileOffset(file.sessionId, file.id);
|
|
22797
|
+
if (offset === void 0) return;
|
|
22798
|
+
landingTopRef.current = offset;
|
|
22799
|
+
setFocus(blockIndexAtOffset(offset));
|
|
22800
|
+
setScrollTick((tick) => tick + 1);
|
|
21984
22801
|
}, [
|
|
21985
22802
|
file.id,
|
|
21986
22803
|
landingTop,
|
|
21987
22804
|
landingTick,
|
|
21988
|
-
landingRow
|
|
22805
|
+
landingRow,
|
|
22806
|
+
landingCard
|
|
21989
22807
|
]);
|
|
21990
22808
|
(0, react.useEffect)(() => {
|
|
21991
22809
|
if (undoFlash === 0) return;
|
|
@@ -22522,16 +23340,35 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22522
23340
|
* row per quoted line whatever the width.
|
|
22523
23341
|
* @returns the occupied row count (whole).
|
|
22524
23342
|
*/
|
|
22525
|
-
const quoteRowsOf = (0, react.useCallback)((quote, wrap) => {
|
|
22526
|
-
|
|
22527
|
-
|
|
23343
|
+
const quoteRowsOf = (0, react.useCallback)((quote, lines, wrap, split) => {
|
|
23344
|
+
const texts = quote.split("\n");
|
|
23345
|
+
if (!split) {
|
|
23346
|
+
if (!wrap) return texts.length;
|
|
23347
|
+
const measure = makeMeasurer(codeFontOf());
|
|
23348
|
+
const width = Math.max(0, bodyWidth - discussionRightInsetPx) - WRAP_GUTTERS_PX;
|
|
23349
|
+
if (measure === void 0) return texts.length;
|
|
23350
|
+
const wrapping = width - measure("0");
|
|
23351
|
+
if (wrapping <= 0) return texts.length;
|
|
23352
|
+
const tabPx = tabWidthSpaces * measure(" ");
|
|
23353
|
+
return texts.reduce((rows, line) => rows + Math.max(1, wrapInto(line, wrapping, measure, tabPx).length), 0);
|
|
23354
|
+
}
|
|
23355
|
+
const pairs = computeSideBySideDiff(texts.map((text, index) => {
|
|
23356
|
+
const line = lines?.[index];
|
|
23357
|
+
return {
|
|
23358
|
+
text,
|
|
23359
|
+
kind: line?.kind ?? "context",
|
|
23360
|
+
oldLine: line?.old,
|
|
23361
|
+
newLine: line?.new
|
|
23362
|
+
};
|
|
23363
|
+
}), true).pairs;
|
|
23364
|
+
if (!wrap) return pairs.length;
|
|
22528
23365
|
const measure = makeMeasurer(codeFontOf());
|
|
22529
|
-
|
|
22530
|
-
|
|
22531
|
-
|
|
22532
|
-
if (wrapping <= 0) return lines.length;
|
|
23366
|
+
if (measure === void 0) return pairs.length;
|
|
23367
|
+
const wrapping = Math.max(0, (bodyWidth - 1) / 2) - WRAP_GUTTERS_PX / 2 - measure("0");
|
|
23368
|
+
if (wrapping <= 0) return pairs.length;
|
|
22533
23369
|
const tabPx = tabWidthSpaces * measure(" ");
|
|
22534
|
-
|
|
23370
|
+
const rowsIn = (text) => text === void 0 ? 1 : Math.max(1, wrapInto(text, wrapping, measure, tabPx).length);
|
|
23371
|
+
return pairs.reduce((count, pair) => count + Math.max(rowsIn(pair.left?.text), rowsIn(pair.right?.text)), 0);
|
|
22535
23372
|
}, [
|
|
22536
23373
|
bodyWidth,
|
|
22537
23374
|
discussionRightInsetPx,
|
|
@@ -22560,13 +23397,27 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22560
23397
|
* @returns the messages to render, the hidden count, and the body height.
|
|
22561
23398
|
*/
|
|
22562
23399
|
const roundLimit = discussionRoundLimit();
|
|
23400
|
+
/**
|
|
23401
|
+
* Rows a thread's own rendered height corrected the model to, by thread id.
|
|
23402
|
+
*
|
|
23403
|
+
* The rows a block reserves are meant to BE the rows it draws, and the wrap model above is how
|
|
23404
|
+
* they are worked out — but a wrap model that is off by a row or by ten shows up as air under the
|
|
23405
|
+
* writing row (or as a clipped turn), and this one demonstrably is: the same answer has measured
|
|
23406
|
+
* 7, 11, 25 and 35 rows in different sessions at the same width. So the block's own rendered
|
|
23407
|
+
* height is read back after every render and the reservation is corrected to it — the same
|
|
23408
|
+
* "measure it, do not reason about it" rule the code view's wrapped rows follow. The map only
|
|
23409
|
+
* ever holds what was measured, and an entry stops changing once the drawing settles.
|
|
23410
|
+
*/
|
|
23411
|
+
const [rowFix, setRowFix] = (0, react.useState)({});
|
|
22563
23412
|
const layoutDiscussion = (0, react.useCallback)((discussion) => {
|
|
22564
23413
|
const answer = discussion.reply === void 0 ? void 0 : stripBlankLines(discussion.reply);
|
|
22565
23414
|
const stoppedNote = discussion.stopped === true && (answer === void 0 || answer === "") && discussion.failed !== true;
|
|
22566
|
-
const
|
|
23415
|
+
const outdatedRows = discussion.lost === true && discussion.quote !== void 0 && discussion.quote !== "" ? 1 + quoteRowsOf(discussion.quote, discussion.quoteLines, langWrap, splitView) * (ROW_HEIGHT_PX / THREAD_ROW_PX) : 0;
|
|
23416
|
+
const writingNote = discussion.asking === true && answer !== void 0 && answer !== "";
|
|
23417
|
+
const trailing = outdatedRows + (answer !== void 0 && answer !== "" ? messageSizeOf({
|
|
22567
23418
|
role: "assistant",
|
|
22568
23419
|
text: answer
|
|
22569
|
-
}) : discussion.failed === true || discussion.asking === true ? 1 : 2 + (stoppedNote ? 1 : 0));
|
|
23420
|
+
}) + (writingNote ? 1 : 0) : discussion.failed === true || discussion.asking === true ? 1 : 2 + (stoppedNote ? 1 : 0));
|
|
22570
23421
|
const tail = discussionRounds(discussion.messages, roundLimit, messageSizeOf);
|
|
22571
23422
|
return {
|
|
22572
23423
|
messages: tail.messages,
|
|
@@ -22578,7 +23429,9 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22578
23429
|
quoteRowsOf,
|
|
22579
23430
|
messageSizeOf,
|
|
22580
23431
|
roundLimit,
|
|
22581
|
-
ROW_HEIGHT_PX
|
|
23432
|
+
ROW_HEIGHT_PX,
|
|
23433
|
+
bodyWidth,
|
|
23434
|
+
splitView
|
|
22582
23435
|
]);
|
|
22583
23436
|
/**
|
|
22584
23437
|
* The discussions as the render will draw them: the body height the measurement
|
|
@@ -22591,15 +23444,20 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22591
23444
|
const laid = layoutDiscussion(discussion);
|
|
22592
23445
|
return {
|
|
22593
23446
|
...discussion,
|
|
22594
|
-
bodyRows: laid.rows,
|
|
23447
|
+
bodyRows: rowFix[discussion.id] ?? laid.rows,
|
|
22595
23448
|
hidden: laid.hidden,
|
|
23449
|
+
quoteWrap: langWrap,
|
|
22596
23450
|
messages: laid.messages.map((message) => ({
|
|
22597
23451
|
...message,
|
|
22598
23452
|
text: discussionText(message)
|
|
22599
23453
|
})),
|
|
22600
23454
|
...discussion.reply === void 0 ? {} : { reply: stripBlankLines(discussion.reply) }
|
|
22601
23455
|
};
|
|
22602
|
-
}), [
|
|
23456
|
+
}), [
|
|
23457
|
+
discussions,
|
|
23458
|
+
layoutDiscussion,
|
|
23459
|
+
rowFix
|
|
23460
|
+
]);
|
|
22603
23461
|
const discussionExtras = (0, react.useMemo)(() => discussionRowExtras(laidDiscussions, rows.length), [laidDiscussions, rows.length]);
|
|
22604
23462
|
const discussionsAtRow = (0, react.useMemo)(() => {
|
|
22605
23463
|
const byRow = /* @__PURE__ */ new Map();
|
|
@@ -22681,6 +23539,16 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22681
23539
|
(0, react.useEffect)(() => {
|
|
22682
23540
|
rememberDiscussions(file.sessionId, discussionsByFile);
|
|
22683
23541
|
}, [file.sessionId, discussionsByFile]);
|
|
23542
|
+
(0, react.useEffect)(() => {
|
|
23543
|
+
const changed = () => {
|
|
23544
|
+
const next = rememberedDiscussions(file.sessionId);
|
|
23545
|
+
setDiscussionsByFile((all) => all === next ? all : next);
|
|
23546
|
+
};
|
|
23547
|
+
window.addEventListener(COMMENTS_CHANGED_EVENT, changed);
|
|
23548
|
+
return () => {
|
|
23549
|
+
window.removeEventListener(COMMENTS_CHANGED_EVENT, changed);
|
|
23550
|
+
};
|
|
23551
|
+
}, [file.sessionId]);
|
|
22684
23552
|
/** Patch one discussion in place, without touching the others or the file key. */
|
|
22685
23553
|
const updateDiscussion = (0, react.useCallback)((id, patch) => {
|
|
22686
23554
|
setDiscussionsByFile((all) => {
|
|
@@ -22873,7 +23741,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22873
23741
|
const next = remapDiscussions(list, (row) => {
|
|
22874
23742
|
const entry = model.diff.rows[row];
|
|
22875
23743
|
return entry?.newLine ?? entry?.oldLine;
|
|
22876
|
-
}, (row) => model.diff.rows[row]?.text ?? "", model.diff.rows.length);
|
|
23744
|
+
}, (row) => model.diff.rows[row]?.text ?? "", model.diff.rows.length, (row) => model.diff.rows[row]?.newLine !== void 0);
|
|
22877
23745
|
return next.some((discussion, index) => discussion !== list[index]) ? {
|
|
22878
23746
|
...all,
|
|
22879
23747
|
[file.id]: next
|
|
@@ -22927,32 +23795,35 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
22927
23795
|
/** Start a discussion on the current selection (no-op on a range that has one). */
|
|
22928
23796
|
const addDiscussion = () => {
|
|
22929
23797
|
if (!commentMode) return;
|
|
22930
|
-
|
|
22931
|
-
if (
|
|
22932
|
-
|
|
22933
|
-
const
|
|
23798
|
+
const range = selectionRows(selection);
|
|
23799
|
+
if (range === void 0) return;
|
|
23800
|
+
if (discussionOverlapping(discussions, range) !== void 0) return;
|
|
23801
|
+
const first = model.diff.rows[range.start];
|
|
23802
|
+
const last = model.diff.rows[range.end] ?? first;
|
|
22934
23803
|
const startLine = first?.newLine ?? first?.oldLine;
|
|
22935
23804
|
if (startLine === void 0) return;
|
|
22936
23805
|
const endLine = last?.newLine ?? last?.oldLine ?? startLine;
|
|
22937
23806
|
const body = bodyRef.current;
|
|
22938
|
-
if (body !== null && offsetOf(
|
|
23807
|
+
if (body !== null && offsetOf(range.start) - body.scrollTop < 0) pendingScrollShiftRef.current += 66;
|
|
22939
23808
|
const id = `discussion-${Date.now().toString(36)}-${discussions.length}`;
|
|
22940
|
-
const quoted = model.diff.rows.slice(
|
|
23809
|
+
const quoted = model.diff.rows.slice(range.start, range.end + 1);
|
|
22941
23810
|
const quote = quoted.map((row) => row.text).join("\n");
|
|
22942
23811
|
const quoteLines = quoted.map((row) => ({
|
|
22943
23812
|
old: row.oldLine,
|
|
22944
23813
|
new: row.newLine,
|
|
22945
23814
|
kind: row.kind
|
|
22946
23815
|
}));
|
|
23816
|
+
const quoteContext = model.diff.rows.slice(Math.max(0, range.start - 1), Math.min(model.diff.rows.length, range.end + 2)).map((row) => row.text).join("\n");
|
|
22947
23817
|
setDiscussions((current) => [...current, {
|
|
22948
23818
|
id,
|
|
22949
23819
|
anchor: {
|
|
22950
|
-
start:
|
|
22951
|
-
end:
|
|
23820
|
+
start: range.start,
|
|
23821
|
+
end: range.end,
|
|
22952
23822
|
startLine,
|
|
22953
23823
|
endLine
|
|
22954
23824
|
},
|
|
22955
23825
|
quote,
|
|
23826
|
+
quoteContext,
|
|
22956
23827
|
quoteLines,
|
|
22957
23828
|
messages: [],
|
|
22958
23829
|
draft: "",
|
|
@@ -23154,29 +24025,98 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23154
24025
|
previewActive,
|
|
23155
24026
|
splitView
|
|
23156
24027
|
]);
|
|
24028
|
+
const widthMovedRef = (0, react.useRef)(false);
|
|
24029
|
+
(0, react.useLayoutEffect)(() => {
|
|
24030
|
+
const body = bodyRef.current;
|
|
24031
|
+
if (body === null) return;
|
|
24032
|
+
const width = body.clientWidth;
|
|
24033
|
+
widthMovedRef.current = width !== bodyWidth;
|
|
24034
|
+
if (width !== bodyWidth) setBodyWidth(width);
|
|
24035
|
+
});
|
|
24036
|
+
const rowFixRef = (0, react.useRef)(rowFix);
|
|
24037
|
+
rowFixRef.current = rowFix;
|
|
24038
|
+
const fitWidthRef = (0, react.useRef)(0);
|
|
24039
|
+
const [, bumpFixTick] = (0, react.useReducer)((n) => n + 1, 0);
|
|
24040
|
+
const fixTickArmedRef = (0, react.useRef)(false);
|
|
24041
|
+
(0, react.useLayoutEffect)(() => {
|
|
24042
|
+
const cardWidth = document.querySelector("[data-diff-discussion]")?.getBoundingClientRect().width ?? 0;
|
|
24043
|
+
const settled = cardWidth > 0 && Math.abs(cardWidth - fitWidthRef.current) <= 1;
|
|
24044
|
+
fitWidthRef.current = cardWidth;
|
|
24045
|
+
if (!settled) {
|
|
24046
|
+
if (cardWidth > 0 && !widthMovedRef.current && !fixTickArmedRef.current) {
|
|
24047
|
+
const armed = bodyRef.current?.clientWidth ?? 0;
|
|
24048
|
+
fixTickArmedRef.current = true;
|
|
24049
|
+
requestAnimationFrame(() => {
|
|
24050
|
+
fixTickArmedRef.current = false;
|
|
24051
|
+
if ((bodyRef.current?.clientWidth ?? 0) !== armed) return;
|
|
24052
|
+
bumpFixTick();
|
|
24053
|
+
});
|
|
24054
|
+
}
|
|
24055
|
+
return;
|
|
24056
|
+
}
|
|
24057
|
+
const next = { ...rowFixRef.current };
|
|
24058
|
+
let changed = false;
|
|
24059
|
+
for (const card of document.querySelectorAll("[data-diff-discussion]")) {
|
|
24060
|
+
const id = card.dataset.diffDiscussionId;
|
|
24061
|
+
const body = card.children[1];
|
|
24062
|
+
const last = body?.lastElementChild;
|
|
24063
|
+
if (id === void 0 || body === void 0 || last === null || last === void 0) continue;
|
|
24064
|
+
const drawn = last.getBoundingClientRect().bottom + (Number.parseFloat(getComputedStyle(last).marginBottom) || 0) - body.getBoundingClientRect().top;
|
|
24065
|
+
if (drawn <= 0) continue;
|
|
24066
|
+
const want = Math.max(1, Math.ceil(drawn / THREAD_ROW_PX));
|
|
24067
|
+
if (next[id] !== want) {
|
|
24068
|
+
next[id] = want;
|
|
24069
|
+
changed = true;
|
|
24070
|
+
}
|
|
24071
|
+
}
|
|
24072
|
+
if (changed) setRowFix(next);
|
|
24073
|
+
});
|
|
24074
|
+
/**
|
|
24075
|
+
* Move the code view to one offset, and take the page's memory with it.
|
|
24076
|
+
*
|
|
24077
|
+
* The memory is what a pane that remounts under the reader resumes (see the landing effect), so it
|
|
24078
|
+
* has to follow every write the panel itself makes — a jump included. Mirroring only the reader's
|
|
24079
|
+
* own scrolls would leave a remount resuming the place they left rather than the place the jump
|
|
24080
|
+
* put them, which is the same "it moved on its own" the memory exists to stop.
|
|
24081
|
+
*
|
|
24082
|
+
* @param body - the code view's scroll box.
|
|
24083
|
+
* @param offset - the offset to settle it at.
|
|
24084
|
+
*/
|
|
24085
|
+
const applyScrollTop = (body, offset) => {
|
|
24086
|
+
if (body.scrollTop !== offset) body.scrollTop = offset;
|
|
24087
|
+
setScrollTop(offset);
|
|
24088
|
+
rememberPanelView(file.sessionId, {
|
|
24089
|
+
fileId: file.id,
|
|
24090
|
+
scrollTop: offset
|
|
24091
|
+
});
|
|
24092
|
+
};
|
|
23157
24093
|
(0, react.useLayoutEffect)(() => {
|
|
23158
24094
|
if (rowCount === 0) return;
|
|
24095
|
+
if (placedFileRef.current !== file.id) return;
|
|
23159
24096
|
const resumed = landingTopRef.current;
|
|
23160
24097
|
if (resumed !== void 0) {
|
|
23161
24098
|
landingTopRef.current = void 0;
|
|
23162
24099
|
if (!previewActive) {
|
|
23163
24100
|
const resumeBody = bodyRef.current;
|
|
23164
|
-
if (resumeBody !== null)
|
|
23165
|
-
const clamped = Math.max(0, Math.min(resumed, resumeBody.scrollHeight - resumeBody.clientHeight));
|
|
23166
|
-
if (resumeBody.scrollTop !== clamped) resumeBody.scrollTop = clamped;
|
|
23167
|
-
setScrollTop(clamped);
|
|
23168
|
-
}
|
|
24101
|
+
if (resumeBody !== null) applyScrollTop(resumeBody, Math.max(0, Math.min(resumed, resumeBody.scrollHeight - resumeBody.clientHeight)));
|
|
23169
24102
|
}
|
|
23170
24103
|
return;
|
|
23171
24104
|
}
|
|
23172
24105
|
const row = landingRowRef.current;
|
|
23173
24106
|
if (row !== void 0 && !previewActive) {
|
|
24107
|
+
const toCard = landingCardRef.current;
|
|
23174
24108
|
landingRowRef.current = void 0;
|
|
24109
|
+
landingCardRef.current = false;
|
|
24110
|
+
flashRowRef.current = void 0;
|
|
24111
|
+
if (splitView) {
|
|
24112
|
+
splitDiffRef.current?.land(row, toCard);
|
|
24113
|
+
return;
|
|
24114
|
+
}
|
|
23175
24115
|
const rowBody = bodyRef.current;
|
|
23176
24116
|
if (rowBody !== null) {
|
|
23177
|
-
const
|
|
23178
|
-
|
|
23179
|
-
|
|
24117
|
+
const cardTop = offsetOf(row + 1) - (discussionExtras.get(row) ?? 0) * THREAD_ROW_PX;
|
|
24118
|
+
const target = toCard ? cardTop : offsetOf(row);
|
|
24119
|
+
applyScrollTop(rowBody, Math.max(0, Math.min(target - leadRows * ROW_HEIGHT_PX, rowBody.scrollHeight - rowBody.clientHeight)));
|
|
23180
24120
|
}
|
|
23181
24121
|
return;
|
|
23182
24122
|
}
|
|
@@ -23193,9 +24133,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23193
24133
|
const body = bodyRef.current;
|
|
23194
24134
|
if (body === null) return;
|
|
23195
24135
|
const target = offsetOf(block.start) - leadRows * ROW_HEIGHT_PX;
|
|
23196
|
-
|
|
23197
|
-
if (body.scrollTop !== clamped) body.scrollTop = clamped;
|
|
23198
|
-
setScrollTop(clamped);
|
|
24136
|
+
applyScrollTop(body, Math.max(0, Math.min(target, body.scrollHeight - body.clientHeight)));
|
|
23199
24137
|
}, [
|
|
23200
24138
|
scrollTick,
|
|
23201
24139
|
offsetsFromWrap,
|
|
@@ -23243,6 +24181,43 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23243
24181
|
};
|
|
23244
24182
|
const jumpBlockRef = (0, react.useRef)(jumpBlock);
|
|
23245
24183
|
jumpBlockRef.current = jumpBlock;
|
|
24184
|
+
/**
|
|
24185
|
+
* Go to a line of the file as it reads NOW: the row carrying that new-file line, because the old side
|
|
24186
|
+
* of the diff is not a place a reader can be sent (its numbers belong to text that is already gone) —
|
|
24187
|
+
* a number that only exists there is answered with a note instead. Both views take it the way a comment
|
|
24188
|
+
* jump does: the split view through its own handle, one column through the height table, with the
|
|
24189
|
+
* configured lead rows above it and the block it lands in flashed.
|
|
24190
|
+
*/
|
|
24191
|
+
const gotoLine = (line) => {
|
|
24192
|
+
const row = model.diff.rows.findIndex((entry) => entry.newLine === line);
|
|
24193
|
+
if (row === -1) {
|
|
24194
|
+
onToast(t("panel.gotoMissing", { line }));
|
|
24195
|
+
return;
|
|
24196
|
+
}
|
|
24197
|
+
if (splitView && !previewActive) {
|
|
24198
|
+
splitDiffRef.current?.land(row, false, true);
|
|
24199
|
+
return;
|
|
24200
|
+
}
|
|
24201
|
+
bumpFlash(false);
|
|
24202
|
+
flashRowRef.current = row;
|
|
24203
|
+
setFocus(blockIndexAtOffset(offsetOf(row)));
|
|
24204
|
+
const body = bodyRef.current;
|
|
24205
|
+
if (body === null) return;
|
|
24206
|
+
applyScrollTop(body, Math.max(0, Math.min(offsetOf(row) - leadRows * ROW_HEIGHT_PX, body.scrollHeight - body.clientHeight)));
|
|
24207
|
+
};
|
|
24208
|
+
(0, react.useEffect)(() => {
|
|
24209
|
+
const onKeyDown = (event) => {
|
|
24210
|
+
if (!matchesShortcut(event, keybindingOf("goto"))) return;
|
|
24211
|
+
if (isTextFieldEvent(event) || pathPickerOpen()) return;
|
|
24212
|
+
event.preventDefault();
|
|
24213
|
+
setGotoDraft("");
|
|
24214
|
+
setGotoOpen(true);
|
|
24215
|
+
};
|
|
24216
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
24217
|
+
return () => {
|
|
24218
|
+
window.removeEventListener("keydown", onKeyDown, true);
|
|
24219
|
+
};
|
|
24220
|
+
}, []);
|
|
23246
24221
|
const stepBlock = (direction) => {
|
|
23247
24222
|
const count = model.blocks.length;
|
|
23248
24223
|
if (count === 0) return;
|
|
@@ -23306,6 +24281,10 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23306
24281
|
const body = bodyRef.current;
|
|
23307
24282
|
if (body === null) return;
|
|
23308
24283
|
syncQuoteScroll(body);
|
|
24284
|
+
rememberPanelView(file.sessionId, {
|
|
24285
|
+
fileId: file.id,
|
|
24286
|
+
scrollTop: body.scrollTop
|
|
24287
|
+
});
|
|
23309
24288
|
setScrollTop(body.scrollTop);
|
|
23310
24289
|
setViewportHeight(body.clientHeight);
|
|
23311
24290
|
const count = model.blocks.length;
|
|
@@ -23432,9 +24411,59 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23432
24411
|
window.removeEventListener(COMMENT_MODE_CHANGED_EVENT, onCommentMode);
|
|
23433
24412
|
};
|
|
23434
24413
|
}, []);
|
|
23435
|
-
|
|
23436
|
-
|
|
23437
|
-
|
|
24414
|
+
/**
|
|
24415
|
+
* One thread's card, as every view draws it. The views differ only in where the card hangs and
|
|
24416
|
+
* how wide the thing it hangs in is, so the card itself is built in exactly one place (see
|
|
24417
|
+
* `DiscussionBlock`): the single-column row stream, and whatever view comes next.
|
|
24418
|
+
*/
|
|
24419
|
+
const renderDiscussion = (0, react.useCallback)((discussion, width, split) => (0, react_jsx_runtime.jsx)(DiscussionBlock, {
|
|
24420
|
+
discussion,
|
|
24421
|
+
label: discussionLineRange(discussion.anchor),
|
|
24422
|
+
bodyWidth: width,
|
|
24423
|
+
lang,
|
|
24424
|
+
menuOpen: discussionMenuFor === discussion.id,
|
|
24425
|
+
asking: askingId !== void 0,
|
|
24426
|
+
split,
|
|
24427
|
+
t,
|
|
24428
|
+
onToggle: toggleDiscussion,
|
|
24429
|
+
onMenuOpen: setDiscussionMenuFor,
|
|
24430
|
+
onRemove: removeDiscussion,
|
|
24431
|
+
onDraft: (id, value) => {
|
|
24432
|
+
setDiscussions((current) => current.map((entry) => entry.id === id ? {
|
|
24433
|
+
...entry,
|
|
24434
|
+
draft: value
|
|
24435
|
+
} : entry));
|
|
24436
|
+
},
|
|
24437
|
+
onSend: sendDiscussion,
|
|
24438
|
+
registerInput: (id, element) => {
|
|
24439
|
+
if (element === null) discussionInputEls.current.delete(id);
|
|
24440
|
+
else discussionInputEls.current.set(id, element);
|
|
24441
|
+
}
|
|
24442
|
+
}), [
|
|
24443
|
+
discussionMenuFor,
|
|
24444
|
+
askingId,
|
|
24445
|
+
t,
|
|
24446
|
+
lang,
|
|
24447
|
+
toggleDiscussion,
|
|
24448
|
+
removeDiscussion,
|
|
24449
|
+
sendDiscussion,
|
|
24450
|
+
discussionLineRange
|
|
24451
|
+
]);
|
|
24452
|
+
/**
|
|
24453
|
+
* The lines a selection names, whichever view made it, or undefined when it names none this panel
|
|
24454
|
+
* can comment on — a side-by-side selection of the LEFT column is the old file, and a thread is
|
|
24455
|
+
* anchored to new-file lines. The frame (and the chord) hang off this, so the left column simply
|
|
24456
|
+
* offers nothing.
|
|
24457
|
+
*/
|
|
24458
|
+
const selectionRowRange = selectionRows(selection);
|
|
24459
|
+
/**
|
|
24460
|
+
* Whether those lines already carry a thread: the comment is withheld then (a row belongs to one
|
|
24461
|
+
* annotation at most).
|
|
24462
|
+
*/
|
|
24463
|
+
const selectionHasDiscussion = selectionRowRange !== void 0 && discussionOverlapping(discussions, selectionRowRange) !== void 0;
|
|
24464
|
+
const frameForSelection = selectionRowRange !== void 0 ? selectionFrame({
|
|
24465
|
+
coversBlocks: !splitView && selectionRange !== void 0,
|
|
24466
|
+
hasDiscussion: selectionHasDiscussion
|
|
23438
24467
|
}) : void 0;
|
|
23439
24468
|
const selectionCommentOffered = commentMode && frameForSelection?.comment === true;
|
|
23440
24469
|
const selectionFrameVisible = frameForSelection !== void 0 && (frameForSelection.keepRevert || selectionCommentOffered);
|
|
@@ -23567,8 +24596,9 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23567
24596
|
const scrollbarWidth = scroller.offsetWidth - scroller.clientWidth;
|
|
23568
24597
|
return Math.max(0, scroller.clientWidth - (scrollbarWidth > 0 ? 0 : OVERVIEW_RULER_WIDTH_PX));
|
|
23569
24598
|
})();
|
|
23570
|
-
const
|
|
23571
|
-
const
|
|
24599
|
+
const flashRow = flashRowRef.current;
|
|
24600
|
+
const flashTop = flashRow !== void 0 ? Math.max(0, offsetOf(flashRow) - scrollTop) : focusedBlock === void 0 ? 0 : Math.max(0, offsetOf(focusedBlock.start) - scrollTop);
|
|
24601
|
+
const flashBottom = flashRow !== void 0 ? Math.min(viewportHeight > 0 ? viewportHeight : Number.POSITIVE_INFINITY, offsetOf(flashRow + 1) - scrollTop) : focusedBlock === void 0 ? 0 : Math.min(viewportHeight > 0 ? viewportHeight : Number.POSITIVE_INFINITY, offsetOf(focusedBlock.end + 1) - scrollTop);
|
|
23572
24602
|
const flashHeight = Math.max(0, flashBottom - flashTop);
|
|
23573
24603
|
const previewFlashNow = previewActive ? previewFlashBox(previewFlash, previewScrollTopRef.current) : void 0;
|
|
23574
24604
|
const searchBar = searchOpen ? (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -23851,6 +24881,110 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
23851
24881
|
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 14 })
|
|
23852
24882
|
})
|
|
23853
24883
|
}),
|
|
24884
|
+
previewActive ? null : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
24885
|
+
label: withChord(t("action.goto"), "goto"),
|
|
24886
|
+
side: "bottom",
|
|
24887
|
+
delayMs: 500,
|
|
24888
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
24889
|
+
type: "button",
|
|
24890
|
+
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.iconAction}`,
|
|
24891
|
+
"data-diff-goto": true,
|
|
24892
|
+
"aria-label": t("action.goto"),
|
|
24893
|
+
onClick: () => {
|
|
24894
|
+
setGotoDraft("");
|
|
24895
|
+
setGotoOpen(true);
|
|
24896
|
+
},
|
|
24897
|
+
children: (0, react_jsx_runtime.jsx)(GotoLineIcon, {})
|
|
24898
|
+
})
|
|
24899
|
+
}),
|
|
24900
|
+
gotoOpen && (0, react_jsx_runtime.jsx)("div", {
|
|
24901
|
+
role: "dialog",
|
|
24902
|
+
"aria-label": t("action.goto"),
|
|
24903
|
+
"data-diff-goto-dialog": true,
|
|
24904
|
+
style: {
|
|
24905
|
+
position: "fixed",
|
|
24906
|
+
inset: 0,
|
|
24907
|
+
zIndex: 40,
|
|
24908
|
+
display: "grid",
|
|
24909
|
+
placeItems: "center",
|
|
24910
|
+
background: "rgba(0, 0, 0, 0.18)"
|
|
24911
|
+
},
|
|
24912
|
+
onClick: () => {
|
|
24913
|
+
setGotoOpen(false);
|
|
24914
|
+
},
|
|
24915
|
+
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
24916
|
+
className: PendingPanel_module_css_default.gotoBox,
|
|
24917
|
+
style: {
|
|
24918
|
+
display: "flex",
|
|
24919
|
+
gap: 8,
|
|
24920
|
+
alignItems: "center",
|
|
24921
|
+
padding: 12,
|
|
24922
|
+
borderRadius: 12,
|
|
24923
|
+
background: "var(--dsw-alias-bg-base)",
|
|
24924
|
+
boxShadow: "var(--dsw-shadow-lv2)"
|
|
24925
|
+
},
|
|
24926
|
+
onClick: (event) => {
|
|
24927
|
+
event.stopPropagation();
|
|
24928
|
+
},
|
|
24929
|
+
children: [
|
|
24930
|
+
(0, react_jsx_runtime.jsx)("input", {
|
|
24931
|
+
className: PendingPanel_module_css_default.gotoInput,
|
|
24932
|
+
"data-diff-goto-input": true,
|
|
24933
|
+
value: gotoDraft,
|
|
24934
|
+
autoFocus: true,
|
|
24935
|
+
inputMode: "numeric",
|
|
24936
|
+
spellCheck: false,
|
|
24937
|
+
autoComplete: "off",
|
|
24938
|
+
"aria-label": t("action.goto"),
|
|
24939
|
+
placeholder: t("action.goto"),
|
|
24940
|
+
style: {
|
|
24941
|
+
width: "8em",
|
|
24942
|
+
padding: "4px 8px",
|
|
24943
|
+
borderRadius: 8,
|
|
24944
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
24945
|
+
background: "transparent",
|
|
24946
|
+
color: "inherit",
|
|
24947
|
+
font: "inherit"
|
|
24948
|
+
},
|
|
24949
|
+
onChange: (event) => {
|
|
24950
|
+
setGotoDraft(event.target.value);
|
|
24951
|
+
},
|
|
24952
|
+
onKeyDown: (event) => {
|
|
24953
|
+
if (event.key === "Escape") {
|
|
24954
|
+
event.preventDefault();
|
|
24955
|
+
setGotoOpen(false);
|
|
24956
|
+
return;
|
|
24957
|
+
}
|
|
24958
|
+
if (event.key !== "Enter") return;
|
|
24959
|
+
event.preventDefault();
|
|
24960
|
+
const line = Number.parseInt(gotoDraft.trim(), 10);
|
|
24961
|
+
setGotoOpen(false);
|
|
24962
|
+
if (Number.isFinite(line) && line > 0) gotoLine(line);
|
|
24963
|
+
}
|
|
24964
|
+
}),
|
|
24965
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
24966
|
+
type: "button",
|
|
24967
|
+
className: PendingPanel_module_css_default.action,
|
|
24968
|
+
"data-diff-goto-go": true,
|
|
24969
|
+
onClick: () => {
|
|
24970
|
+
const line = Number.parseInt(gotoDraft.trim(), 10);
|
|
24971
|
+
setGotoOpen(false);
|
|
24972
|
+
if (Number.isFinite(line) && line > 0) gotoLine(line);
|
|
24973
|
+
},
|
|
24974
|
+
children: t("action.gotoGo")
|
|
24975
|
+
}),
|
|
24976
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
24977
|
+
type: "button",
|
|
24978
|
+
className: PendingPanel_module_css_default.action,
|
|
24979
|
+
"data-diff-goto-cancel": true,
|
|
24980
|
+
onClick: () => {
|
|
24981
|
+
setGotoOpen(false);
|
|
24982
|
+
},
|
|
24983
|
+
children: t("action.gotoCancel")
|
|
24984
|
+
})
|
|
24985
|
+
]
|
|
24986
|
+
})
|
|
24987
|
+
}),
|
|
23854
24988
|
(0, react_jsx_runtime.jsx)("span", { className: PendingPanel_module_css_default.divider }),
|
|
23855
24989
|
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
23856
24990
|
label: t(splitView ? "action.viewUnified" : "action.viewSplit"),
|
|
@@ -24101,7 +25235,20 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
24101
25235
|
onBlockKeep,
|
|
24102
25236
|
onBlockRevert,
|
|
24103
25237
|
onWrapToast: (text) => onToast(text),
|
|
24104
|
-
onVisibleLines: onSplitVisibleLines
|
|
25238
|
+
onVisibleLines: onSplitVisibleLines,
|
|
25239
|
+
discussions: laidDiscussions,
|
|
25240
|
+
renderDiscussion,
|
|
25241
|
+
selectionComment: splitView && selectionCommentOffered ? (0, react_jsx_runtime.jsxs)("button", {
|
|
25242
|
+
type: "button",
|
|
25243
|
+
className: PendingPanel_module_css_default.action,
|
|
25244
|
+
"data-diff-selection-comment": true,
|
|
25245
|
+
onClick: addDiscussion,
|
|
25246
|
+
children: [t("action.comment"), commentChord !== "" && (0, react_jsx_runtime.jsx)("span", {
|
|
25247
|
+
className: PendingPanel_module_css_default.actionChord,
|
|
25248
|
+
"data-diff-selection-comment-chord": true,
|
|
25249
|
+
children: commentChord
|
|
25250
|
+
})]
|
|
25251
|
+
}) : void 0
|
|
24105
25252
|
}) : (0, react_jsx_runtime.jsxs)("div", {
|
|
24106
25253
|
className: PendingPanel_module_css_default.diffBodyWrap,
|
|
24107
25254
|
ref: bodyWrapRef,
|
|
@@ -24166,153 +25313,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
24166
25313
|
children: (0, react_jsx_runtime.jsx)("div", {
|
|
24167
25314
|
className: PendingPanel_module_css_default.discussionPin,
|
|
24168
25315
|
style: { marginLeft: -88 },
|
|
24169
|
-
children: (
|
|
24170
|
-
className: PendingPanel_module_css_default.discussion,
|
|
24171
|
-
"data-diff-discussion": true,
|
|
24172
|
-
"data-lost": discussion.lost === true ? "" : void 0,
|
|
24173
|
-
style: {
|
|
24174
|
-
width: Math.max(0, bodyWidth),
|
|
24175
|
-
height: rows * THREAD_ROW_PX
|
|
24176
|
-
},
|
|
24177
|
-
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
24178
|
-
className: PendingPanel_module_css_default.discussionHead,
|
|
24179
|
-
children: [
|
|
24180
|
-
(0, react_jsx_runtime.jsx)("button", {
|
|
24181
|
-
type: "button",
|
|
24182
|
-
className: PendingPanel_module_css_default.discussionToggle,
|
|
24183
|
-
"data-diff-discussion-toggle": true,
|
|
24184
|
-
"aria-expanded": !discussion.collapsed,
|
|
24185
|
-
"aria-label": t(discussion.collapsed ? "action.discussionExpand" : "action.discussionCollapse"),
|
|
24186
|
-
onClick: () => {
|
|
24187
|
-
toggleDiscussion(discussion.id);
|
|
24188
|
-
},
|
|
24189
|
-
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 })
|
|
24190
|
-
}),
|
|
24191
|
-
(0, react_jsx_runtime.jsx)("span", {
|
|
24192
|
-
className: PendingPanel_module_css_default.discussionRangeWrap,
|
|
24193
|
-
children: (0, react_jsx_runtime.jsx)("span", {
|
|
24194
|
-
className: PendingPanel_module_css_default.discussionRange,
|
|
24195
|
-
"data-diff-discussion-range": true,
|
|
24196
|
-
children: discussionLineRange(discussion.anchor)
|
|
24197
|
-
})
|
|
24198
|
-
}),
|
|
24199
|
-
(0, react_jsx_runtime.jsx)("span", { className: PendingPanel_module_css_default.flexSpacer }),
|
|
24200
|
-
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
24201
|
-
open: discussionMenuFor === discussion.id,
|
|
24202
|
-
portal: true,
|
|
24203
|
-
compact: true,
|
|
24204
|
-
align: "end",
|
|
24205
|
-
items: discussionMenuItems,
|
|
24206
|
-
onSelect: (id) => {
|
|
24207
|
-
if (id === "delete") removeDiscussion(discussion.id);
|
|
24208
|
-
setDiscussionMenuFor(void 0);
|
|
24209
|
-
},
|
|
24210
|
-
onClose: () => {
|
|
24211
|
-
setDiscussionMenuFor(void 0);
|
|
24212
|
-
},
|
|
24213
|
-
anchor: (0, react_jsx_runtime.jsx)("button", {
|
|
24214
|
-
type: "button",
|
|
24215
|
-
className: PendingPanel_module_css_default.discussionToggle,
|
|
24216
|
-
"data-diff-discussion-menu": true,
|
|
24217
|
-
"aria-label": t("action.more"),
|
|
24218
|
-
onClick: () => {
|
|
24219
|
-
setDiscussionMenuFor((current) => current === discussion.id ? void 0 : discussion.id);
|
|
24220
|
-
},
|
|
24221
|
-
children: "⋯"
|
|
24222
|
-
})
|
|
24223
|
-
})
|
|
24224
|
-
]
|
|
24225
|
-
}), !discussion.collapsed && (0, react_jsx_runtime.jsxs)("div", {
|
|
24226
|
-
className: PendingPanel_module_css_default.discussionBody,
|
|
24227
|
-
children: [
|
|
24228
|
-
discussion.lost === true && discussion.quote !== void 0 && discussion.quote !== "" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("p", {
|
|
24229
|
-
className: PendingPanel_module_css_default.discussionNote,
|
|
24230
|
-
"data-diff-discussion-quote-label": true,
|
|
24231
|
-
children: t("discussion.outdatedQuote")
|
|
24232
|
-
}), (0, react_jsx_runtime.jsx)(DiscussionQuote, {
|
|
24233
|
-
quote: discussion.quote,
|
|
24234
|
-
lines: discussion.quoteLines,
|
|
24235
|
-
lang,
|
|
24236
|
-
wrap: langWrap
|
|
24237
|
-
})] }),
|
|
24238
|
-
discussion.hidden !== void 0 && discussion.hidden > 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
24239
|
-
className: PendingPanel_module_css_default.discussionNote,
|
|
24240
|
-
"data-diff-discussion-hidden": true,
|
|
24241
|
-
children: t("discussion.hidden", { count: discussion.hidden })
|
|
24242
|
-
}),
|
|
24243
|
-
discussion.stopped === true && (discussion.reply === void 0 || discussion.reply === "") && discussion.failed !== true && (0, react_jsx_runtime.jsx)("p", {
|
|
24244
|
-
className: PendingPanel_module_css_default.discussionNote,
|
|
24245
|
-
"data-diff-discussion-stopped": true,
|
|
24246
|
-
children: t("discussion.stopped")
|
|
24247
|
-
}),
|
|
24248
|
-
discussion.messages.map((message, index) => message.role === "user" ? (0, react_jsx_runtime.jsx)("p", {
|
|
24249
|
-
className: PendingPanel_module_css_default.discussionUser,
|
|
24250
|
-
"data-diff-discussion-user": true,
|
|
24251
|
-
children: discussionNodes(message.text)
|
|
24252
|
-
}, `u${index}`) : (0, react_jsx_runtime.jsx)("p", {
|
|
24253
|
-
className: PendingPanel_module_css_default.discussionAnswer,
|
|
24254
|
-
"data-diff-discussion-reply": true,
|
|
24255
|
-
children: discussionNodes(message.text)
|
|
24256
|
-
}, `a${index}`)),
|
|
24257
|
-
discussion.reply !== void 0 && discussion.reply !== "" ? (0, react_jsx_runtime.jsx)("p", {
|
|
24258
|
-
className: PendingPanel_module_css_default.discussionAnswer,
|
|
24259
|
-
"data-diff-discussion-reply": true,
|
|
24260
|
-
children: discussionNodes(discussion.reply)
|
|
24261
|
-
}) : discussion.failed === true ? (0, react_jsx_runtime.jsx)("p", {
|
|
24262
|
-
className: PendingPanel_module_css_default.discussionNote,
|
|
24263
|
-
"data-diff-discussion-failed": true,
|
|
24264
|
-
children: t("discussion.failed")
|
|
24265
|
-
}) : discussion.asking === true ? (0, react_jsx_runtime.jsxs)("p", {
|
|
24266
|
-
className: PendingPanel_module_css_default.discussionNote,
|
|
24267
|
-
"data-diff-discussion-asking": true,
|
|
24268
|
-
children: [discussion.queued === true ? t("discussion.queued") : t("discussion.thinking"), (0, react_jsx_runtime.jsxs)("span", {
|
|
24269
|
-
className: PendingPanel_module_css_default.discussionDots,
|
|
24270
|
-
"data-diff-discussion-dots": true,
|
|
24271
|
-
"aria-hidden": "true",
|
|
24272
|
-
children: [
|
|
24273
|
-
(0, react_jsx_runtime.jsx)("span", { children: "." }),
|
|
24274
|
-
(0, react_jsx_runtime.jsx)("span", { children: "." }),
|
|
24275
|
-
(0, react_jsx_runtime.jsx)("span", { children: "." })
|
|
24276
|
-
]
|
|
24277
|
-
})]
|
|
24278
|
-
}) : (0, react_jsx_runtime.jsxs)("div", {
|
|
24279
|
-
className: PendingPanel_module_css_default.discussionCompose,
|
|
24280
|
-
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
24281
|
-
className: PendingPanel_module_css_default.discussionInput,
|
|
24282
|
-
"data-diff-discussion-input": true,
|
|
24283
|
-
ref: (element) => {
|
|
24284
|
-
if (element === null) discussionInputEls.current.delete(discussion.id);
|
|
24285
|
-
else discussionInputEls.current.set(discussion.id, element);
|
|
24286
|
-
},
|
|
24287
|
-
value: discussion.draft,
|
|
24288
|
-
placeholder: t("discussion.placeholder"),
|
|
24289
|
-
onChange: (event) => {
|
|
24290
|
-
const value = event.target.value;
|
|
24291
|
-
setDiscussions((current) => current.map((entry) => entry.id === discussion.id ? {
|
|
24292
|
-
...entry,
|
|
24293
|
-
draft: value
|
|
24294
|
-
} : entry));
|
|
24295
|
-
},
|
|
24296
|
-
onKeyDown: (event) => {
|
|
24297
|
-
if (event.key !== "Enter") return;
|
|
24298
|
-
if (event.nativeEvent.isComposing || event.keyCode === 229) return;
|
|
24299
|
-
event.preventDefault();
|
|
24300
|
-
sendDiscussion(discussion.id);
|
|
24301
|
-
}
|
|
24302
|
-
}), (0, react_jsx_runtime.jsxs)("button", {
|
|
24303
|
-
type: "button",
|
|
24304
|
-
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionPrimary} ${PendingPanel_module_css_default.discussionSend}`,
|
|
24305
|
-
"data-diff-discussion-send": true,
|
|
24306
|
-
disabled: askingId !== void 0,
|
|
24307
|
-
onClick: () => {
|
|
24308
|
-
sendDiscussion(discussion.id);
|
|
24309
|
-
},
|
|
24310
|
-
children: [t("action.comment"), (0, react_jsx_runtime.jsx)(ReturnIcon, {})]
|
|
24311
|
-
})]
|
|
24312
|
-
})
|
|
24313
|
-
]
|
|
24314
|
-
})]
|
|
24315
|
-
}, discussion.id)
|
|
25316
|
+
children: renderDiscussion(discussion, bodyWidth, false)
|
|
24316
25317
|
})
|
|
24317
25318
|
})
|
|
24318
25319
|
]
|
|
@@ -24605,14 +25606,17 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
24605
25606
|
*/
|
|
24606
25607
|
const [landing, setLanding] = (0, react.useState)(void 0);
|
|
24607
25608
|
/** Ask the diff to land on one file: its first change unless `top` says where, or the row a jump
|
|
24608
|
-
* to a comment names (which lands the way a change-block jump does, see `landingRow`).
|
|
25609
|
+
* to a comment names (which lands the way a change-block jump does, see `landingRow`). `card` lands
|
|
25610
|
+
* the thread's own box instead of the rows it named, which is what an outdated comment needs: the
|
|
25611
|
+
* code it was written about is gone, so the position its numbers point at says nothing.
|
|
24609
25612
|
* The nonce makes the request an event rather than a value, so re-clicking the
|
|
24610
25613
|
* chip for the file already open lands on its first change again. */
|
|
24611
|
-
const landOn = (fileId, top, row) => {
|
|
25614
|
+
const landOn = (fileId, top, row, card) => {
|
|
24612
25615
|
setLanding((prev) => ({
|
|
24613
25616
|
fileId,
|
|
24614
25617
|
top,
|
|
24615
25618
|
row,
|
|
25619
|
+
card,
|
|
24616
25620
|
n: (prev?.n ?? 0) + 1
|
|
24617
25621
|
}));
|
|
24618
25622
|
};
|
|
@@ -24724,8 +25728,21 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
24724
25728
|
* choice rides the same block RPC as its `removeWhenResolved` flag. */
|
|
24725
25729
|
const [blockPrompt, setBlockPrompt] = (0, react.useState)(null);
|
|
24726
25730
|
const [filePrompt, setFilePrompt] = (0, react.useState)(null);
|
|
25731
|
+
/** The confirm dialog's own checkbox: stop asking about this file for the rest of the page. */
|
|
25732
|
+
const [quietRemoval, setQuietRemoval] = (0, react.useState)(false);
|
|
25733
|
+
/**
|
|
25734
|
+
* Record the confirm dialog's checkbox, if it was ticked, and put it back for the next dialog.
|
|
25735
|
+
* The tick is about the questions still to come, not about the answer just given: the button the
|
|
25736
|
+
* reader presses is the answer, and it runs either way.
|
|
25737
|
+
*/
|
|
25738
|
+
const settleRemovalAsk = (id) => {
|
|
25739
|
+
if (quietRemoval) quietenRemovalAsk(current, id);
|
|
25740
|
+
setQuietRemoval(false);
|
|
25741
|
+
};
|
|
24727
25742
|
/** The file list row whose action menu is open, and where the right-click landed. */
|
|
24728
25743
|
const [rowMenu, setRowMenu] = (0, react.useState)(null);
|
|
25744
|
+
/** The comments-tab item whose menu is open, if any: which thread, and where the press landed. */
|
|
25745
|
+
const [commentMenu, setCommentMenu] = (0, react.useState)(null);
|
|
24729
25746
|
/** Whether the add-path dialog is open. One dialog covers both shapes: what
|
|
24730
25747
|
* the browser settles on decides whether a file or a directory is added. */
|
|
24731
25748
|
const [addOpen, setAddOpen] = (0, react.useState)(false);
|
|
@@ -24746,8 +25763,9 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
24746
25763
|
/** The chord's on-screen echo: the edge just flipped, and a nonce so a repeat
|
|
24747
25764
|
* restarts the notice instead of re-rendering the same one. */
|
|
24748
25765
|
const [coverNotice, setCoverNotice] = (0, react.useState)(null);
|
|
24749
|
-
/** File-list pane width, adjustable by dragging the divider.
|
|
24750
|
-
|
|
25766
|
+
/** File-list pane width, adjustable by dragging the divider. It opens AT the floor, which is the
|
|
25767
|
+
* width the bulk footer needs for its three labels, so a fresh pane cannot wrap them either. */
|
|
25768
|
+
const [listWidth, setListWidth] = (0, react.useState)(260);
|
|
24751
25769
|
/** Whether the floating (collapsed) file list is currently shown. */
|
|
24752
25770
|
const [floatOpen, setFloatOpen] = (0, react.useState)(false);
|
|
24753
25771
|
/** Whether the file list is always folded, whatever the width allows. */
|
|
@@ -25004,6 +26022,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25004
26022
|
const blockKeepWithPrompt = (sessionId, id, block, removeWhenResolved) => {
|
|
25005
26023
|
const file = files.find((entry) => entry.id === id);
|
|
25006
26024
|
if (removeWhenResolved === void 0 && file !== void 0 && blockResolvesWholeFile(file, block)) {
|
|
26025
|
+
if (removalAskQuiet(current, id)) return onBlockKeep(sessionId, id, block, false);
|
|
25007
26026
|
setBlockPrompt({
|
|
25008
26027
|
action: "keep",
|
|
25009
26028
|
sessionId,
|
|
@@ -25017,6 +26036,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25017
26036
|
const blockRevertWithPrompt = (sessionId, id, block, removeWhenResolved) => {
|
|
25018
26037
|
const file = files.find((entry) => entry.id === id);
|
|
25019
26038
|
if (removeWhenResolved === void 0 && file !== void 0 && blockResolvesWholeFile(file, block)) {
|
|
26039
|
+
if (removalAskQuiet(current, id)) return onBlockRevert(sessionId, id, block, false);
|
|
25020
26040
|
setBlockPrompt({
|
|
25021
26041
|
action: "revert",
|
|
25022
26042
|
sessionId,
|
|
@@ -25029,6 +26049,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25029
26049
|
};
|
|
25030
26050
|
const keepWithPrompt = (sessionId, id, keepListed) => {
|
|
25031
26051
|
if (keepListed === void 0 && confirmFileRemoveEnabled()) {
|
|
26052
|
+
if (removalAskQuiet(current, id)) return onKeep(sessionId, id, true);
|
|
25032
26053
|
setFilePrompt({
|
|
25033
26054
|
action: "keep",
|
|
25034
26055
|
sessionId,
|
|
@@ -25040,6 +26061,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25040
26061
|
};
|
|
25041
26062
|
const revertWithPrompt = (sessionId, id, keepListed) => {
|
|
25042
26063
|
if (keepListed === void 0 && confirmFileRemoveEnabled()) {
|
|
26064
|
+
if (removalAskQuiet(current, id)) return onRevert(sessionId, id, true);
|
|
25043
26065
|
setFilePrompt({
|
|
25044
26066
|
action: "revert",
|
|
25045
26067
|
sessionId,
|
|
@@ -25403,6 +26425,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25403
26425
|
id: discussion.id,
|
|
25404
26426
|
fileId: file.id,
|
|
25405
26427
|
row: discussion.anchor.start,
|
|
26428
|
+
end: discussion.anchor.end,
|
|
25406
26429
|
label: referenceLabelOf(file.path, snapshot.workspacePath, discussion.anchor.startLine, discussion.anchor.endLine),
|
|
25407
26430
|
title: commentTitle(discussion) || t("panel.commentEmptyTitle"),
|
|
25408
26431
|
lost: discussion.lost === true
|
|
@@ -25414,10 +26437,31 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25414
26437
|
commentsTick,
|
|
25415
26438
|
t
|
|
25416
26439
|
]);
|
|
25417
|
-
/** Open the file a comment hangs in and land on the comment
|
|
25418
|
-
|
|
26440
|
+
/** Open the file a comment hangs in and land on the comment: the rows it names, or — for an outdated
|
|
26441
|
+
* thread, whose code is gone — its own box, which is the only place that says anything. */
|
|
26442
|
+
const jumpToComment = (fileId, row, card = false) => {
|
|
25419
26443
|
if (fileId !== selected) setSelected(fileId);
|
|
25420
|
-
landOn(fileId, void 0, row);
|
|
26444
|
+
landOn(fileId, void 0, row, card);
|
|
26445
|
+
};
|
|
26446
|
+
/**
|
|
26447
|
+
* The comment menu's rows: the one action a thread has, named exactly as the block's own
|
|
26448
|
+
* overflow menu names it — ending a comment is one thing, and the pane it is asked from must
|
|
26449
|
+
* not look like it does something else.
|
|
26450
|
+
*/
|
|
26451
|
+
const commentMenuItems = (0, react.useMemo)(() => [{
|
|
26452
|
+
id: "close",
|
|
26453
|
+
label: t("action.discussionEnd")
|
|
26454
|
+
}], [t]);
|
|
26455
|
+
/**
|
|
26456
|
+
* End one comment from the list. The threads belong to the file detail, so the list does not
|
|
26457
|
+
* reach into its state: it forgets the thread in the page's memory, and the detail picks that
|
|
26458
|
+
* up (see `forgetDiscussion`), which is also what takes the block out of the open file.
|
|
26459
|
+
*/
|
|
26460
|
+
const runCommentMenu = (id) => {
|
|
26461
|
+
const target = commentMenu;
|
|
26462
|
+
setCommentMenu(null);
|
|
26463
|
+
if (target === null || id !== "close") return;
|
|
26464
|
+
forgetDiscussion(current, target.fileId, target.id);
|
|
25421
26465
|
};
|
|
25422
26466
|
/**
|
|
25423
26467
|
* The folded card's own box, derived from the measured one, or undefined while
|
|
@@ -25452,7 +26496,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25452
26496
|
setListTab("pending");
|
|
25453
26497
|
},
|
|
25454
26498
|
children: t("panel.tab.pending")
|
|
25455
|
-
}), (0, react_jsx_runtime.
|
|
26499
|
+
}), (0, react_jsx_runtime.jsxs)("button", {
|
|
25456
26500
|
type: "button",
|
|
25457
26501
|
role: "tab",
|
|
25458
26502
|
className: PendingPanel_module_css_default.listTab,
|
|
@@ -25461,7 +26505,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25461
26505
|
onClick: () => {
|
|
25462
26506
|
setListTab("comments");
|
|
25463
26507
|
},
|
|
25464
|
-
children: t("panel.tab.comments")
|
|
26508
|
+
children: [(0, react_jsx_runtime.jsx)("span", { children: t("panel.tab.comments") }), commentEntries.length > 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
26509
|
+
className: PendingPanel_module_css_default.tabCount,
|
|
26510
|
+
"data-diff-list-count": true,
|
|
26511
|
+
children: commentEntries.length
|
|
26512
|
+
})]
|
|
25465
26513
|
})]
|
|
25466
26514
|
}) : (0, react_jsx_runtime.jsx)("h3", {
|
|
25467
26515
|
className: PendingPanel_module_css_default.listTitle,
|
|
@@ -25504,12 +26552,21 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25504
26552
|
"data-diff-comment-link": entry.id,
|
|
25505
26553
|
"data-mobile-nav-copy": "1",
|
|
25506
26554
|
onClick: () => {
|
|
25507
|
-
jumpToComment(entry.fileId, entry.row);
|
|
26555
|
+
jumpToComment(entry.fileId, entry.lost ? entry.end : entry.row, entry.lost);
|
|
26556
|
+
},
|
|
26557
|
+
onContextMenu: (event) => {
|
|
26558
|
+
event.preventDefault();
|
|
26559
|
+
setCommentMenu({
|
|
26560
|
+
id: entry.id,
|
|
26561
|
+
fileId: entry.fileId,
|
|
26562
|
+
x: event.clientX,
|
|
26563
|
+
y: event.clientY
|
|
26564
|
+
});
|
|
25508
26565
|
},
|
|
25509
26566
|
onKeyDown: (event) => {
|
|
25510
26567
|
if (event.key !== "Enter" && event.key !== " ") return;
|
|
25511
26568
|
event.preventDefault();
|
|
25512
|
-
jumpToComment(entry.fileId, entry.row);
|
|
26569
|
+
jumpToComment(entry.fileId, entry.lost ? entry.end : entry.row, entry.lost);
|
|
25513
26570
|
},
|
|
25514
26571
|
children: [(0, react_jsx_runtime.jsxs)("span", {
|
|
25515
26572
|
className: PendingPanel_module_css_default.commentHead,
|
|
@@ -25741,7 +26798,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25741
26798
|
event.preventDefault();
|
|
25742
26799
|
const startX = event.clientX;
|
|
25743
26800
|
const startWidth = listWidth;
|
|
25744
|
-
const cap = floatMode && floatBox !== null ? Math.max(
|
|
26801
|
+
const cap = floatMode && floatBox !== null ? Math.max(260, floatBox.width - 24) : MAX_LIST_WIDTH_PX;
|
|
25745
26802
|
try {
|
|
25746
26803
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
25747
26804
|
} catch {}
|
|
@@ -25750,7 +26807,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25750
26807
|
let latest = startWidth;
|
|
25751
26808
|
let pending = 0;
|
|
25752
26809
|
const onMove = (move) => {
|
|
25753
|
-
latest = Math.min(Math.max(startWidth + (move.clientX - startX),
|
|
26810
|
+
latest = Math.min(Math.max(startWidth + (move.clientX - startX), 260), cap);
|
|
25754
26811
|
if (pending !== 0) return;
|
|
25755
26812
|
pending = requestAnimationFrame(() => {
|
|
25756
26813
|
pending = 0;
|
|
@@ -25775,19 +26832,25 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25775
26832
|
};
|
|
25776
26833
|
/**
|
|
25777
26834
|
* End the text selection when the press lands on the panel's chrome — blank space, a label, the
|
|
25778
|
-
* toolbar, the file list.
|
|
26835
|
+
* toolbar, the file list — or on a row the selection already covers (see `pressOnSelectedRow`).
|
|
25779
26836
|
*
|
|
25780
26837
|
* The chrome is `user-select: none` (see `.panel`), and a press on such an area is one the
|
|
25781
26838
|
* browser does NOT clear the selection for: the highlight stayed up, and so did the selection
|
|
25782
|
-
* frame that goes with it, over a gesture that plainly ended.
|
|
25783
|
-
*
|
|
25784
|
-
*
|
|
26839
|
+
* frame that goes with it, over a gesture that plainly ended. The same is true inside the code
|
|
26840
|
+
* view when the press lands on the selection's own row, which is the one content press the panel
|
|
26841
|
+
* ends itself. What IS content is otherwise left to the browser — which is also what keeps a drag
|
|
26842
|
+
* started on chrome able to select the code it runs into, since dropping the ranges first costs
|
|
26843
|
+
* the drag nothing.
|
|
25785
26844
|
*/
|
|
25786
26845
|
const onPanelMouseDown = (event) => {
|
|
25787
26846
|
const target = event.target;
|
|
25788
26847
|
if (!(target instanceof Element)) return;
|
|
25789
|
-
if (target.closest(KEEPS_SELECTION) !== null) return;
|
|
25790
26848
|
const live = window.getSelection();
|
|
26849
|
+
if (target.closest("[data-diff-selection-actions], [data-diff-copy]") === null && pressOnSelectedRow(target, live)) {
|
|
26850
|
+
if (typeof live?.removeAllRanges === "function") live.removeAllRanges();
|
|
26851
|
+
return;
|
|
26852
|
+
}
|
|
26853
|
+
if (target.closest(KEEPS_SELECTION) !== null) return;
|
|
25791
26854
|
if (typeof live?.removeAllRanges === "function") live.removeAllRanges();
|
|
25792
26855
|
};
|
|
25793
26856
|
const content = (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
@@ -25976,6 +27039,10 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
25976
27039
|
landingTop: landing !== void 0 && landing.fileId === selectedFile.id ? landing.top : void 0,
|
|
25977
27040
|
landingTick: landing !== void 0 && landing.fileId === selectedFile.id ? landing.n : 0,
|
|
25978
27041
|
landingRow: landing !== void 0 && landing.fileId === selectedFile.id ? landing.row : void 0,
|
|
27042
|
+
landingCard: landing !== void 0 && landing.fileId === selectedFile.id ? landing.card : void 0,
|
|
27043
|
+
onLanded: () => {
|
|
27044
|
+
setLanding((current) => current === void 0 ? current : void 0);
|
|
27045
|
+
},
|
|
25979
27046
|
failedMessage: failed.get(selectedFile.id),
|
|
25980
27047
|
commentSkill: snapshot.commentSkill,
|
|
25981
27048
|
onPasteReference,
|
|
@@ -26025,33 +27092,50 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
26025
27092
|
className: PendingPanel_module_css_default.confirmCard,
|
|
26026
27093
|
role: "dialog",
|
|
26027
27094
|
"aria-modal": "true",
|
|
26028
|
-
children: [
|
|
26029
|
-
|
|
26030
|
-
|
|
26031
|
-
|
|
26032
|
-
|
|
26033
|
-
|
|
26034
|
-
|
|
26035
|
-
|
|
26036
|
-
"
|
|
26037
|
-
|
|
26038
|
-
|
|
26039
|
-
|
|
26040
|
-
|
|
26041
|
-
|
|
26042
|
-
|
|
26043
|
-
|
|
26044
|
-
|
|
26045
|
-
|
|
26046
|
-
|
|
26047
|
-
|
|
26048
|
-
|
|
26049
|
-
|
|
26050
|
-
|
|
26051
|
-
|
|
26052
|
-
|
|
26053
|
-
|
|
26054
|
-
|
|
27095
|
+
children: [
|
|
27096
|
+
(0, react_jsx_runtime.jsx)("p", {
|
|
27097
|
+
className: PendingPanel_module_css_default.confirmText,
|
|
27098
|
+
children: t("panel.resolvedAsk", { file: basenameOf(promptFile.path) })
|
|
27099
|
+
}),
|
|
27100
|
+
(0, react_jsx_runtime.jsxs)("label", {
|
|
27101
|
+
className: PendingPanel_module_css_default.pickerCheck,
|
|
27102
|
+
title: t("panel.removalQuietHint"),
|
|
27103
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
27104
|
+
type: "checkbox",
|
|
27105
|
+
"data-diff-confirm-quiet": true,
|
|
27106
|
+
checked: quietRemoval,
|
|
27107
|
+
onChange: (event) => {
|
|
27108
|
+
setQuietRemoval(event.target.checked);
|
|
27109
|
+
}
|
|
27110
|
+
}), t("panel.removalQuiet")]
|
|
27111
|
+
}),
|
|
27112
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
27113
|
+
className: PendingPanel_module_css_default.confirmActions,
|
|
27114
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
27115
|
+
type: "button",
|
|
27116
|
+
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionPrimary}`,
|
|
27117
|
+
"data-diff-confirm-remove": true,
|
|
27118
|
+
onClick: () => {
|
|
27119
|
+
setBlockPrompt(null);
|
|
27120
|
+
const { action, sessionId, id, block } = blockPrompt;
|
|
27121
|
+
settleRemovalAsk(id);
|
|
27122
|
+
action === "keep" ? onBlockKeep(sessionId, id, block, true) : onBlockRevert(sessionId, id, block, true);
|
|
27123
|
+
},
|
|
27124
|
+
children: t("row.dismiss")
|
|
27125
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
27126
|
+
type: "button",
|
|
27127
|
+
className: PendingPanel_module_css_default.action,
|
|
27128
|
+
"data-diff-confirm-keep": true,
|
|
27129
|
+
onClick: () => {
|
|
27130
|
+
setBlockPrompt(null);
|
|
27131
|
+
const { action, sessionId, id, block } = blockPrompt;
|
|
27132
|
+
settleRemovalAsk(id);
|
|
27133
|
+
action === "keep" ? onBlockKeep(sessionId, id, block, false) : onBlockRevert(sessionId, id, block, false);
|
|
27134
|
+
},
|
|
27135
|
+
children: t("panel.keepInList")
|
|
27136
|
+
})]
|
|
27137
|
+
})
|
|
27138
|
+
]
|
|
26055
27139
|
})
|
|
26056
27140
|
}),
|
|
26057
27141
|
filePrompt !== null && promptEntry !== void 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -26061,33 +27145,50 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
26061
27145
|
className: PendingPanel_module_css_default.confirmCard,
|
|
26062
27146
|
role: "dialog",
|
|
26063
27147
|
"aria-modal": "true",
|
|
26064
|
-
children: [
|
|
26065
|
-
|
|
26066
|
-
|
|
26067
|
-
|
|
26068
|
-
|
|
26069
|
-
|
|
26070
|
-
|
|
26071
|
-
|
|
26072
|
-
"
|
|
26073
|
-
|
|
26074
|
-
|
|
26075
|
-
|
|
26076
|
-
|
|
26077
|
-
|
|
26078
|
-
|
|
26079
|
-
|
|
26080
|
-
|
|
26081
|
-
|
|
26082
|
-
|
|
26083
|
-
|
|
26084
|
-
|
|
26085
|
-
|
|
26086
|
-
|
|
26087
|
-
|
|
26088
|
-
|
|
26089
|
-
|
|
26090
|
-
|
|
27148
|
+
children: [
|
|
27149
|
+
(0, react_jsx_runtime.jsx)("p", {
|
|
27150
|
+
className: PendingPanel_module_css_default.confirmText,
|
|
27151
|
+
children: t(filePrompt.action === "keep" ? "panel.fileKeptAsk" : "panel.fileRevertedAsk", { file: basenameOf(promptEntry.path) })
|
|
27152
|
+
}),
|
|
27153
|
+
(0, react_jsx_runtime.jsxs)("label", {
|
|
27154
|
+
className: PendingPanel_module_css_default.pickerCheck,
|
|
27155
|
+
title: t("panel.removalQuietHint"),
|
|
27156
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
27157
|
+
type: "checkbox",
|
|
27158
|
+
"data-diff-file-confirm-quiet": true,
|
|
27159
|
+
checked: quietRemoval,
|
|
27160
|
+
onChange: (event) => {
|
|
27161
|
+
setQuietRemoval(event.target.checked);
|
|
27162
|
+
}
|
|
27163
|
+
}), t("panel.removalQuiet")]
|
|
27164
|
+
}),
|
|
27165
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
27166
|
+
className: PendingPanel_module_css_default.confirmActions,
|
|
27167
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
27168
|
+
type: "button",
|
|
27169
|
+
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionPrimary}`,
|
|
27170
|
+
"data-diff-file-confirm-remove": true,
|
|
27171
|
+
onClick: () => {
|
|
27172
|
+
setFilePrompt(null);
|
|
27173
|
+
const { action, sessionId, id } = filePrompt;
|
|
27174
|
+
settleRemovalAsk(id);
|
|
27175
|
+
action === "keep" ? onKeep(sessionId, id, false) : onRevert(sessionId, id, false);
|
|
27176
|
+
},
|
|
27177
|
+
children: t("row.dismiss")
|
|
27178
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
27179
|
+
type: "button",
|
|
27180
|
+
className: PendingPanel_module_css_default.action,
|
|
27181
|
+
"data-diff-file-confirm-keep": true,
|
|
27182
|
+
onClick: () => {
|
|
27183
|
+
setFilePrompt(null);
|
|
27184
|
+
const { action, sessionId, id } = filePrompt;
|
|
27185
|
+
settleRemovalAsk(id);
|
|
27186
|
+
action === "keep" ? onKeep(sessionId, id, true) : onRevert(sessionId, id, true);
|
|
27187
|
+
},
|
|
27188
|
+
children: t("panel.keepInList")
|
|
27189
|
+
})]
|
|
27190
|
+
})
|
|
27191
|
+
]
|
|
26091
27192
|
})
|
|
26092
27193
|
}),
|
|
26093
27194
|
rowMenu !== null && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
@@ -26102,6 +27203,18 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
26102
27203
|
getAnchorRect: () => new DOMRect(rowMenu.x, rowMenu.y, 0, 0),
|
|
26103
27204
|
anchor: (0, react_jsx_runtime.jsx)("span", { className: PendingPanel_module_css_default.rowMenuAnchor })
|
|
26104
27205
|
}),
|
|
27206
|
+
commentMenu !== null && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
27207
|
+
open: true,
|
|
27208
|
+
portal: true,
|
|
27209
|
+
compact: true,
|
|
27210
|
+
items: commentMenuItems,
|
|
27211
|
+
onSelect: runCommentMenu,
|
|
27212
|
+
onClose: () => {
|
|
27213
|
+
setCommentMenu(null);
|
|
27214
|
+
},
|
|
27215
|
+
getAnchorRect: () => new DOMRect(commentMenu.x, commentMenu.y, 0, 0),
|
|
27216
|
+
anchor: (0, react_jsx_runtime.jsx)("span", { className: PendingPanel_module_css_default.rowMenuAnchor })
|
|
27217
|
+
}),
|
|
26105
27218
|
addOpen && current !== void 0 && (0, react_jsx_runtime.jsx)(PathPicker, {
|
|
26106
27219
|
rootPath: snapshot.workspacePath,
|
|
26107
27220
|
onBrowse: (path) => onBrowse(current, path),
|
|
@@ -28215,6 +29328,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
28215
29328
|
"panel.discussionRoundsDesc": "一条评论里保留最近几轮(你问一句、Agent 答一句算一轮),更早的整轮省略。默认 2 轮,范围 1–10。",
|
|
28216
29329
|
"panel.quickSummonDesc": "用键盘快捷键打开/关闭差异面板。点击右侧按钮后按下新的按键组合即可修改。",
|
|
28217
29330
|
"panel.recordShortcut": "按下快捷键…",
|
|
29331
|
+
"panel.key.goto": "转到行",
|
|
29332
|
+
"action.goto": "转到行",
|
|
29333
|
+
"action.gotoGo": "确定",
|
|
29334
|
+
"action.gotoCancel": "取消",
|
|
29335
|
+
"panel.gotoMissing": "第 {line} 行不在当前文件中",
|
|
28218
29336
|
"settings.keybindings": "快捷键",
|
|
28219
29337
|
"settings.keybindingsDesc": "展开后可配置各项操作的按键组合。",
|
|
28220
29338
|
"settings.comment": "评论",
|
|
@@ -28259,6 +29377,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
28259
29377
|
"discussion.promptRuleSkill": "(这是一条代码批注:先加载 {skill} skill,按它的规则回答。)",
|
|
28260
29378
|
"discussion.thinking": "思考中",
|
|
28261
29379
|
"discussion.queued": "排队等待中",
|
|
29380
|
+
"discussion.answering": "答复中",
|
|
28262
29381
|
"discussion.outdatedQuote": "评论代码已过期:",
|
|
28263
29382
|
"discussion.hidden": "更早的 {count} 条已省略",
|
|
28264
29383
|
"discussion.failed": "这次提问失败了,可以再试一次。",
|
|
@@ -28335,6 +29454,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
28335
29454
|
"status.missing": "该改动已不存在",
|
|
28336
29455
|
"panel.resolvedAsk": "「{file}」的所有改动都已处理,是否从列表移除?",
|
|
28337
29456
|
"panel.keepInList": "保留在列表",
|
|
29457
|
+
"panel.removalQuiet": "当前会话内不再询问该文件",
|
|
29458
|
+
"panel.removalQuietHint": "本次浏览器访问内有效:刷新页面后会重新询问。",
|
|
28338
29459
|
"panel.fileKeptAsk": "「{file}」的改动已全部保留,是否从列表移出?",
|
|
28339
29460
|
"panel.fileRevertedAsk": "「{file}」的改动已全部回退,是否从列表移出?",
|
|
28340
29461
|
"panel.confirmFileRemove": "处理整文件后询问是否移出列表",
|
|
@@ -28428,6 +29549,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
28428
29549
|
"panel.discussionRoundsDesc": "How many rounds a comment keeps (one question and the answer to it); older rounds are left out. Default 2, range 1-10.",
|
|
28429
29550
|
"panel.quickSummonDesc": "Open or close the diff panel with a keyboard shortcut. Click the button and press a new chord to change it.",
|
|
28430
29551
|
"panel.recordShortcut": "Press keys…",
|
|
29552
|
+
"panel.key.goto": "Go to line",
|
|
29553
|
+
"action.goto": "Go to line",
|
|
29554
|
+
"action.gotoGo": "Go",
|
|
29555
|
+
"action.gotoCancel": "Cancel",
|
|
29556
|
+
"panel.gotoMissing": "Line {line} is not in the current file",
|
|
28431
29557
|
"settings.keybindings": "Shortcuts",
|
|
28432
29558
|
"settings.keybindingsDesc": "Expand to configure the key combo for each action.",
|
|
28433
29559
|
"settings.comment": "Comments",
|
|
@@ -28472,6 +29598,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
28472
29598
|
"discussion.promptRuleSkill": "(This is a comment on a few diff lines: load the {skill} skill first and answer by its rules.)",
|
|
28473
29599
|
"discussion.thinking": "Thinking",
|
|
28474
29600
|
"discussion.queued": "Queued",
|
|
29601
|
+
"discussion.answering": "Replying",
|
|
28475
29602
|
"discussion.outdatedQuote": "Commented code is outdated:",
|
|
28476
29603
|
"discussion.hidden": "{count} earlier turns omitted",
|
|
28477
29604
|
"discussion.failed": "That question failed; you can try again.",
|
|
@@ -28548,6 +29675,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
28548
29675
|
"status.missing": "This change no longer exists",
|
|
28549
29676
|
"panel.resolvedAsk": "All changes in \"{file}\" are resolved. Remove it from the list?",
|
|
28550
29677
|
"panel.keepInList": "Keep in list",
|
|
29678
|
+
"panel.removalQuiet": "Stop asking about this file in this session",
|
|
29679
|
+
"panel.removalQuietHint": "For this browser visit only — a reload asks again.",
|
|
28551
29680
|
"panel.fileKeptAsk": "All changes in \"{file}\" are kept. Remove it from the list?",
|
|
28552
29681
|
"panel.fileRevertedAsk": "All changes in \"{file}\" are reverted. Remove it from the list?",
|
|
28553
29682
|
"panel.confirmFileRemove": "Ask after a whole-file keep/revert",
|