@plannotator/ui 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -0
- package/assets/diff-options.png +0 -0
- package/assets/icon-codex.png +0 -0
- package/assets/look-flat.png +0 -0
- package/assets/look-grid.png +0 -0
- package/assets/review-sections.png +0 -0
- package/assets/review-tree.png +0 -0
- package/assets/workspaces.webp +0 -0
- package/components/AISettingsTab.tsx +145 -0
- package/components/ActionMenu.tsx +101 -0
- package/components/AgentControls.tsx +216 -0
- package/components/AgentsTab.tsx +1294 -0
- package/components/AnnotationPanel.tsx +731 -0
- package/components/AnnotationSidebar.tsx +86 -0
- package/components/AnnotationToolbar.tsx +323 -0
- package/components/AnnotationToolstrip.tsx +355 -0
- package/components/ApproveDropdown.tsx +170 -0
- package/components/AttachmentsButton.tsx +410 -0
- package/components/BlockRenderer.tsx +163 -0
- package/components/BorderTrail.tsx +38 -0
- package/components/CodeFilePicker.tsx +64 -0
- package/components/CodeFilePopout.tsx +602 -0
- package/components/CodePathValidationContext.tsx +14 -0
- package/components/CommentPopover.tsx +512 -0
- package/components/CompletionOverlay.tsx +99 -0
- package/components/ConfirmDialog.tsx +128 -0
- package/components/DocBadges.tsx +231 -0
- package/components/EditorAnnotationCard.tsx +65 -0
- package/components/ExportModal.tsx +565 -0
- package/components/FloatingQuickLabelPicker.tsx +144 -0
- package/components/GitHubIcon.tsx +16 -0
- package/components/GitLabIcon.tsx +30 -0
- package/components/GraphvizBlock.tsx +511 -0
- package/components/ImageAnnotator/Canvas.tsx +118 -0
- package/components/ImageAnnotator/Toolbar.tsx +218 -0
- package/components/ImageAnnotator/index.tsx +272 -0
- package/components/ImageAnnotator/types.ts +39 -0
- package/components/ImageAnnotator/utils.ts +147 -0
- package/components/ImageThumbnail.tsx +126 -0
- package/components/ImportModal.tsx +146 -0
- package/components/InlineMarkdown.tsx +1094 -0
- package/components/KeyboardShortcuts.tsx +208 -0
- package/components/Landing.tsx +496 -0
- package/components/ListItemBody.tsx +62 -0
- package/components/ListMarker.tsx +73 -0
- package/components/LookAndFeelAnnouncementDialog.tsx +230 -0
- package/components/MarkdownEditor.tsx +44 -0
- package/components/MenuVersionSection.tsx +91 -0
- package/components/MermaidBlock.tsx +579 -0
- package/components/ModeToggle.tsx +68 -0
- package/components/OpenInAppButton.tsx +299 -0
- package/components/OverlayScrollArea.tsx +82 -0
- package/components/PermissionModeSetup.tsx +92 -0
- package/components/PinpointOverlay.tsx +99 -0
- package/components/PlanAIAnnouncementDialog.tsx +187 -0
- package/components/PlanHeaderMenu.tsx +299 -0
- package/components/PopoutDialog.tsx +91 -0
- package/components/Popover.tsx +27 -0
- package/components/ProviderIcons.tsx +51 -0
- package/components/PullRequestIcon.tsx +12 -0
- package/components/QuickLabelDropdown.tsx +63 -0
- package/components/RenderedMarkdown.tsx +54 -0
- package/components/RepoIcon.tsx +12 -0
- package/components/ResizeHandle.tsx +86 -0
- package/components/ReviewAgentsIcon.tsx +18 -0
- package/components/SearchableSelect.tsx +157 -0
- package/components/Settings.tsx +2220 -0
- package/components/SparklesIcon.tsx +45 -0
- package/components/StickyHeaderLane.tsx +260 -0
- package/components/TableOfContents.tsx +157 -0
- package/components/TaterSpritePullup.tsx +34 -0
- package/components/TaterSpriteRunning.tsx +54 -0
- package/components/TaterSpriteSitting.tsx +37 -0
- package/components/TextShimmer.tsx +57 -0
- package/components/ThemeProvider.tsx +162 -0
- package/components/ThemeTab.tsx +139 -0
- package/components/ToolbarButtons.tsx +116 -0
- package/components/Tooltip.tsx +45 -0
- package/components/Viewer.tsx +977 -0
- package/components/ai/AIProviderBar.tsx +95 -0
- package/components/ai/DocumentAIChatPanel.tsx +313 -0
- package/components/blocks/AlertBlock.tsx +58 -0
- package/components/blocks/Callout.tsx +60 -0
- package/components/blocks/CodeBlock.tsx +75 -0
- package/components/blocks/HtmlBlock.tsx +122 -0
- package/components/blocks/MathBlock.tsx +36 -0
- package/components/blocks/TableBlock.tsx +146 -0
- package/components/blocks/TablePopout.tsx +279 -0
- package/components/blocks/TableToolbar.tsx +153 -0
- package/components/blocks/proseBody.tsx +102 -0
- package/components/core/button.tsx +44 -0
- package/components/core/textarea.tsx +26 -0
- package/components/diagramLanguages.ts +14 -0
- package/components/goal-setup/GoalSetupSurface.tsx +1354 -0
- package/components/html-viewer/HtmlViewer.tsx +386 -0
- package/components/html-viewer/bridge-script.ts +505 -0
- package/components/html-viewer/index.ts +1 -0
- package/components/html-viewer/useHtmlAnnotation.ts +400 -0
- package/components/icons/AgentIcons.tsx +66 -0
- package/components/icons/AppIcon.tsx +56 -0
- package/components/icons/MessagesIcon.tsx +11 -0
- package/components/icons/ObsidianIcons.tsx +208 -0
- package/components/icons/app/android-studio.svg +369 -0
- package/components/icons/app/antigravity.svg +97 -0
- package/components/icons/app/cursor.svg +16 -0
- package/components/icons/app/file-explorer.svg +20 -0
- package/components/icons/app/finder.png +0 -0
- package/components/icons/app/ghostty.svg +13 -0
- package/components/icons/app/iterm2.svg +13 -0
- package/components/icons/app/powershell.svg +14 -0
- package/components/icons/app/sublime-text.svg +17 -0
- package/components/icons/app/terminal.png +0 -0
- package/components/icons/app/textmate.png +0 -0
- package/components/icons/app/vscode.svg +39 -0
- package/components/icons/app/warp.png +0 -0
- package/components/icons/app/xcode.png +0 -0
- package/components/icons/app/zed-dark.svg +15 -0
- package/components/icons/app/zed.svg +15 -0
- package/components/icons/themeIcons.tsx +47 -0
- package/components/mermaidSvg.ts +33 -0
- package/components/plan-diff/PlanCleanDiffView.tsx +884 -0
- package/components/plan-diff/PlanDiffBadge.tsx +48 -0
- package/components/plan-diff/PlanDiffModeSwitcher.tsx +103 -0
- package/components/plan-diff/PlanDiffViewer.tsx +214 -0
- package/components/plan-diff/PlanRawDiffView.tsx +102 -0
- package/components/plan-diff/VSCodeIcon.tsx +132 -0
- package/components/settings/HooksTab.tsx +208 -0
- package/components/sidebar/ArchiveBrowser.tsx +98 -0
- package/components/sidebar/CountBadge.tsx +12 -0
- package/components/sidebar/FileBrowser.tsx +498 -0
- package/components/sidebar/MessagesBrowser.tsx +109 -0
- package/components/sidebar/SidebarContainer.tsx +353 -0
- package/components/sidebar/SidebarTabs.tsx +155 -0
- package/components/sidebar/VersionBrowser.tsx +141 -0
- package/components/types.d.ts +7 -0
- package/components/ui/badge.tsx +44 -0
- package/components/ui/button.tsx +83 -0
- package/components/ui/card.tsx +58 -0
- package/components/ui/dialog.tsx +106 -0
- package/components/ui/dropdown-menu.tsx +240 -0
- package/components/ui/state-pill.tsx +45 -0
- package/components/ui/tabs.tsx +46 -0
- package/components/ui/textarea.tsx +25 -0
- package/config/configStore.ts +214 -0
- package/config/index.ts +4 -0
- package/config/reviewView.ts +42 -0
- package/config/settings.ts +310 -0
- package/config/useConfig.ts +20 -0
- package/configure.ts +69 -0
- package/globals.d.ts +14 -0
- package/hooks/pfm/useCodeFilePopout.ts +111 -0
- package/hooks/useAIChat.ts +532 -0
- package/hooks/useAIProviderConfig.ts +115 -0
- package/hooks/useActiveSection.ts +78 -0
- package/hooks/useAgentJobs.ts +306 -0
- package/hooks/useAgentSettings.ts +579 -0
- package/hooks/useAgents.ts +90 -0
- package/hooks/useAnnotationDraft.ts +523 -0
- package/hooks/useAnnotationHighlighter.ts +1170 -0
- package/hooks/useArchive.ts +171 -0
- package/hooks/useAutoClose.ts +104 -0
- package/hooks/useCodeAnnotationDraft.ts +194 -0
- package/hooks/useCodeFilePopout.ts +1 -0
- package/hooks/useDismissOnOutsideAndEscape.ts +50 -0
- package/hooks/useDraggable.ts +108 -0
- package/hooks/useEditorAnnotations.ts +64 -0
- package/hooks/useExternalAnnotationHighlights.ts +105 -0
- package/hooks/useExternalAnnotations.ts +268 -0
- package/hooks/useFileBrowser.ts +402 -0
- package/hooks/useInputMethodSwitch.ts +89 -0
- package/hooks/useIsMobile.ts +17 -0
- package/hooks/useLinkedDoc.ts +494 -0
- package/hooks/useOverlayViewport.ts +36 -0
- package/hooks/usePinpoint.ts +182 -0
- package/hooks/usePlanDiff.ts +176 -0
- package/hooks/usePrintMode.ts +27 -0
- package/hooks/useResizablePanel.ts +173 -0
- package/hooks/useScrollViewport.ts +38 -0
- package/hooks/useSharing.ts +441 -0
- package/hooks/useSidebar.ts +55 -0
- package/hooks/useUpdateCheck.ts +132 -0
- package/hooks/useValidatedCodePaths.ts +94 -0
- package/icons/GitUser.tsx +17 -0
- package/lib/utils.ts +11 -0
- package/package.json +117 -0
- package/plannotator.webp +0 -0
- package/print.css +427 -0
- package/shortcuts/code-review/ai.shortcuts.ts +25 -0
- package/shortcuts/code-review/allFilesDiff.shortcuts.ts +46 -0
- package/shortcuts/code-review/annotationToolbar.shortcuts.ts +30 -0
- package/shortcuts/code-review/fileTree.shortcuts.ts +35 -0
- package/shortcuts/code-review/prComments.shortcuts.ts +18 -0
- package/shortcuts/code-review/suggestionModal.shortcuts.ts +25 -0
- package/shortcuts/code-review/tourDialog.shortcuts.ts +18 -0
- package/shortcuts/core.ts +399 -0
- package/shortcuts/index.ts +21 -0
- package/shortcuts/plan-review/annotationPanel.shortcuts.ts +25 -0
- package/shortcuts/plan-review/annotationToolbar.shortcuts.ts +39 -0
- package/shortcuts/plan-review/commentPopover.shortcuts.ts +21 -0
- package/shortcuts/plan-review/goalSetup.shortcuts.ts +10 -0
- package/shortcuts/plan-review/imageAnnotator.shortcuts.ts +42 -0
- package/shortcuts/plan-review/inputMethod.shortcuts.ts +30 -0
- package/shortcuts/plan-review/sidebar.shortcuts.ts +34 -0
- package/shortcuts/plan-review/viewer.shortcuts.ts +24 -0
- package/shortcuts/runtime.ts +259 -0
- package/sprite_package_additional/index.html +34 -0
- package/sprite_package_additional/sprite.png +0 -0
- package/sprite_package_new/index.html +34 -0
- package/sprite_package_new/sprite.png +0 -0
- package/sprite_package_pulluphang/index.html +34 -0
- package/sprite_package_pulluphang/sprite.png +0 -0
- package/styles.css +1 -0
- package/theme.css +893 -0
- package/themes/adwaita.css +62 -0
- package/themes/andromeeda.css +66 -0
- package/themes/aurora-x.css +66 -0
- package/themes/ayu-dark.css +66 -0
- package/themes/caffeine.css +113 -0
- package/themes/catppuccin.css +62 -0
- package/themes/claude-plus.css +60 -0
- package/themes/cursor-hc.css +34 -0
- package/themes/cursor-midnight.css +34 -0
- package/themes/cursor.css +62 -0
- package/themes/dark-plus.css +66 -0
- package/themes/doom-64.css +109 -0
- package/themes/dracula.css +33 -0
- package/themes/everforest-hard.css +62 -0
- package/themes/everforest-soft.css +62 -0
- package/themes/everforest.css +62 -0
- package/themes/github.css +66 -0
- package/themes/gruvbox.css +62 -0
- package/themes/houston.css +66 -0
- package/themes/kanagawa-dragon.css +34 -0
- package/themes/kanagawa-lotus.css +34 -0
- package/themes/kanagawa-wave.css +34 -0
- package/themes/laserwave.css +66 -0
- package/themes/material.css +62 -0
- package/themes/min.css +66 -0
- package/themes/monokai-pro.css +34 -0
- package/themes/neutral.css +59 -0
- package/themes/night-owl.css +66 -0
- package/themes/nord.css +66 -0
- package/themes/one-dark-pro.css +66 -0
- package/themes/one-light.css +66 -0
- package/themes/paulmillr.css +34 -0
- package/themes/plannotator.css +60 -0
- package/themes/plastic.css +66 -0
- package/themes/poimandres.css +66 -0
- package/themes/quantum-rose.css +109 -0
- package/themes/red.css +66 -0
- package/themes/rose-pine.css +62 -0
- package/themes/simple.css +124 -0
- package/themes/slack.css +66 -0
- package/themes/snazzy-light.css +66 -0
- package/themes/soft-pop.css +60 -0
- package/themes/solar-dusk.css +109 -0
- package/themes/solarized.css +66 -0
- package/themes/synthwave-84.css +34 -0
- package/themes/terminal.css +62 -0
- package/themes/tinacious.css +57 -0
- package/themes/tokyo-night.css +62 -0
- package/themes/vesper.css +62 -0
- package/themes/vitesse-black.css +66 -0
- package/themes/vitesse.css +62 -0
- package/types.ts +264 -0
- package/utils/agentSwitch.ts +71 -0
- package/utils/aiChatFormat.ts +33 -0
- package/utils/aiPrompt.ts +29 -0
- package/utils/aiProvider.ts +217 -0
- package/utils/anchors.ts +11 -0
- package/utils/annotateAgentTerminal.ts +29 -0
- package/utils/annotationHelpers.ts +101 -0
- package/utils/bear.ts +59 -0
- package/utils/blockTargeting.ts +240 -0
- package/utils/callback.ts +99 -0
- package/utils/commentContent.ts +8 -0
- package/utils/defaultNotesApp.ts +20 -0
- package/utils/diffFonts.ts +33 -0
- package/utils/editorMode.ts +31 -0
- package/utils/fileBrowser.ts +40 -0
- package/utils/generateId.ts +7 -0
- package/utils/generateIdentity.ts +29 -0
- package/utils/identity.ts +112 -0
- package/utils/inlineTransforms.ts +41 -0
- package/utils/inputMethod.ts +17 -0
- package/utils/lookAndFeelAnnouncement.ts +18 -0
- package/utils/obsidian.ts +201 -0
- package/utils/octarine.ts +53 -0
- package/utils/parser.ts +991 -0
- package/utils/permissionMode.ts +77 -0
- package/utils/planAIAnnouncement.ts +17 -0
- package/utils/planAgentInstructions.ts +137 -0
- package/utils/planDiffEngine.ts +590 -0
- package/utils/planSave.ts +49 -0
- package/utils/platform.ts +11 -0
- package/utils/quickLabels.ts +77 -0
- package/utils/reviewAgentInstructions.ts +182 -0
- package/utils/sanitizeHtml.ts +45 -0
- package/utils/sharing.ts +350 -0
- package/utils/slugify.ts +37 -0
- package/utils/storage.ts +141 -0
- package/utils/themeRegistry.ts +567 -0
- package/utils/uiPreferences.ts +34 -0
- package/utils/upload.ts +56 -0
- package/utils/wideMode.ts +48 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlanDiffBadge — The +/- change badge
|
|
3
|
+
*
|
|
4
|
+
* Sits in the repo info area of the document card (top-left).
|
|
5
|
+
* Shows addition/deletion counts and toggles plan diff view when clicked.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React from "react";
|
|
9
|
+
import type { PlanDiffStats } from "../../utils/planDiffEngine";
|
|
10
|
+
|
|
11
|
+
interface PlanDiffBadgeProps {
|
|
12
|
+
stats: PlanDiffStats | null;
|
|
13
|
+
isActive: boolean;
|
|
14
|
+
onToggle: () => void;
|
|
15
|
+
hasPreviousVersion: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const PlanDiffBadge: React.FC<PlanDiffBadgeProps> = ({
|
|
19
|
+
stats,
|
|
20
|
+
isActive,
|
|
21
|
+
onToggle,
|
|
22
|
+
hasPreviousVersion,
|
|
23
|
+
}) => {
|
|
24
|
+
if (!hasPreviousVersion || !stats) return null;
|
|
25
|
+
|
|
26
|
+
const hasChanges = stats.additions > 0 || stats.deletions > 0 || stats.modifications > 0;
|
|
27
|
+
if (!hasChanges) return null;
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<button
|
|
31
|
+
onClick={onToggle}
|
|
32
|
+
className={`px-1.5 py-0.5 rounded text-[9px] font-mono transition-colors cursor-pointer ${
|
|
33
|
+
isActive
|
|
34
|
+
? "bg-primary/15"
|
|
35
|
+
: "bg-muted/50 hover:bg-muted"
|
|
36
|
+
}`}
|
|
37
|
+
title={isActive ? "Exit plan diff view" : "Show what changed from previous version"}
|
|
38
|
+
>
|
|
39
|
+
<span className={isActive ? "text-success" : "text-success/70"}>
|
|
40
|
+
+{stats.additions}
|
|
41
|
+
</span>
|
|
42
|
+
<span className="text-muted-foreground/50 mx-0.5">/</span>
|
|
43
|
+
<span className={isActive ? "text-destructive" : "text-destructive/70"}>
|
|
44
|
+
-{stats.deletions}
|
|
45
|
+
</span>
|
|
46
|
+
</button>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlanDiffModeSwitcher — Toggle between clean/rendered and raw diff views
|
|
3
|
+
*
|
|
4
|
+
* Follows the same visual pattern as ModeSwitcher.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from "react";
|
|
8
|
+
|
|
9
|
+
export type PlanDiffMode = "clean" | "classic" | "raw";
|
|
10
|
+
|
|
11
|
+
interface PlanDiffModeSwitcherProps {
|
|
12
|
+
mode: PlanDiffMode;
|
|
13
|
+
onChange: (mode: PlanDiffMode) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const PlanDiffModeSwitcher: React.FC<PlanDiffModeSwitcherProps> = ({
|
|
17
|
+
mode,
|
|
18
|
+
onChange,
|
|
19
|
+
}) => {
|
|
20
|
+
return (
|
|
21
|
+
<div className="inline-flex items-center bg-muted/50 rounded-lg p-0.5 border border-border/30">
|
|
22
|
+
<button
|
|
23
|
+
onClick={() => onChange("clean")}
|
|
24
|
+
title="Word-level inline diff (experimental)"
|
|
25
|
+
className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-all ${
|
|
26
|
+
mode === "clean"
|
|
27
|
+
? "bg-background text-foreground shadow-sm"
|
|
28
|
+
: "text-muted-foreground hover:text-foreground"
|
|
29
|
+
}`}
|
|
30
|
+
>
|
|
31
|
+
<svg
|
|
32
|
+
className="w-3.5 h-3.5"
|
|
33
|
+
fill="none"
|
|
34
|
+
viewBox="0 0 24 24"
|
|
35
|
+
stroke="currentColor"
|
|
36
|
+
strokeWidth={2}
|
|
37
|
+
>
|
|
38
|
+
<path
|
|
39
|
+
strokeLinecap="round"
|
|
40
|
+
strokeLinejoin="round"
|
|
41
|
+
d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"
|
|
42
|
+
/>
|
|
43
|
+
<path
|
|
44
|
+
strokeLinecap="round"
|
|
45
|
+
strokeLinejoin="round"
|
|
46
|
+
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
|
47
|
+
/>
|
|
48
|
+
</svg>
|
|
49
|
+
Rendered
|
|
50
|
+
<span className="text-[9px] uppercase tracking-wider opacity-60 ml-0.5">
|
|
51
|
+
exp
|
|
52
|
+
</span>
|
|
53
|
+
</button>
|
|
54
|
+
<button
|
|
55
|
+
onClick={() => onChange("classic")}
|
|
56
|
+
title="Block-level stacked diff (old above new)"
|
|
57
|
+
className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-all ${
|
|
58
|
+
mode === "classic"
|
|
59
|
+
? "bg-background text-foreground shadow-sm"
|
|
60
|
+
: "text-muted-foreground hover:text-foreground"
|
|
61
|
+
}`}
|
|
62
|
+
>
|
|
63
|
+
<svg
|
|
64
|
+
className="w-3.5 h-3.5"
|
|
65
|
+
fill="none"
|
|
66
|
+
viewBox="0 0 24 24"
|
|
67
|
+
stroke="currentColor"
|
|
68
|
+
strokeWidth={2}
|
|
69
|
+
>
|
|
70
|
+
<path
|
|
71
|
+
strokeLinecap="round"
|
|
72
|
+
strokeLinejoin="round"
|
|
73
|
+
d="M4 6h16M4 12h16M4 18h16"
|
|
74
|
+
/>
|
|
75
|
+
</svg>
|
|
76
|
+
Classic
|
|
77
|
+
</button>
|
|
78
|
+
<button
|
|
79
|
+
onClick={() => onChange("raw")}
|
|
80
|
+
className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-all ${
|
|
81
|
+
mode === "raw"
|
|
82
|
+
? "bg-background text-foreground shadow-sm"
|
|
83
|
+
: "text-muted-foreground hover:text-foreground"
|
|
84
|
+
}`}
|
|
85
|
+
>
|
|
86
|
+
<svg
|
|
87
|
+
className="w-3.5 h-3.5"
|
|
88
|
+
fill="none"
|
|
89
|
+
viewBox="0 0 24 24"
|
|
90
|
+
stroke="currentColor"
|
|
91
|
+
strokeWidth={2}
|
|
92
|
+
>
|
|
93
|
+
<path
|
|
94
|
+
strokeLinecap="round"
|
|
95
|
+
strokeLinejoin="round"
|
|
96
|
+
d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5"
|
|
97
|
+
/>
|
|
98
|
+
</svg>
|
|
99
|
+
Raw
|
|
100
|
+
</button>
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlanDiffViewer — Orchestrator for plan diff views
|
|
3
|
+
*
|
|
4
|
+
* Replaces the Viewer component when plan diff mode is active.
|
|
5
|
+
* Renders the document card with the same styling, but shows
|
|
6
|
+
* diff content instead of the annotatable plan.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import React, { useState } from "react";
|
|
10
|
+
import type { PlanDiffBlock, PlanDiffStats } from "../../utils/planDiffEngine";
|
|
11
|
+
import type { Annotation, EditorMode } from "../../types";
|
|
12
|
+
import {
|
|
13
|
+
PlanDiffModeSwitcher,
|
|
14
|
+
type PlanDiffMode,
|
|
15
|
+
} from "./PlanDiffModeSwitcher";
|
|
16
|
+
import { PlanCleanDiffView } from "./PlanCleanDiffView";
|
|
17
|
+
import { PlanRawDiffView } from "./PlanRawDiffView";
|
|
18
|
+
import { PlanDiffBadge } from "./PlanDiffBadge";
|
|
19
|
+
import { VSCodeIcon } from "./VSCodeIcon";
|
|
20
|
+
|
|
21
|
+
interface PlanDiffViewerProps {
|
|
22
|
+
diffBlocks: PlanDiffBlock[];
|
|
23
|
+
diffStats: PlanDiffStats;
|
|
24
|
+
diffMode: PlanDiffMode;
|
|
25
|
+
onDiffModeChange: (mode: PlanDiffMode) => void;
|
|
26
|
+
onPlanDiffToggle: () => void;
|
|
27
|
+
repoInfo?: { display: string; branch?: string } | null;
|
|
28
|
+
baseVersionLabel?: string;
|
|
29
|
+
baseVersion?: number;
|
|
30
|
+
maxWidth?: number;
|
|
31
|
+
// Annotation props
|
|
32
|
+
annotations?: Annotation[];
|
|
33
|
+
onAddAnnotation?: (ann: Annotation) => void;
|
|
34
|
+
onSelectAnnotation?: (id: string | null) => void;
|
|
35
|
+
selectedAnnotationId?: string | null;
|
|
36
|
+
mode?: EditorMode;
|
|
37
|
+
onOpenVscodeDiff?: (baseVersion: number) => Promise<{ ok?: boolean; error?: string }>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const defaultOpenVscodeDiff = async (
|
|
41
|
+
baseVersion: number
|
|
42
|
+
): Promise<{ ok?: boolean; error?: string }> => {
|
|
43
|
+
try {
|
|
44
|
+
const res = await fetch("/api/plan/vscode-diff", {
|
|
45
|
+
method: "POST",
|
|
46
|
+
headers: { "Content-Type": "application/json" },
|
|
47
|
+
body: JSON.stringify({ baseVersion }),
|
|
48
|
+
});
|
|
49
|
+
const data = (await res.json()) as { ok?: boolean; error?: string };
|
|
50
|
+
if (!res.ok || data.error) {
|
|
51
|
+
return { error: data.error || "Failed to open VS Code diff" };
|
|
52
|
+
}
|
|
53
|
+
return { ok: true };
|
|
54
|
+
} catch {
|
|
55
|
+
return { error: "Failed to connect to server" };
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const PlanDiffViewer: React.FC<PlanDiffViewerProps> = ({
|
|
60
|
+
diffBlocks,
|
|
61
|
+
diffStats,
|
|
62
|
+
diffMode,
|
|
63
|
+
onDiffModeChange,
|
|
64
|
+
onPlanDiffToggle,
|
|
65
|
+
repoInfo,
|
|
66
|
+
baseVersionLabel,
|
|
67
|
+
baseVersion,
|
|
68
|
+
maxWidth,
|
|
69
|
+
annotations,
|
|
70
|
+
onAddAnnotation,
|
|
71
|
+
onSelectAnnotation,
|
|
72
|
+
selectedAnnotationId,
|
|
73
|
+
mode,
|
|
74
|
+
onOpenVscodeDiff,
|
|
75
|
+
}) => {
|
|
76
|
+
const [vscodeDiffLoading, setVscodeDiffLoading] = useState(false);
|
|
77
|
+
const [vscodeDiffError, setVscodeDiffError] = useState<string | null>(null);
|
|
78
|
+
|
|
79
|
+
const canOpenVscodeDiff = baseVersion != null;
|
|
80
|
+
|
|
81
|
+
const handleOpenVscodeDiff = async () => {
|
|
82
|
+
if (!canOpenVscodeDiff || baseVersion == null) return;
|
|
83
|
+
setVscodeDiffLoading(true);
|
|
84
|
+
setVscodeDiffError(null);
|
|
85
|
+
try {
|
|
86
|
+
const result = await (onOpenVscodeDiff ?? defaultOpenVscodeDiff)(baseVersion);
|
|
87
|
+
if (result.error) {
|
|
88
|
+
setVscodeDiffError(result.error);
|
|
89
|
+
}
|
|
90
|
+
} catch {
|
|
91
|
+
// A host-supplied opener that throws (instead of returning { error }) must
|
|
92
|
+
// not wedge the button in a permanent loading state.
|
|
93
|
+
setVscodeDiffError("Failed to open VS Code diff");
|
|
94
|
+
} finally {
|
|
95
|
+
setVscodeDiffLoading(false);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<div className="relative z-50 w-full" style={maxWidth ? { maxWidth } : { maxWidth: 832 }}>
|
|
101
|
+
<article className="w-full bg-card border border-border/50 rounded-xl shadow-xl p-5 md:p-8 lg:p-10 xl:p-12 relative">
|
|
102
|
+
{/* Top-left: repo info + diff badge — matches Viewer layout (flex-col) so badge doesn't jump position */}
|
|
103
|
+
<div className="absolute top-3 left-3 md:top-4 md:left-5 flex flex-col items-start gap-1 text-[9px] text-muted-foreground/50 font-mono">
|
|
104
|
+
{repoInfo && (
|
|
105
|
+
<div className="flex items-center gap-1.5">
|
|
106
|
+
<span
|
|
107
|
+
className="px-1.5 py-0.5 bg-muted/50 rounded truncate max-w-[140px]"
|
|
108
|
+
title={repoInfo.display}
|
|
109
|
+
>
|
|
110
|
+
{repoInfo.display}
|
|
111
|
+
</span>
|
|
112
|
+
{repoInfo.branch && (
|
|
113
|
+
<span
|
|
114
|
+
className="px-1.5 py-0.5 bg-muted/30 rounded max-w-[120px] flex items-center gap-1 overflow-hidden"
|
|
115
|
+
title={repoInfo.branch}
|
|
116
|
+
>
|
|
117
|
+
<svg
|
|
118
|
+
className="w-2.5 h-2.5 flex-shrink-0"
|
|
119
|
+
viewBox="0 0 16 16"
|
|
120
|
+
fill="currentColor"
|
|
121
|
+
>
|
|
122
|
+
<path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z" />
|
|
123
|
+
</svg>
|
|
124
|
+
<span className="truncate">{repoInfo.branch}</span>
|
|
125
|
+
</span>
|
|
126
|
+
)}
|
|
127
|
+
</div>
|
|
128
|
+
)}
|
|
129
|
+
<PlanDiffBadge
|
|
130
|
+
stats={diffStats}
|
|
131
|
+
isActive={true}
|
|
132
|
+
onToggle={onPlanDiffToggle}
|
|
133
|
+
hasPreviousVersion={true}
|
|
134
|
+
/>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
{/* Top-right: back to plan view button */}
|
|
138
|
+
<div className="float-right -mr-4 -mt-4 md:-mr-5 md:-mt-5 lg:-mr-7 lg:-mt-7 xl:-mr-9 xl:-mt-9 p-2">
|
|
139
|
+
<button
|
|
140
|
+
onClick={onPlanDiffToggle}
|
|
141
|
+
className="flex items-center gap-1 px-2 py-1.5 rounded-md text-xs text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
|
|
142
|
+
title="Back to plan view"
|
|
143
|
+
>
|
|
144
|
+
<span className="hidden md:inline text-[10px] font-medium">Exit Diff</span>
|
|
145
|
+
<svg
|
|
146
|
+
className="w-3.5 h-3.5"
|
|
147
|
+
fill="none"
|
|
148
|
+
viewBox="0 0 24 24"
|
|
149
|
+
stroke="currentColor"
|
|
150
|
+
strokeWidth={2}
|
|
151
|
+
>
|
|
152
|
+
<path
|
|
153
|
+
strokeLinecap="round"
|
|
154
|
+
strokeLinejoin="round"
|
|
155
|
+
d="M6 18L18 6M6 6l12 12"
|
|
156
|
+
/>
|
|
157
|
+
</svg>
|
|
158
|
+
</button>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
{/* Diff mode switcher + version label + VS Code button */}
|
|
162
|
+
<div className="mt-6 mb-6 flex items-center gap-3">
|
|
163
|
+
<PlanDiffModeSwitcher mode={diffMode} onChange={onDiffModeChange} />
|
|
164
|
+
{baseVersionLabel && (
|
|
165
|
+
<span className="text-[10px] text-muted-foreground">
|
|
166
|
+
vs {baseVersionLabel}
|
|
167
|
+
</span>
|
|
168
|
+
)}
|
|
169
|
+
{canOpenVscodeDiff && (
|
|
170
|
+
<button
|
|
171
|
+
onClick={handleOpenVscodeDiff}
|
|
172
|
+
disabled={vscodeDiffLoading}
|
|
173
|
+
className="ml-auto flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium text-muted-foreground hover:text-foreground hover:bg-muted/50 border border-border/30 transition-colors disabled:opacity-50"
|
|
174
|
+
title="Open diff in VS Code"
|
|
175
|
+
>
|
|
176
|
+
<VSCodeIcon className="w-3.5 h-3.5 flex-shrink-0" />
|
|
177
|
+
<span className="hidden md:inline">
|
|
178
|
+
{vscodeDiffLoading ? "Opening..." : "VS Code"}
|
|
179
|
+
</span>
|
|
180
|
+
</button>
|
|
181
|
+
)}
|
|
182
|
+
</div>
|
|
183
|
+
|
|
184
|
+
{/* VS Code diff error message */}
|
|
185
|
+
{vscodeDiffError && (
|
|
186
|
+
<div className="mb-4 px-3 py-2 rounded-md bg-destructive/10 border border-destructive/20 text-xs text-destructive">
|
|
187
|
+
{vscodeDiffError}
|
|
188
|
+
<button
|
|
189
|
+
onClick={() => setVscodeDiffError(null)}
|
|
190
|
+
className="ml-2 text-destructive/60 hover:text-destructive"
|
|
191
|
+
>
|
|
192
|
+
dismiss
|
|
193
|
+
</button>
|
|
194
|
+
</div>
|
|
195
|
+
)}
|
|
196
|
+
|
|
197
|
+
{/* Diff content */}
|
|
198
|
+
{diffMode === "raw" ? (
|
|
199
|
+
<PlanRawDiffView blocks={diffBlocks} />
|
|
200
|
+
) : (
|
|
201
|
+
<PlanCleanDiffView
|
|
202
|
+
blocks={diffBlocks}
|
|
203
|
+
annotations={annotations}
|
|
204
|
+
onAddAnnotation={onAddAnnotation}
|
|
205
|
+
onSelectAnnotation={onSelectAnnotation}
|
|
206
|
+
selectedAnnotationId={selectedAnnotationId}
|
|
207
|
+
mode={mode}
|
|
208
|
+
wordLevel={diffMode === "clean"}
|
|
209
|
+
/>
|
|
210
|
+
)}
|
|
211
|
+
</article>
|
|
212
|
+
</div>
|
|
213
|
+
);
|
|
214
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlanRawDiffView — Raw markdown diff mode (P2 style)
|
|
3
|
+
*
|
|
4
|
+
* Shows the raw markdown source with +/- prefixed lines,
|
|
5
|
+
* like a traditional code diff. Monospace font, line numbers,
|
|
6
|
+
* colored backgrounds.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import React, { useMemo } from "react";
|
|
10
|
+
import type { PlanDiffBlock } from "../../utils/planDiffEngine";
|
|
11
|
+
|
|
12
|
+
interface PlanRawDiffViewProps {
|
|
13
|
+
blocks: PlanDiffBlock[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface DiffLine {
|
|
17
|
+
type: "added" | "removed" | "unchanged";
|
|
18
|
+
content: string;
|
|
19
|
+
lineNumber: number | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const PlanRawDiffView: React.FC<PlanRawDiffViewProps> = ({ blocks }) => {
|
|
23
|
+
const lines = useMemo(() => {
|
|
24
|
+
const result: DiffLine[] = [];
|
|
25
|
+
let lineNum = 1;
|
|
26
|
+
|
|
27
|
+
for (const block of blocks) {
|
|
28
|
+
const rawLines = block.content.split("\n");
|
|
29
|
+
// Remove trailing empty string from split
|
|
30
|
+
if (rawLines.length > 0 && rawLines[rawLines.length - 1] === "") {
|
|
31
|
+
rawLines.pop();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (block.type === "modified" && block.oldContent) {
|
|
35
|
+
// Show old content as removed
|
|
36
|
+
const oldLines = block.oldContent.split("\n");
|
|
37
|
+
if (oldLines.length > 0 && oldLines[oldLines.length - 1] === "") {
|
|
38
|
+
oldLines.pop();
|
|
39
|
+
}
|
|
40
|
+
for (const line of oldLines) {
|
|
41
|
+
result.push({ type: "removed", content: line, lineNumber: null });
|
|
42
|
+
}
|
|
43
|
+
// Show new content as added
|
|
44
|
+
for (const line of rawLines) {
|
|
45
|
+
result.push({ type: "added", content: line, lineNumber: lineNum++ });
|
|
46
|
+
}
|
|
47
|
+
} else if (block.type === "added") {
|
|
48
|
+
for (const line of rawLines) {
|
|
49
|
+
result.push({ type: "added", content: line, lineNumber: lineNum++ });
|
|
50
|
+
}
|
|
51
|
+
} else if (block.type === "removed") {
|
|
52
|
+
for (const line of rawLines) {
|
|
53
|
+
result.push({ type: "removed", content: line, lineNumber: null });
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
for (const line of rawLines) {
|
|
57
|
+
result.push({
|
|
58
|
+
type: "unchanged",
|
|
59
|
+
content: line,
|
|
60
|
+
lineNumber: lineNum++,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return result;
|
|
67
|
+
}, [blocks]);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<div className="font-mono text-[13px] leading-relaxed bg-muted/30 rounded-lg border border-border/30 overflow-x-auto">
|
|
71
|
+
<div>
|
|
72
|
+
{lines.map((line, index) => (
|
|
73
|
+
<div
|
|
74
|
+
key={index}
|
|
75
|
+
className={`flex px-4 py-0.5 ${
|
|
76
|
+
line.type === "added"
|
|
77
|
+
? "plan-diff-line-added"
|
|
78
|
+
: line.type === "removed"
|
|
79
|
+
? "plan-diff-line-removed"
|
|
80
|
+
: "hover:bg-muted/30"
|
|
81
|
+
}`}
|
|
82
|
+
>
|
|
83
|
+
{/* Gutter: +/- prefix */}
|
|
84
|
+
<div className="w-5 flex-shrink-0 select-none opacity-60 text-right pr-2">
|
|
85
|
+
{line.type === "added"
|
|
86
|
+
? "+"
|
|
87
|
+
: line.type === "removed"
|
|
88
|
+
? "-"
|
|
89
|
+
: " "}
|
|
90
|
+
</div>
|
|
91
|
+
{/* Line number */}
|
|
92
|
+
<div className="w-8 flex-shrink-0 select-none text-muted-foreground/40 text-right pr-3 text-[11px]">
|
|
93
|
+
{line.lineNumber ?? ""}
|
|
94
|
+
</div>
|
|
95
|
+
{/* Content */}
|
|
96
|
+
<div className="whitespace-pre-wrap break-words min-w-0">{line.content || " "}</div>
|
|
97
|
+
</div>
|
|
98
|
+
))}
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
export const VSCodeIcon: React.FC<{ className?: string }> = ({ className }) => (
|
|
4
|
+
<svg
|
|
5
|
+
className={className}
|
|
6
|
+
viewBox="0 0 100 100"
|
|
7
|
+
fill="none"
|
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
9
|
+
>
|
|
10
|
+
<mask
|
|
11
|
+
id="mask0"
|
|
12
|
+
{...{ 'mask-type': 'alpha' }}
|
|
13
|
+
maskUnits="userSpaceOnUse"
|
|
14
|
+
x="0"
|
|
15
|
+
y="0"
|
|
16
|
+
width="100"
|
|
17
|
+
height="100"
|
|
18
|
+
>
|
|
19
|
+
<path
|
|
20
|
+
fillRule="evenodd"
|
|
21
|
+
clipRule="evenodd"
|
|
22
|
+
d="M70.9119 99.3171C72.4869 99.9307 74.2828 99.8914 75.8725 99.1264L96.4608 89.2197C98.6242 88.1787 100 85.9892 100 83.5872V16.4133C100 14.0113 98.6243 11.8218 96.4609 10.7808L75.8725 0.873756C73.7862 -0.130129 71.3446 0.11576 69.5135 1.44695C69.252 1.63711 69.0028 1.84943 68.769 2.08341L29.3551 38.0415L12.1872 25.0096C10.589 23.7965 8.35363 23.8959 6.86933 25.2461L1.36303 30.2549C-0.452552 31.9064 -0.454633 34.7627 1.35853 36.417L16.2471 50.0001L1.35853 63.5832C-0.454633 65.2374 -0.452552 68.0938 1.36303 69.7453L6.86933 74.7541C8.35363 76.1043 10.589 76.2037 12.1872 74.9905L29.3551 61.9587L68.769 97.9167C69.3925 98.5406 70.1246 99.0104 70.9119 99.3171ZM75.0152 27.2989L45.1091 50.0001L75.0152 72.7012V27.2989Z"
|
|
23
|
+
fill="white"
|
|
24
|
+
/>
|
|
25
|
+
</mask>
|
|
26
|
+
<g mask="url(#mask0)">
|
|
27
|
+
<path
|
|
28
|
+
d="M96.4614 10.7962L75.8569 0.875542C73.4719 -0.272773 70.6217 0.211611 68.75 2.08333L1.29858 63.5832C-0.515693 65.2373 -0.513607 68.0937 1.30308 69.7452L6.81272 74.754C8.29793 76.1042 10.5347 76.2036 12.1338 74.9905L93.3609 13.3699C96.086 11.3026 100 13.2462 100 16.6667V16.4275C100 14.0265 98.6246 11.8378 96.4614 10.7962Z"
|
|
29
|
+
fill="#0065A9"
|
|
30
|
+
/>
|
|
31
|
+
<g filter="url(#filter0_d)">
|
|
32
|
+
<path
|
|
33
|
+
d="M96.4614 89.2038L75.8569 99.1245C73.4719 100.273 70.6217 99.7884 68.75 97.9167L1.29858 36.4169C-0.515693 34.7627 -0.513607 31.9063 1.30308 30.2548L6.81272 25.246C8.29793 23.8958 10.5347 23.7964 12.1338 25.0095L93.3609 86.6301C96.086 88.6974 100 86.7538 100 83.3334V83.5726C100 85.9735 98.6246 88.1622 96.4614 89.2038Z"
|
|
34
|
+
fill="#007ACC"
|
|
35
|
+
/>
|
|
36
|
+
</g>
|
|
37
|
+
<g filter="url(#filter1_d)">
|
|
38
|
+
<path
|
|
39
|
+
d="M75.8578 99.1263C73.4721 100.274 70.6219 99.7885 68.75 97.9166C71.0564 100.223 75 98.5895 75 95.3278V4.67213C75 1.41039 71.0564 -0.223106 68.75 2.08329C70.6219 0.211402 73.4721 -0.273666 75.8578 0.873633L96.4587 10.7807C98.6234 11.8217 100 14.0112 100 16.4132V83.5871C100 85.9891 98.6234 88.1786 96.4586 89.2196L75.8578 99.1263Z"
|
|
40
|
+
fill="#1F9CF0"
|
|
41
|
+
/>
|
|
42
|
+
</g>
|
|
43
|
+
<g style={{ mixBlendMode: "overlay" }} opacity="0.25">
|
|
44
|
+
<path
|
|
45
|
+
fillRule="evenodd"
|
|
46
|
+
clipRule="evenodd"
|
|
47
|
+
d="M70.8511 99.3171C72.4261 99.9306 74.2221 99.8913 75.8117 99.1264L96.4 89.2197C98.5634 88.1787 99.9392 85.9892 99.9392 83.5871V16.4133C99.9392 14.0112 98.5635 11.8217 96.4001 10.7807L75.8117 0.873695C73.7255 -0.13019 71.2838 0.115699 69.4527 1.44688C69.1912 1.63705 68.942 1.84937 68.7082 2.08335L29.2943 38.0414L12.1264 25.0096C10.5283 23.7964 8.29285 23.8959 6.80855 25.246L1.30225 30.2548C-0.513334 31.9064 -0.515415 34.7627 1.29775 36.4169L16.1863 50L1.29775 63.5832C-0.515415 65.2374 -0.513334 68.0937 1.30225 69.7452L6.80855 74.754C8.29285 76.1042 10.5283 76.2036 12.1264 74.9905L29.2943 61.9586L68.7082 97.9167C69.3317 98.5405 70.0638 99.0104 70.8511 99.3171ZM74.9544 27.2989L45.0483 50L74.9544 72.7012V27.2989Z"
|
|
48
|
+
fill="url(#paint0_linear)"
|
|
49
|
+
/>
|
|
50
|
+
</g>
|
|
51
|
+
</g>
|
|
52
|
+
<defs>
|
|
53
|
+
<filter
|
|
54
|
+
id="filter0_d"
|
|
55
|
+
x="-8.39411"
|
|
56
|
+
y="15.8291"
|
|
57
|
+
width="116.727"
|
|
58
|
+
height="92.2456"
|
|
59
|
+
filterUnits="userSpaceOnUse"
|
|
60
|
+
colorInterpolationFilters="sRGB"
|
|
61
|
+
>
|
|
62
|
+
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
|
63
|
+
<feColorMatrix
|
|
64
|
+
in="SourceAlpha"
|
|
65
|
+
type="matrix"
|
|
66
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
|
67
|
+
/>
|
|
68
|
+
<feOffset />
|
|
69
|
+
<feGaussianBlur stdDeviation="4.16667" />
|
|
70
|
+
<feColorMatrix
|
|
71
|
+
type="matrix"
|
|
72
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
|
73
|
+
/>
|
|
74
|
+
<feBlend
|
|
75
|
+
mode="overlay"
|
|
76
|
+
in2="BackgroundImageFix"
|
|
77
|
+
result="effect1_dropShadow"
|
|
78
|
+
/>
|
|
79
|
+
<feBlend
|
|
80
|
+
mode="normal"
|
|
81
|
+
in="SourceGraphic"
|
|
82
|
+
in2="effect1_dropShadow"
|
|
83
|
+
result="shape"
|
|
84
|
+
/>
|
|
85
|
+
</filter>
|
|
86
|
+
<filter
|
|
87
|
+
id="filter1_d"
|
|
88
|
+
x="60.4167"
|
|
89
|
+
y="-8.07558"
|
|
90
|
+
width="47.9167"
|
|
91
|
+
height="116.151"
|
|
92
|
+
filterUnits="userSpaceOnUse"
|
|
93
|
+
colorInterpolationFilters="sRGB"
|
|
94
|
+
>
|
|
95
|
+
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
|
96
|
+
<feColorMatrix
|
|
97
|
+
in="SourceAlpha"
|
|
98
|
+
type="matrix"
|
|
99
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
|
100
|
+
/>
|
|
101
|
+
<feOffset />
|
|
102
|
+
<feGaussianBlur stdDeviation="4.16667" />
|
|
103
|
+
<feColorMatrix
|
|
104
|
+
type="matrix"
|
|
105
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
|
106
|
+
/>
|
|
107
|
+
<feBlend
|
|
108
|
+
mode="overlay"
|
|
109
|
+
in2="BackgroundImageFix"
|
|
110
|
+
result="effect1_dropShadow"
|
|
111
|
+
/>
|
|
112
|
+
<feBlend
|
|
113
|
+
mode="normal"
|
|
114
|
+
in="SourceGraphic"
|
|
115
|
+
in2="effect1_dropShadow"
|
|
116
|
+
result="shape"
|
|
117
|
+
/>
|
|
118
|
+
</filter>
|
|
119
|
+
<linearGradient
|
|
120
|
+
id="paint0_linear"
|
|
121
|
+
x1="49.9392"
|
|
122
|
+
y1="0.257812"
|
|
123
|
+
x2="49.9392"
|
|
124
|
+
y2="99.7423"
|
|
125
|
+
gradientUnits="userSpaceOnUse"
|
|
126
|
+
>
|
|
127
|
+
<stop stopColor="white" />
|
|
128
|
+
<stop offset="1" stopColor="white" stopOpacity="0" />
|
|
129
|
+
</linearGradient>
|
|
130
|
+
</defs>
|
|
131
|
+
</svg>
|
|
132
|
+
);
|