mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-09-22 22:38:05 +03:00
VitePress: Add mermaid zoom
This commit is contained in:
@@ -0,0 +1,497 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, onBeforeUnmount, nextTick } from "vue"
|
||||||
|
|
||||||
|
// --- Types ---
|
||||||
|
interface PanZoomInstance {
|
||||||
|
destroy: () => void
|
||||||
|
resize?: () => void
|
||||||
|
fit?: () => void
|
||||||
|
center?: () => void
|
||||||
|
resetZoom?: () => void
|
||||||
|
zoomIn?: () => void
|
||||||
|
zoomOut?: () => void
|
||||||
|
zoomBy?: (scale: number) => void
|
||||||
|
panBy?: (p: { x: number; y: number }) => void
|
||||||
|
getPan?: () => { x: number; y: number }
|
||||||
|
pan?: (p: { x: number; y: number }) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- State ---
|
||||||
|
const open = ref(false)
|
||||||
|
const svgHtml = ref("")
|
||||||
|
const contentRef = ref<HTMLElement | null>(null)
|
||||||
|
let panZoom: PanZoomInstance | null = null
|
||||||
|
|
||||||
|
// Factory cache (Singleton pattern)
|
||||||
|
type SvgPanZoomFactory = (
|
||||||
|
svg: SVGSVGElement,
|
||||||
|
opts: Record<string, any>
|
||||||
|
) => PanZoomInstance
|
||||||
|
let svgPanZoomFactory: SvgPanZoomFactory | null = null
|
||||||
|
|
||||||
|
const PAN_STEP_PX = 60
|
||||||
|
|
||||||
|
// --- Backdrop Logic ---
|
||||||
|
let backdropPress = false
|
||||||
|
let backdropPointerId: number | null = null
|
||||||
|
|
||||||
|
// --- Actions ---
|
||||||
|
const destroyPanzoom = () => {
|
||||||
|
if (!panZoom) return
|
||||||
|
try {
|
||||||
|
panZoom.destroy()
|
||||||
|
} catch {}
|
||||||
|
panZoom = null
|
||||||
|
}
|
||||||
|
|
||||||
|
const initPanzoom = async () => {
|
||||||
|
await nextTick()
|
||||||
|
destroyPanzoom()
|
||||||
|
|
||||||
|
const svg = contentRef.value?.querySelector(
|
||||||
|
"svg"
|
||||||
|
) as SVGSVGElement | null
|
||||||
|
if (!svg) return
|
||||||
|
|
||||||
|
// Cache the factory to avoid repeated dynamic imports
|
||||||
|
if (!svgPanZoomFactory) {
|
||||||
|
const mod: any = await import("svg-pan-zoom")
|
||||||
|
svgPanZoomFactory = (mod.default ?? mod) as SvgPanZoomFactory
|
||||||
|
}
|
||||||
|
|
||||||
|
panZoom = svgPanZoomFactory(svg, {
|
||||||
|
zoomEnabled: true,
|
||||||
|
panEnabled: true,
|
||||||
|
mouseWheelZoomEnabled: true,
|
||||||
|
dblClickZoomEnabled: true,
|
||||||
|
fit: true,
|
||||||
|
center: true,
|
||||||
|
minZoom: 0.1,
|
||||||
|
maxZoom: 20,
|
||||||
|
controlIconsEnabled: false,
|
||||||
|
preventMouseEventsDefault: true
|
||||||
|
})
|
||||||
|
|
||||||
|
// Initial alignment:
|
||||||
|
// 1. Sync call ensures correct position on first paint (no flash).
|
||||||
|
// 2. RAF handles any layout shifts or font loading settlements.
|
||||||
|
const align = () => {
|
||||||
|
try {
|
||||||
|
panZoom?.resize?.()
|
||||||
|
panZoom?.fit?.()
|
||||||
|
panZoom?.center?.()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
align()
|
||||||
|
requestAnimationFrame(align)
|
||||||
|
}
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
open.value = false
|
||||||
|
svgHtml.value = ""
|
||||||
|
destroyPanzoom()
|
||||||
|
backdropPress = false
|
||||||
|
backdropPointerId = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Pan/Zoom Helpers ---
|
||||||
|
// Helper to safely execute PanZoom methods if the instance exists
|
||||||
|
const withPanZoom = (fn: (pz: PanZoomInstance) => void) => {
|
||||||
|
const pz = panZoom
|
||||||
|
if (!pz) return
|
||||||
|
try {
|
||||||
|
fn(pz)
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const zoomIn = () => withPanZoom((pz) => pz.zoomIn?.())
|
||||||
|
const zoomOut = () => withPanZoom((pz) => pz.zoomOut?.())
|
||||||
|
const resetView = () =>
|
||||||
|
withPanZoom((pz) => {
|
||||||
|
pz.resetZoom?.()
|
||||||
|
pz.fit?.()
|
||||||
|
pz.center?.()
|
||||||
|
})
|
||||||
|
|
||||||
|
const panBy = (dx: number, dy: number) =>
|
||||||
|
withPanZoom((pz) => {
|
||||||
|
// Prefer native panBy if available (better stability with transforms)
|
||||||
|
if (pz.panBy) {
|
||||||
|
pz.panBy({ x: dx, y: dy })
|
||||||
|
} else if (pz.getPan && pz.pan) {
|
||||||
|
const { x, y } = pz.getPan()
|
||||||
|
pz.pan({ x: x + dx, y: y + dy })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const panUp = () => panBy(0, PAN_STEP_PX)
|
||||||
|
const panDown = () => panBy(0, -PAN_STEP_PX)
|
||||||
|
const panLeft = () => panBy(PAN_STEP_PX, 0)
|
||||||
|
const panRight = () => panBy(-PAN_STEP_PX, 0)
|
||||||
|
|
||||||
|
// --- Event Handlers ---
|
||||||
|
function onKeydown(e: KeyboardEvent) {
|
||||||
|
if (e.key === "Escape") close()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onDocClick(e: MouseEvent) {
|
||||||
|
if (open.value) return
|
||||||
|
|
||||||
|
const target = e.target as HTMLElement | null
|
||||||
|
const svg = target?.closest?.("svg") as SVGElement | null
|
||||||
|
// Strict check: only Mermaid diagrams
|
||||||
|
if (!svg || !svg.closest(".mermaid")) return
|
||||||
|
|
||||||
|
e.preventDefault()
|
||||||
|
svgHtml.value = svg.outerHTML
|
||||||
|
open.value = true
|
||||||
|
await initPanzoom()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backdrop specific: only close if user starts AND ends click on backdrop
|
||||||
|
function onBackdropPointerDown(e: PointerEvent) {
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
backdropPress = true
|
||||||
|
backdropPointerId = e.pointerId
|
||||||
|
} else {
|
||||||
|
backdropPress = false
|
||||||
|
backdropPointerId = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBackdropPointerUp(e: PointerEvent) {
|
||||||
|
const isSamePointer = backdropPointerId === e.pointerId
|
||||||
|
const releasedOnBackdrop = e.target === e.currentTarget
|
||||||
|
|
||||||
|
if (backdropPress && isSamePointer && releasedOnBackdrop) {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
backdropPress = false
|
||||||
|
backdropPointerId = null
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBackdropPointerCancel() {
|
||||||
|
backdropPress = false
|
||||||
|
backdropPointerId = null
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
document.addEventListener("keydown", onKeydown)
|
||||||
|
document.addEventListener("click", onDocClick, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
document.removeEventListener("keydown", onKeydown)
|
||||||
|
document.removeEventListener("click", onDocClick, true)
|
||||||
|
destroyPanzoom()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Teleport to="body">
|
||||||
|
<div
|
||||||
|
v-show="open"
|
||||||
|
class="mz-overlay"
|
||||||
|
aria-modal="true"
|
||||||
|
role="dialog"
|
||||||
|
@pointerdown="onBackdropPointerDown"
|
||||||
|
@pointerup="onBackdropPointerUp"
|
||||||
|
@pointercancel="onBackdropPointerCancel"
|
||||||
|
>
|
||||||
|
<div class="mz-box" @click.stop @pointerdown.stop @pointerup.stop>
|
||||||
|
<div class="mz-toolbar" @click.stop>
|
||||||
|
<button
|
||||||
|
class="mz-btn"
|
||||||
|
type="button"
|
||||||
|
title="Zoom out"
|
||||||
|
aria-label="Zoom out"
|
||||||
|
@click="zoomOut"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M19.96 11.48C19.96 13.8 19.02 15.9 17.5 17.45C16.93 18.02 16.28 18.5 15.57 18.9C14.36 19.58 12.96 19.96 11.48 19.96C6.8 19.96 3 16.16 3 11.48C3 6.8 6.8 3 11.48 3C16.16 3 19.96 6.8 19.96 11.48Z"
|
||||||
|
/>
|
||||||
|
<path d="M18.15 18.15L21.88 21.88" />
|
||||||
|
<path d="M8 11.55H15.1" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="mz-btn"
|
||||||
|
type="button"
|
||||||
|
title="Zoom in"
|
||||||
|
aria-label="Zoom in"
|
||||||
|
@click="zoomIn"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M19.96 11.48C19.96 13.8 19.02 15.9 17.5 17.45C16.93 18.02 16.28 18.5 15.57 18.9C14.36 19.58 12.96 19.96 11.48 19.96C6.8 19.96 3 16.16 3 11.48C3 6.8 6.8 3 11.48 3C16.16 3 19.96 6.8 19.96 11.48Z"
|
||||||
|
/>
|
||||||
|
<path d="M18.15 18.15L21.88 21.88" />
|
||||||
|
<path d="M8 11.55H15.1" />
|
||||||
|
<path d="M11.55 15.1L11.55 8" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="mz-btn"
|
||||||
|
type="button"
|
||||||
|
title="Reset view"
|
||||||
|
aria-label="Reset view"
|
||||||
|
@click="resetView"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="M20.95 9.75L22.25 6.13" />
|
||||||
|
<path d="M20.95 9.75L17.16 9.12" />
|
||||||
|
<path
|
||||||
|
d="M20.16 8.28C19.4 6.57 18.09 5.1 16.32 4.14C12.06 1.85 6.75 3.45 4.46 7.7C3.92 8.7 3.6 9.78 3.48 10.85"
|
||||||
|
/>
|
||||||
|
<path d="M3.54 14.25L2.24 17.87" />
|
||||||
|
<path d="M3.54 14.25L7.33 14.87" />
|
||||||
|
<path
|
||||||
|
d="M4.33 15.71C5.1 17.42 6.4 18.9 8.18 19.85C12.44 22.14 17.74 20.55 20.03 16.3C20.57 15.28 20.9 14.22 21.02 13.15"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="mz-btn"
|
||||||
|
type="button"
|
||||||
|
title="Pan up"
|
||||||
|
aria-label="Pan up"
|
||||||
|
@click="panUp"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="M12.4 7L17.8 11.5" />
|
||||||
|
<path d="M12.4 7L7 11.5" />
|
||||||
|
<path d="M12.4 12L17.8 16.5" />
|
||||||
|
<path d="M12.4 12L7 16.5" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="mz-btn"
|
||||||
|
type="button"
|
||||||
|
title="Pan down"
|
||||||
|
aria-label="Pan down"
|
||||||
|
@click="panDown"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="M17.65 12L12.25 16.5L6.85 12" />
|
||||||
|
<path d="M17.65 7L12.25 11.5L6.85 7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="mz-btn"
|
||||||
|
type="button"
|
||||||
|
title="Pan left"
|
||||||
|
aria-label="Pan left"
|
||||||
|
@click="panLeft"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="M7 11.75L11.5 17.15" />
|
||||||
|
<path d="M7 11.75L11.5 6.35" />
|
||||||
|
<path d="M12 11.75L16.5 17.15" />
|
||||||
|
<path d="M12 11.75L16.5 6.35" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="mz-btn"
|
||||||
|
type="button"
|
||||||
|
title="Pan right"
|
||||||
|
aria-label="Pan right"
|
||||||
|
@click="panRight"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="M16 11.75L11.5 17.15" />
|
||||||
|
<path d="M16 11.75L11.5 6.35" />
|
||||||
|
<path d="M11 11.75L6.5 17.15" />
|
||||||
|
<path d="M11 11.75L6.5 6.35" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="mz-btn"
|
||||||
|
type="button"
|
||||||
|
title="Close"
|
||||||
|
aria-label="Close"
|
||||||
|
@click="close"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="M19 5L5 19" />
|
||||||
|
<path d="M5 5L19 19" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ref="contentRef" class="mz-canvas" v-html="svgHtml" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.mz-overlay {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 20px;
|
||||||
|
backdrop-filter: blur(2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mz-box {
|
||||||
|
position: relative;
|
||||||
|
width: min(1200px, 96vw);
|
||||||
|
height: min(900px, 92vh);
|
||||||
|
background: var(--vp-c-bg, #fff);
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid var(--vp-c-divider, #eee);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mz-toolbar {
|
||||||
|
position: absolute;
|
||||||
|
top: 12px;
|
||||||
|
right: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 6px;
|
||||||
|
border: 1px solid var(--vp-c-divider, #ddd);
|
||||||
|
border-radius: 10px;
|
||||||
|
background: color-mix(in srgb, var(--vp-c-bg, #fff) 85%, transparent);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mz-btn {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--vp-c-text-1, #333);
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
transition:
|
||||||
|
background-color 0.2s,
|
||||||
|
color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mz-btn:hover {
|
||||||
|
background-color: var(--vp-c-bg-soft, #f4f4f4);
|
||||||
|
color: var(--vp-c-brand, #3451b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mz-btn:active {
|
||||||
|
background-color: var(--vp-c-bg-mute, #e2e2e2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mz-canvas {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background-image: radial-gradient(
|
||||||
|
var(--vp-c-divider, #e5e5e5) 1px,
|
||||||
|
transparent 1px
|
||||||
|
);
|
||||||
|
background-size: 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mz-canvas :deep(svg) {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: block;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
max-width: none !important;
|
||||||
|
max-height: none !important;
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mz-canvas :deep(svg:active) {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -12,6 +12,7 @@ import { h } from "vue"
|
|||||||
import TranslationNotice from "./components/TranslationNotice.vue"
|
import TranslationNotice from "./components/TranslationNotice.vue"
|
||||||
import PageContributors from "./components/PageContributors.vue"
|
import PageContributors from "./components/PageContributors.vue"
|
||||||
import BackToTop from "./components/BackToTop.vue"
|
import BackToTop from "./components/BackToTop.vue"
|
||||||
|
import MermaidZoom from "./components/MermaidZoom.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
extends: DefaultTheme,
|
extends: DefaultTheme,
|
||||||
@@ -35,7 +36,7 @@ export default {
|
|||||||
return h(DefaultTheme.Layout, null, {
|
return h(DefaultTheme.Layout, null, {
|
||||||
"doc-before": () => h(TranslationNotice),
|
"doc-before": () => h(TranslationNotice),
|
||||||
"doc-after": () => h(PageContributors),
|
"doc-after": () => h(PageContributors),
|
||||||
"layout-bottom": () => h(BackToTop)
|
"layout-bottom": () => [h(BackToTop), h(MermaidZoom)]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
@import "./var.css";
|
@import "./var.css";
|
||||||
@import "./custom-block.css";
|
@import "./custom-block.css";
|
||||||
@import "./blockquote.css";
|
@import "./blockquote.css";
|
||||||
|
@import "./vitepress-plugin-mermaid.css";
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/* .vitepress/theme/style/vitepress-plugin-mermaid.css */
|
||||||
|
|
||||||
|
/* Fix: VitePress typography styles affect Mermaid htmlLabels and clip last line */
|
||||||
|
.vp-doc .mermaid svg foreignObject p {
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
line-height: 1.2 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In some cases, the default overflow setting for foreignObjects may cause clipping, so I'll go ahead and disable it */
|
||||||
|
.vp-doc .mermaid svg foreignObject > div {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
text-align: center !important;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-doc .mermaid svg {
|
||||||
|
cursor: zoom-in;
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"medium-zoom": "^1.1.0",
|
"medium-zoom": "^1.1.0",
|
||||||
"mermaid": "^11.12.2",
|
"mermaid": "^11.12.2",
|
||||||
|
"svg-pan-zoom": "^3.6.2",
|
||||||
"vitepress": "2.0.0-alpha.15",
|
"vitepress": "2.0.0-alpha.15",
|
||||||
"vitepress-plugin-llms": "^1.10.0",
|
"vitepress-plugin-llms": "^1.10.0",
|
||||||
"vitepress-plugin-mermaid": "^2.0.17"
|
"vitepress-plugin-mermaid": "^2.0.17"
|
||||||
|
|||||||
Generated
+8
@@ -14,6 +14,9 @@ importers:
|
|||||||
mermaid:
|
mermaid:
|
||||||
specifier: ^11.12.2
|
specifier: ^11.12.2
|
||||||
version: 11.12.2
|
version: 11.12.2
|
||||||
|
svg-pan-zoom:
|
||||||
|
specifier: ^3.6.2
|
||||||
|
version: 3.6.2
|
||||||
vitepress:
|
vitepress:
|
||||||
specifier: 2.0.0-alpha.15
|
specifier: 2.0.0-alpha.15
|
||||||
version: 2.0.0-alpha.15(postcss@8.5.6)
|
version: 2.0.0-alpha.15(postcss@8.5.6)
|
||||||
@@ -1320,6 +1323,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==}
|
resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
|
svg-pan-zoom@3.6.2:
|
||||||
|
resolution: {integrity: sha512-JwnvRWfVKw/Xzfe6jriFyfey/lWJLq4bUh2jwoR5ChWQuQoOH8FEh1l/bEp46iHHKHEJWIyFJETbazraxNWECg==}
|
||||||
|
|
||||||
tabbable@6.3.0:
|
tabbable@6.3.0:
|
||||||
resolution: {integrity: sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==}
|
resolution: {integrity: sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==}
|
||||||
|
|
||||||
@@ -2898,6 +2904,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
copy-anything: 4.0.5
|
copy-anything: 4.0.5
|
||||||
|
|
||||||
|
svg-pan-zoom@3.6.2: {}
|
||||||
|
|
||||||
tabbable@6.3.0: {}
|
tabbable@6.3.0: {}
|
||||||
|
|
||||||
tinyexec@1.0.2: {}
|
tinyexec@1.0.2: {}
|
||||||
|
|||||||
Reference in New Issue
Block a user