entari-plugin-hyw 2.2.5__py3-none-any.whl → 3.5.0rc6__py3-none-any.whl
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.
- entari_plugin_hyw/__init__.py +371 -315
- entari_plugin_hyw/assets/card-dist/index.html +396 -0
- entari_plugin_hyw/assets/card-dist/logos/anthropic.svg +1 -0
- entari_plugin_hyw/assets/card-dist/logos/cerebras.svg +9 -0
- entari_plugin_hyw/assets/card-dist/logos/deepseek.png +0 -0
- entari_plugin_hyw/assets/card-dist/logos/gemini.svg +1 -0
- entari_plugin_hyw/assets/card-dist/logos/google.svg +1 -0
- entari_plugin_hyw/assets/card-dist/logos/grok.png +0 -0
- entari_plugin_hyw/assets/card-dist/logos/huggingface.png +0 -0
- entari_plugin_hyw/assets/card-dist/logos/microsoft.svg +15 -0
- entari_plugin_hyw/assets/card-dist/logos/minimax.png +0 -0
- entari_plugin_hyw/assets/card-dist/logos/mistral.png +0 -0
- entari_plugin_hyw/assets/card-dist/logos/nvida.png +0 -0
- entari_plugin_hyw/assets/card-dist/logos/openai.svg +1 -0
- entari_plugin_hyw/assets/card-dist/logos/openrouter.png +0 -0
- entari_plugin_hyw/assets/card-dist/logos/perplexity.svg +24 -0
- entari_plugin_hyw/assets/card-dist/logos/qwen.png +0 -0
- entari_plugin_hyw/assets/card-dist/logos/xai.png +0 -0
- entari_plugin_hyw/assets/card-dist/logos/xiaomi.png +0 -0
- entari_plugin_hyw/assets/card-dist/logos/zai.png +0 -0
- entari_plugin_hyw/assets/card-dist/vite.svg +1 -0
- entari_plugin_hyw/assets/icon/anthropic.svg +1 -0
- entari_plugin_hyw/assets/icon/cerebras.svg +9 -0
- entari_plugin_hyw/assets/icon/deepseek.png +0 -0
- entari_plugin_hyw/assets/icon/gemini.svg +1 -0
- entari_plugin_hyw/assets/icon/google.svg +1 -0
- entari_plugin_hyw/assets/icon/grok.png +0 -0
- entari_plugin_hyw/assets/icon/huggingface.png +0 -0
- entari_plugin_hyw/assets/icon/microsoft.svg +15 -0
- entari_plugin_hyw/assets/icon/minimax.png +0 -0
- entari_plugin_hyw/assets/icon/mistral.png +0 -0
- entari_plugin_hyw/assets/icon/nvida.png +0 -0
- entari_plugin_hyw/assets/icon/openai.svg +1 -0
- entari_plugin_hyw/assets/icon/openrouter.png +0 -0
- entari_plugin_hyw/assets/icon/perplexity.svg +24 -0
- entari_plugin_hyw/assets/icon/qwen.png +0 -0
- entari_plugin_hyw/assets/icon/xai.png +0 -0
- entari_plugin_hyw/assets/icon/xiaomi.png +0 -0
- entari_plugin_hyw/assets/icon/zai.png +0 -0
- entari_plugin_hyw/card-ui/.gitignore +24 -0
- entari_plugin_hyw/card-ui/README.md +5 -0
- entari_plugin_hyw/card-ui/index.html +16 -0
- entari_plugin_hyw/card-ui/package-lock.json +2342 -0
- entari_plugin_hyw/card-ui/package.json +31 -0
- entari_plugin_hyw/card-ui/public/logos/anthropic.svg +1 -0
- entari_plugin_hyw/card-ui/public/logos/cerebras.svg +9 -0
- entari_plugin_hyw/card-ui/public/logos/deepseek.png +0 -0
- entari_plugin_hyw/card-ui/public/logos/gemini.svg +1 -0
- entari_plugin_hyw/card-ui/public/logos/google.svg +1 -0
- entari_plugin_hyw/card-ui/public/logos/grok.png +0 -0
- entari_plugin_hyw/card-ui/public/logos/huggingface.png +0 -0
- entari_plugin_hyw/card-ui/public/logos/microsoft.svg +15 -0
- entari_plugin_hyw/card-ui/public/logos/minimax.png +0 -0
- entari_plugin_hyw/card-ui/public/logos/mistral.png +0 -0
- entari_plugin_hyw/card-ui/public/logos/nvida.png +0 -0
- entari_plugin_hyw/card-ui/public/logos/openai.svg +1 -0
- entari_plugin_hyw/card-ui/public/logos/openrouter.png +0 -0
- entari_plugin_hyw/card-ui/public/logos/perplexity.svg +24 -0
- entari_plugin_hyw/card-ui/public/logos/qwen.png +0 -0
- entari_plugin_hyw/card-ui/public/logos/xai.png +0 -0
- entari_plugin_hyw/card-ui/public/logos/xiaomi.png +0 -0
- entari_plugin_hyw/card-ui/public/logos/zai.png +0 -0
- entari_plugin_hyw/card-ui/public/vite.svg +1 -0
- entari_plugin_hyw/card-ui/src/App.vue +412 -0
- entari_plugin_hyw/card-ui/src/assets/vue.svg +1 -0
- entari_plugin_hyw/card-ui/src/components/HelloWorld.vue +41 -0
- entari_plugin_hyw/card-ui/src/components/MarkdownContent.vue +386 -0
- entari_plugin_hyw/card-ui/src/components/SectionCard.vue +41 -0
- entari_plugin_hyw/card-ui/src/components/StageCard.vue +237 -0
- entari_plugin_hyw/card-ui/src/main.ts +5 -0
- entari_plugin_hyw/card-ui/src/style.css +29 -0
- entari_plugin_hyw/card-ui/src/test_regex.js +103 -0
- entari_plugin_hyw/card-ui/src/types.ts +52 -0
- entari_plugin_hyw/card-ui/tsconfig.app.json +16 -0
- entari_plugin_hyw/card-ui/tsconfig.json +7 -0
- entari_plugin_hyw/card-ui/tsconfig.node.json +26 -0
- entari_plugin_hyw/card-ui/vite.config.ts +16 -0
- entari_plugin_hyw/history.py +170 -0
- entari_plugin_hyw/image_cache.py +274 -0
- entari_plugin_hyw/misc.py +128 -0
- entari_plugin_hyw/pipeline.py +1338 -0
- entari_plugin_hyw/prompts.py +108 -0
- entari_plugin_hyw/render_vue.py +314 -0
- entari_plugin_hyw/search.py +696 -0
- entari_plugin_hyw-3.5.0rc6.dist-info/METADATA +116 -0
- entari_plugin_hyw-3.5.0rc6.dist-info/RECORD +88 -0
- entari_plugin_hyw/hyw_core.py +0 -555
- entari_plugin_hyw-2.2.5.dist-info/METADATA +0 -135
- entari_plugin_hyw-2.2.5.dist-info/RECORD +0 -6
- {entari_plugin_hyw-2.2.5.dist-info → entari_plugin_hyw-3.5.0rc6.dist-info}/WHEEL +0 -0
- {entari_plugin_hyw-2.2.5.dist-info → entari_plugin_hyw-3.5.0rc6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, computed, onMounted } from 'vue'
|
|
3
|
+
import { Icon } from '@iconify/vue'
|
|
4
|
+
|
|
5
|
+
import type { RenderData } from './types'
|
|
6
|
+
import StageCard from './components/StageCard.vue'
|
|
7
|
+
import MarkdownContent from './components/MarkdownContent.vue'
|
|
8
|
+
|
|
9
|
+
// Get icon for card type
|
|
10
|
+
const getCardIcon = (contentType?: string): string => {
|
|
11
|
+
switch (contentType) {
|
|
12
|
+
case 'summary': return 'mdi:file-document-outline'
|
|
13
|
+
case 'code': return 'mdi:code-braces'
|
|
14
|
+
case 'table': return 'mdi:table'
|
|
15
|
+
default: return 'mdi:card-outline'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Get display label for card
|
|
20
|
+
const getCardLabel = (contentType?: string, language?: string): string => {
|
|
21
|
+
switch (contentType) {
|
|
22
|
+
case 'summary': return 'Summary'
|
|
23
|
+
case 'code': return language ? language.charAt(0).toUpperCase() + language.slice(1) : 'Code'
|
|
24
|
+
case 'table': return 'Table'
|
|
25
|
+
default: return ''
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare global {
|
|
30
|
+
interface Window {
|
|
31
|
+
RENDER_DATA: RenderData
|
|
32
|
+
updateRenderData: (data: RenderData) => void
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const data = ref<RenderData | null>(null)
|
|
37
|
+
|
|
38
|
+
// Expose update method for Python to call
|
|
39
|
+
window.updateRenderData = (newData: RenderData) => {
|
|
40
|
+
data.value = newData
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const numSearchRefs = computed(() => data.value?.references?.length || 0)
|
|
44
|
+
const numPageRefs = computed(() => data.value?.page_references?.length || 0)
|
|
45
|
+
|
|
46
|
+
// Calculate the reference offset for each stage (for unified badge numbering)
|
|
47
|
+
const getRefOffset = (stageIndex: number): number => {
|
|
48
|
+
if (!data.value?.stages) return 0
|
|
49
|
+
let offset = 0
|
|
50
|
+
for (let i = 0; i < stageIndex; i++) {
|
|
51
|
+
const stage = data.value.stages[i]
|
|
52
|
+
if (stage) {
|
|
53
|
+
offset += (stage.references?.length || 0) + (stage.crawled_pages?.length || 0)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return offset
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Helper: Strips content before the first H1 heading (e.g., AI "thought" prefixes)
|
|
60
|
+
const stripPrefixBeforeH1 = (text: string): string => {
|
|
61
|
+
// Find the first line starting with "# " (H1)
|
|
62
|
+
const h1Match = text.match(/^#\s+/m)
|
|
63
|
+
if (h1Match && h1Match.index !== undefined) {
|
|
64
|
+
// If found, return everything starting from that H1
|
|
65
|
+
// This effectively discards any "thought" blocks or "### ASSISTANT" prefixes appearing before it.
|
|
66
|
+
return text.substring(h1Match.index)
|
|
67
|
+
}
|
|
68
|
+
// If no H1 found, return text as-is (fallback)
|
|
69
|
+
return text
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const mainTitle = computed(() => {
|
|
73
|
+
const md = stripPrefixBeforeH1(data.value?.markdown || '')
|
|
74
|
+
const match = md.match(/^#\s+(.+)$/m)
|
|
75
|
+
return match && match[1] ? match[1].trim() : ''
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
// Process title to support <u> underline tags
|
|
79
|
+
const processedTitle = computed(() => {
|
|
80
|
+
return mainTitle.value.replace(/<u>([^<]*)<\/u>/g, (_, content) => {
|
|
81
|
+
return `<span class="underline decoration-[5px] underline-offset-8" style="text-decoration-color: var(--theme-color)">${content}</span>`
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
const dedent = (text: string) => {
|
|
89
|
+
const lines = text.split('\n')
|
|
90
|
+
// Find minimum indentation of non-empty lines
|
|
91
|
+
let minIndent = Infinity
|
|
92
|
+
for (const line of lines) {
|
|
93
|
+
if (line.trim().length === 0) continue
|
|
94
|
+
const leadingSpace = line.match(/^\s*/)?.[0].length || 0
|
|
95
|
+
if (leadingSpace < minIndent) minIndent = leadingSpace
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (minIndent === Infinity || minIndent === 0) return text
|
|
99
|
+
|
|
100
|
+
return lines.map(line => {
|
|
101
|
+
if (line.trim().length === 0) return ''
|
|
102
|
+
return line.substring(minIndent)
|
|
103
|
+
}).join('\n')
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
const themeColor = computed(() => data.value?.theme_color || '#ef4444')
|
|
108
|
+
|
|
109
|
+
// Calculate relative luminance to determine if color is light or dark
|
|
110
|
+
const getLuminance = (hex: string): number => {
|
|
111
|
+
const match = hex.replace('#', '').match(/.{2}/g)
|
|
112
|
+
if (!match) return 0
|
|
113
|
+
const [r, g, b] = match.map(x => {
|
|
114
|
+
const c = parseInt(x, 16) / 255
|
|
115
|
+
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
|
|
116
|
+
})
|
|
117
|
+
return 0.2126 * (r ?? 0) + 0.7152 * (g ?? 0) + 0.0722 * (b ?? 0)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Auto text color: dark text on light bg, white text on dark bg
|
|
121
|
+
const headerTextColor = computed(() => {
|
|
122
|
+
const luminance = getLuminance(themeColor.value)
|
|
123
|
+
return luminance > 0.4 ? '#1f2937' : '#ffffff' // gray-800 or white
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
const themeStyle = computed(() => ({
|
|
127
|
+
'--theme-color': themeColor.value,
|
|
128
|
+
'--header-text-color': headerTextColor.value,
|
|
129
|
+
'--text-primary': '#2c2c2e', // Warm dark gray for headings (Apple HIG inspired)
|
|
130
|
+
'--text-body': '#3a3a3c', // Softer reading color for body text
|
|
131
|
+
'--text-muted': '#636366', // Muted secondary text
|
|
132
|
+
'--border-color': '#e5e7eb', // gray-200, for borders
|
|
133
|
+
'--bg-subtle': '#f9fafb' // gray-50, for subtle backgrounds
|
|
134
|
+
}))
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
const parsedSections = computed(() => {
|
|
138
|
+
const rawMd = data.value?.markdown || ''
|
|
139
|
+
if (!rawMd) return []
|
|
140
|
+
|
|
141
|
+
// Robustness: Strip any content (AI thoughts, system role prefixes) before the first H1 heading
|
|
142
|
+
// User request: "Match the first big header, ignore what comes before it" ("匹配第一个大标题 无视前面的")
|
|
143
|
+
const md = stripPrefixBeforeH1(rawMd)
|
|
144
|
+
|
|
145
|
+
let content = md.replace(/^#\s+.+$/m, '')
|
|
146
|
+
content = content.replace(/(?:^|\n)\s*(?:#{1,3}|\*\*)\s*(?:References|Citations|Sources)[\s\S]*$/i, '')
|
|
147
|
+
content = content.trim()
|
|
148
|
+
|
|
149
|
+
const sections: Array<{ type: 'markdown' | 'card', content: string, title?: string, contentType?: 'table' | 'code' | 'summary', language?: string }> = []
|
|
150
|
+
|
|
151
|
+
// Combine regex involves complexity, so we'll use a tokenizer approach
|
|
152
|
+
// split tokens by Code Block or Table
|
|
153
|
+
// split tokens by Code Block or Table or Summary
|
|
154
|
+
const combinedRegex = /(```[\s\S]*?```|((?:^|\n)\|[^\n]*\|(?:\n\|[^\n]*\|)*)|<summary>[\s\S]*?<\/summary>)/
|
|
155
|
+
|
|
156
|
+
let remaining = content
|
|
157
|
+
|
|
158
|
+
while (remaining) {
|
|
159
|
+
const match = remaining.match(combinedRegex)
|
|
160
|
+
if (!match) {
|
|
161
|
+
if (remaining.trim()) {
|
|
162
|
+
sections.push({ type: 'markdown', content: remaining.trim() })
|
|
163
|
+
}
|
|
164
|
+
break
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const index = match.index!
|
|
168
|
+
const matchedStr = match[0]
|
|
169
|
+
const preText = remaining.substring(0, index)
|
|
170
|
+
|
|
171
|
+
if (preText.trim()) {
|
|
172
|
+
sections.push({ type: 'markdown', content: preText.trim() })
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Determine type
|
|
176
|
+
const isCode = matchedStr.startsWith('```')
|
|
177
|
+
const isSummary = matchedStr.startsWith('<summary>')
|
|
178
|
+
// Tables might match with a leading newline, trim it for checking but render carefully
|
|
179
|
+
const isTable = !isCode && !isSummary && matchedStr.trim().startsWith('|')
|
|
180
|
+
|
|
181
|
+
if (isCode || isTable || isSummary) {
|
|
182
|
+
let language = ''
|
|
183
|
+
let content = matchedStr.trim()
|
|
184
|
+
|
|
185
|
+
if (isCode) {
|
|
186
|
+
const match = matchedStr.match(/^```(\w+)/)
|
|
187
|
+
if (match && match[1]) language = match[1]
|
|
188
|
+
} else if (isSummary) {
|
|
189
|
+
// Strip tags
|
|
190
|
+
content = content.replace(/^<summary>/, '').replace(/<\/summary>$/, '')
|
|
191
|
+
content = dedent(content)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
sections.push({
|
|
195
|
+
type: 'card',
|
|
196
|
+
title: isCode ? 'Code' : (isSummary ? 'Summary' : 'Table'),
|
|
197
|
+
content: content,
|
|
198
|
+
contentType: isCode ? 'code' : (isSummary ? 'summary' : 'table'),
|
|
199
|
+
language: language
|
|
200
|
+
})
|
|
201
|
+
} else {
|
|
202
|
+
// Should not happen if regex is correct, but safe fallback
|
|
203
|
+
sections.push({ type: 'markdown', content: matchedStr })
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
remaining = remaining.substring(index + matchedStr.length)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return sections
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
onMounted(() => {
|
|
213
|
+
if (window.RENDER_DATA && Object.keys(window.RENDER_DATA).length > 0) {
|
|
214
|
+
data.value = window.RENDER_DATA
|
|
215
|
+
} else {
|
|
216
|
+
// Demo data for development preview
|
|
217
|
+
data.value = {
|
|
218
|
+
markdown: `# 终极硬核整合包格雷科技新视野
|
|
219
|
+
|
|
220
|
+
<summary>
|
|
221
|
+
《格雷科技:新视野》(GregTech: New Horizons,简称 GTNH)是一款基于 Minecraft 1.7.10 版本的深度硬核科技向整合包。它以 GregTech 5 Unofficial 为核心,通过超过 8 年的持续开发,将 300 多个模组深度集成,构建了极其严苛且逻辑严密的科技树,是公认的生存挑战巅峰之作。
|
|
222
|
+
</summary>
|
|
223
|
+
|
|
224
|
+
## 核心机制与游戏体验
|
|
225
|
+
GTNH 的核心在于"格雷化"改造,几乎所有模组的合成表都经过重新设计,以匹配其严苛的阶级制度 [4][8]。玩家需要从原始的石器时代开始,历经蒸汽时代、电力时代,最终向星际航行迈进。其游戏过程极其漫长,旨在让玩家在每一毫秒的进度中感受工业发展的成就感 [3][7]。
|
|
226
|
+
|
|
227
|
+

|
|
228
|
+
|
|
229
|
+
## 科技阶层与任务系统
|
|
230
|
+
整合包拥有 15 个清晰的科技等级(Tiers),最终目标是建造"星门"(Stargate)[2]。为了引导玩家不迷失在复杂的工业流程中,GTNH 内置了超过 3900 条任务的巨型任务书,涵盖了从基础生存到高阶多方块结构的详细指导 [4][7]。
|
|
231
|
+
|
|
232
|
+
- 15 个科技等级
|
|
233
|
+
- 任务数量:3900+
|
|
234
|
+
- 最终目标:建造"星门"
|
|
235
|
+
|
|
236
|
+
> 机动战士高达系列是日本动画史上最具影响力的动画作品之一,深受全球观众的喜爱。
|
|
237
|
+
|
|
238
|
+
| 特性 | 详细描述 |
|
|
239
|
+
| :--- | :--- |
|
|
240
|
+
| **基础版本** | Minecraft 1.7.10 (高度优化) |
|
|
241
|
+
| **任务数量** | 3900+ 任务引导 [7] |
|
|
242
|
+
| **科技阶层** | 15 个技术等级 [2] |
|
|
243
|
+
| **核心模组** | GregTech 5 Unofficial, Thaumcraft 等 [8] |
|
|
244
|
+
|
|
245
|
+
## 安装与运行建议
|
|
246
|
+
由于其高度集成的特性,官方强烈建议使用 **Prism Launcher** 进行安装和管理 [5]。在运行环境方面,虽然基于旧版 MC,但通过社区努力,目前推荐使用 **Java 17-25** 版本以获得最佳的内存管理和性能优化,确保大型自动化工厂运行流畅 [5]。
|
|
247
|
+
|
|
248
|
+
\`\`\`bash
|
|
249
|
+
curl -s https://raw.githubusercontent.com/GTNewHorizons/GT-New-Horizons-Modpack/master/README.md
|
|
250
|
+
java -version
|
|
251
|
+
java -Xmx1024M -Xms1024M -jar prism-launcher.jar
|
|
252
|
+
\`\`\``,
|
|
253
|
+
total_time: 8.5,
|
|
254
|
+
stages: [
|
|
255
|
+
{
|
|
256
|
+
name: 'instruct',
|
|
257
|
+
model: 'qwen/qwen3-235b-a22b-2507',
|
|
258
|
+
provider: 'Qwen',
|
|
259
|
+
time: 1.83,
|
|
260
|
+
cost: 0.0002,
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: 'search',
|
|
264
|
+
model: '',
|
|
265
|
+
provider: '',
|
|
266
|
+
time: 0.5,
|
|
267
|
+
cost: 0.0,
|
|
268
|
+
references: [
|
|
269
|
+
{ title: 'GTNH 2025 Server Information', url: 'https://stonelegion.com/mc-gtnh-2026/' },
|
|
270
|
+
{ title: 'GT New Horizons Wiki', url: 'https://gtnh.miraheze.org/wiki/Main_Page' },
|
|
271
|
+
{ title: 'GT New Horizons - GitHub', url: 'https://github.com/GTNewHorizons/GT-New-Horizons-Modpack' },
|
|
272
|
+
{ title: 'GT New Horizons - CurseForge', url: 'https://www.curseforge.com/minecraft/modpacks/gt-new-horizons' },
|
|
273
|
+
{ title: 'Installing and Migrating - GTNH', url: 'https://gtnh.miraheze.org/wiki/Installing_and_Migrating' },
|
|
274
|
+
{ title: 'Modlist - GT New Horizons', url: 'https://wiki.gtnewhorizons.com/wiki/Modlist' },
|
|
275
|
+
{ title: 'GregTech: New Horizons - Home', url: 'https://www.gtnewhorizons.com/' },
|
|
276
|
+
{ title: 'GT New Horizons - FTB Wiki', url: 'https://ftb.fandom.com/wiki/GT_New_Horizons' }
|
|
277
|
+
],
|
|
278
|
+
image_references: [
|
|
279
|
+
{ title: 'GTNH Live Lets Play', url: 'https://i.ytimg.com/vi/5T-oSWAgaMM/maxresdefault.jpg', thumbnail: 'https://tse4.mm.bing.net/th/id/OIP.b_56VnY4nyrzeqp1JetmFQHaEK?pid=Api' },
|
|
280
|
+
{ title: 'GTNH Modpack Cover', url: 'https://i.mcmod.cn/modpack/cover/20240113/1705139595_29797_dSkE.jpg', thumbnail: 'https://tse1.mm.bing.net/th/id/OIP.KNKaZX1d_4Ueq6vpl1qJNAHaEo?pid=Api' },
|
|
281
|
+
{ title: 'GTNH Steam Age', url: 'https://i.ytimg.com/vi/8IPwXxqB71w/maxresdefault.jpg', thumbnail: 'https://tse4.mm.bing.net/th/id/OIP.P-KrnI4GBH21yPgwpNPSzAHaEK?pid=Api' },
|
|
282
|
+
{ title: 'GTNH MCMod Cover', url: 'https://i.mcmod.cn/post/cover/20230201/1675241030_2_VqDc.jpg', thumbnail: 'https://tse2.mm.bing.net/th/id/OIP.GvYz7YWrg-fnpAHjOiW3OAHaEo?pid=Api' },
|
|
283
|
+
{ title: 'GTNH Tectech Tutorial', url: 'http://i0.hdslb.com/bfs/archive/1ed1e53341fd44018138f2823b2fe6c499fb9c9c.jpg', thumbnail: 'https://tse4.mm.bing.net/th/id/OIP.0Wg7xFHTjhxIV9hKuUo4xwHaEo?pid=Api' }
|
|
284
|
+
]
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: 'crawler',
|
|
288
|
+
model: '',
|
|
289
|
+
provider: '',
|
|
290
|
+
time: 2.5,
|
|
291
|
+
cost: 0.0,
|
|
292
|
+
crawled_pages: [
|
|
293
|
+
{ title: 'GregTech: New Horizons Official Wiki', url: 'https://gtnh.miraheze.org/wiki/Main_Page' },
|
|
294
|
+
{ title: 'GT New Horizons Modpack Download', url: 'https://www.curseforge.com/minecraft/modpacks/gt-new-horizons' },
|
|
295
|
+
{ title: 'Installing and Migrating Guide', url: 'https://gtnh.miraheze.org/wiki/Installing_and_Migrating' }
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: 'agent',
|
|
300
|
+
model: 'google/gemini-3-flash-preview',
|
|
301
|
+
provider: 'Google',
|
|
302
|
+
time: 13.0,
|
|
303
|
+
cost: 0.0018,
|
|
304
|
+
}
|
|
305
|
+
],
|
|
306
|
+
references: [
|
|
307
|
+
{ title: 'GTNH 2025 Server Information', url: 'https://stonelegion.com/mc-gtnh-2026/' },
|
|
308
|
+
{ title: 'GT New Horizons Wiki', url: 'https://gtnh.miraheze.org/wiki/Main_Page' },
|
|
309
|
+
{ title: 'GT New Horizons - GitHub', url: 'https://github.com/GTNewHorizons/GT-New-Horizons-Modpack' },
|
|
310
|
+
{ title: 'GT New Horizons - CurseForge', url: 'https://www.curseforge.com/minecraft/modpacks/gt-new-horizons' },
|
|
311
|
+
{ title: 'Installing and Migrating - GTNH', url: 'https://gtnh.miraheze.org/wiki/Installing_and_Migrating' },
|
|
312
|
+
{ title: 'Modlist - GT New Horizons', url: 'https://wiki.gtnewhorizons.com/wiki/Modlist' },
|
|
313
|
+
{ title: 'GregTech: New Horizons - Home', url: 'https://www.gtnewhorizons.com/' },
|
|
314
|
+
{ title: 'GT New Horizons - FTB Wiki', url: 'https://ftb.fandom.com/wiki/GT_New_Horizons' }
|
|
315
|
+
],
|
|
316
|
+
page_references: [
|
|
317
|
+
{ title: 'GregTech: New Horizons Official Wiki', url: 'https://gtnh.miraheze.org/wiki/Main_Page' },
|
|
318
|
+
{ title: 'GT New Horizons Modpack Download', url: 'https://www.curseforge.com/minecraft/modpacks/gt-new-horizons' }
|
|
319
|
+
],
|
|
320
|
+
image_references: [
|
|
321
|
+
{ title: 'GTNH Live Lets Play', url: 'https://i.ytimg.com/vi/5T-oSWAgaMM/maxresdefault.jpg', thumbnail: 'https://tse4.mm.bing.net/th/id/OIP.b_56VnY4nyrzeqp1JetmFQHaEK?pid=Api' },
|
|
322
|
+
{ title: 'GTNH Modpack Cover', url: 'https://i.mcmod.cn/modpack/cover/20240113/1705139595_29797_dSkE.jpg', thumbnail: 'https://tse1.mm.bing.net/th/id/OIP.KNKaZX1d_4Ueq6vpl1qJNAHaEo?pid=Api' },
|
|
323
|
+
{ title: 'GTNH Steam Age', url: 'https://i.ytimg.com/vi/8IPwXxqB71w/maxresdefault.jpg', thumbnail: 'https://tse4.mm.bing.net/th/id/OIP.P-KrnI4GBH21yPgwpNPSzAHaEK?pid=Api' }
|
|
324
|
+
],
|
|
325
|
+
stats: { total_time: 8.5 },
|
|
326
|
+
theme_color: '#ef4444'
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
})
|
|
330
|
+
</script>
|
|
331
|
+
|
|
332
|
+
<template>
|
|
333
|
+
<div class="bg-[#f2f2f2] flex justify-center" :style="themeStyle">
|
|
334
|
+
<!-- Main container with explicit background for screenshot capture -->
|
|
335
|
+
<div id="main-container" class="w-[540px] pt-16 pb-12 space-y-8 !bg-[#f2f2f2]" data-theme="light">
|
|
336
|
+
|
|
337
|
+
<!-- Title -->
|
|
338
|
+
<header v-if="mainTitle" class="px-6 mb-8">
|
|
339
|
+
<!-- Removed Time/Icon Badge as requested -->
|
|
340
|
+
<h1 class="text-4xl font-black leading-tight tracking-tighter uppercase tabular-nums" style="color: var(--text-primary)" v-html="processedTitle"></h1>
|
|
341
|
+
</header>
|
|
342
|
+
|
|
343
|
+
<!-- Content Sections -->
|
|
344
|
+
<template v-for="(section, idx) in parsedSections" :key="idx">
|
|
345
|
+
|
|
346
|
+
<!-- Standard Markdown -->
|
|
347
|
+
<div v-if="section.type === 'markdown'" class="px-7">
|
|
348
|
+
<MarkdownContent
|
|
349
|
+
:markdown="section.content"
|
|
350
|
+
:num-search-refs="numSearchRefs"
|
|
351
|
+
:num-page-refs="numPageRefs"
|
|
352
|
+
class="prose-h2:text-[26px] prose-h2:font-black prose-h2:uppercase prose-h2:tracking-tight prose-h2:mb-4 prose-h2:text-gray-800"
|
|
353
|
+
/>
|
|
354
|
+
</div>
|
|
355
|
+
|
|
356
|
+
<!-- Special Card (Table/Code/Summary) -->
|
|
357
|
+
<div v-else-if="section.type === 'card'" class="mx-6 relative">
|
|
358
|
+
<!-- Corner Rectangle Badge with Icon and Label -->
|
|
359
|
+
<div
|
|
360
|
+
class="absolute -top-2 -left-2 h-7 px-2.5 z-10 flex items-center gap-1.5"
|
|
361
|
+
:style="{ backgroundColor: themeColor, color: headerTextColor, boxShadow: '0 2px 4px 0 rgba(0,0,0,0.15)' }"
|
|
362
|
+
>
|
|
363
|
+
<Icon :icon="getCardIcon(section.contentType)" class="text-base" />
|
|
364
|
+
<span class="text-xs font-bold uppercase tracking-wide">{{ getCardLabel(section.contentType, section.language) }}</span>
|
|
365
|
+
</div>
|
|
366
|
+
<div
|
|
367
|
+
class="shadow-sm shadow-black/10 bg-white"
|
|
368
|
+
:class="[
|
|
369
|
+
section.contentType === 'summary' ? 'pt-8 px-5 pb-3 text-base leading-relaxed' : '',
|
|
370
|
+
section.contentType === 'code' ? 'pt-7 pb-2' : '',
|
|
371
|
+
section.contentType === 'table' ? 'pt-5' : ''
|
|
372
|
+
]"
|
|
373
|
+
>
|
|
374
|
+
<MarkdownContent
|
|
375
|
+
:markdown="section.content"
|
|
376
|
+
:bare="true"
|
|
377
|
+
:num-search-refs="numSearchRefs"
|
|
378
|
+
:num-page-refs="numPageRefs"
|
|
379
|
+
/>
|
|
380
|
+
</div>
|
|
381
|
+
</div>
|
|
382
|
+
|
|
383
|
+
</template>
|
|
384
|
+
|
|
385
|
+
<!-- Workflow -->
|
|
386
|
+
<div v-if="data?.stages?.length" class="mx-6 relative">
|
|
387
|
+
<!-- Corner Rectangle Badge with Icon and Label -->
|
|
388
|
+
<div
|
|
389
|
+
class="absolute -top-2 -left-2 h-7 px-2.5 z-10 flex items-center gap-1.5"
|
|
390
|
+
:style="{ backgroundColor: themeColor, color: headerTextColor, boxShadow: '0 2px 4px 0 rgba(0,0,0,0.15)' }"
|
|
391
|
+
>
|
|
392
|
+
<Icon icon="mdi:link-variant" class="text-base" />
|
|
393
|
+
<span class="text-xs font-bold uppercase tracking-wide">Flow</span>
|
|
394
|
+
</div>
|
|
395
|
+
<div class="p-2 pt-5 bg-white shadow-sm shadow-black/10">
|
|
396
|
+
<StageCard
|
|
397
|
+
v-for="(stage, index) in data.stages"
|
|
398
|
+
:key="index"
|
|
399
|
+
:stage="stage"
|
|
400
|
+
:is-first="index === 0"
|
|
401
|
+
:is-last="index === data.stages.length - 1"
|
|
402
|
+
:prev-stage-name="index > 0 ? data.stages[index - 1]?.name : undefined"
|
|
403
|
+
:ref-offset="getRefOffset(index)"
|
|
404
|
+
/>
|
|
405
|
+
</div>
|
|
406
|
+
</div>
|
|
407
|
+
|
|
408
|
+
</div>
|
|
409
|
+
</div>
|
|
410
|
+
</template>
|
|
411
|
+
|
|
412
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
defineProps<{ msg: string }>()
|
|
5
|
+
|
|
6
|
+
const count = ref(0)
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<h1>{{ msg }}</h1>
|
|
11
|
+
|
|
12
|
+
<div class="card">
|
|
13
|
+
<button type="button" @click="count++">count is {{ count }}</button>
|
|
14
|
+
<p>
|
|
15
|
+
Edit
|
|
16
|
+
<code>components/HelloWorld.vue</code> to test HMR
|
|
17
|
+
</p>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<p>
|
|
21
|
+
Check out
|
|
22
|
+
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
|
23
|
+
>create-vue</a
|
|
24
|
+
>, the official Vue + Vite starter
|
|
25
|
+
</p>
|
|
26
|
+
<p>
|
|
27
|
+
Learn more about IDE Support for Vue in the
|
|
28
|
+
<a
|
|
29
|
+
href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
|
|
30
|
+
target="_blank"
|
|
31
|
+
>Vue Docs Scaling up Guide</a
|
|
32
|
+
>.
|
|
33
|
+
</p>
|
|
34
|
+
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<style scoped>
|
|
38
|
+
.read-the-docs {
|
|
39
|
+
color: #888;
|
|
40
|
+
}
|
|
41
|
+
</style>
|