PageSourceSearch

https://www.01.ai/assets/content/render.1.9.23165519.js

js 01.ai collected 2026-09-24 18:08:03 UTC 29,952 bytes, 525 lines download raw bytes

1/*
2 * Structural templates for content-managed pages.
3 * Keep copy in zh-CN.js and visual decisions in enterprise-theme.css.
4 */
5(() => {
6  const DIAGRAM_IMAGES_ZH = {
7    'home-ai-consult': {
8      src: 'assets/media/diagrams/home-ai-consult-diagram.1.9.23165519.webp',
9      width: 1232,
10      height: 520,
11      alt: '战略咨询与 FDE 共创架构'
12    },
13    'home-ecosystem': {
14      src: 'assets/media/diagrams/home-ecosystem-diagram.1.9.23165519.webp',
15      width: 1232,
16      height: 566,
17      alt: '零一万物生态矩阵——协同共赢,价值倍增'
18    }
19  };
20  const DIAGRAM_IMAGES_EN = {
21    'home-ai-consult': {
22      src: 'assets/media/diagrams/home-ai-consult-diagram-en.1.9.23165519.webp',
23      width: 1232,
24      height: 560,
25      alt: 'Strategy Advisory and FDE co-creation architecture'
26    },
27    'home-ecosystem': {
28      src: 'assets/media/diagrams/home-ecosystem-diagram-en.1.9.23165519.webp',
29      width: 1232,
30      height: 610,
31      alt: '01.AI Ecosystem Partnership — Co-develop solutions. Co-create value.'
32    }
33  };
34  const isEnglishSite = (document.documentElement.lang || '').toLowerCase().startsWith('en');
35  const defaultDiagramImages = isEnglishSite ? DIAGRAM_IMAGES_EN : DIAGRAM_IMAGES_ZH;
36
37  const mount = document.querySelector('[data-content-page]');
38  const site = window.OAI_SITE_CONTENT;
39  if (!mount || !site) return;
40
41  const pageKey = mount.dataset.contentPage;
42  const page = site[pageKey];
43  const shared = site.shared;
44  if (!page) return;
45  document.body.classList.add(`content-page-${pageKey}`);
46
47  const basePath = window.OAI_SITE_BASE_PATH || '';
48  const asset = (path) => {
49    if (!path) return '';
50    if (/^(?:https?:|mailto:|tel:|#|\/)/.test(path) || path.startsWith('../')) return path;
51    return `${basePath}${path}`;
52  };
53  const diagramImage = (id, className = 'diagram-export reveal d1') => {
54    const registry = window.OAI_DIAGRAM_IMAGES || defaultDiagramImages;
55    const item = registry[id];
56    if (!item) return '';
57    return `<div class="${className}"><img src="${escape(asset(item.src))}" alt="${escape(item.alt)}" width="${item.width}" height="${item.height}" loading="lazy"></div>`;
58  };
59  const escape = (value) => String(value).replace(/[&<>"']/g, (character) => ({
60    '&': '&amp;',
61    '<': '&lt;',
62    '>': '&gt;',
63    '"': '&quot;',
64    "'": '&#39;'
65  }[character]));
66  const multiline = (value) => escape(value).replace(/\n/g, '<br>');
67  const segments = (items) => items.map((item) =>
68    item.accent ? `<em>${escape(item.text)}</em>` : escape(item.text)
69  ).join('');
70  const heroDescription = (value) =>
71    escape(value).replace(/一号位工程/g, '<span class="hero-sub-highlight">一号位工程</span>');
72  const arrow = window.OAI_ICON ? window.OAI_ICON('oai-arrow-right', 'sm') : '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>';
73  const arrowLeft = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M19 12H5M12 5l-7 7 7 7"/></svg>';
74  const icon = (id) => (window.OAI_ICON ? window.OAI_ICON(id, 'lg') : '');
75  const solutionIcons = ['oai-layout-dashboard', 'oai-landmark', 'oai-handshake'];
76  const valueIcons = ['oai-target', 'oai-boxes', 'oai-rocket', 'oai-refresh-cw'];
77  const external = (item) => item.external ? ' target="_blank" rel="noopener" class="external"' : '';
78  const button = (item, kind) =>
79    `<a href="${escape(item.href)}" class="btn ${kind}${item.external ? ' external' : ''}"${item.external ? ' target="_blank" rel="noopener"' : ''}>${escape(item.label)}${kind !== 'btn-accent' ? arrow : ''}</a>`;
80  const currentYear = () => String(new Date().getFullYear());
81  const formatCopyright = (value) =>
82    escape(String(value).replace(/\{year\}/g, currentYear()));
83  const logoMarkup = () => `<img class="nav-logo-img" src="${escape(asset(shared.logo || 'branding/logo.png'))}" alt="01.AI">`;
84
85  function navigation(active, dark) {
86    const language = shared.language || {};
87    const languageHref = language[pageKey] || language.default || `en/${pageKey === 'home' ? 'index' : 'enterprise'}.html`;
88    const languageLabel = language.label || 'EN';
89    const languageAria = language.aria || 'Switch language';
90    const languageLink = `<a href="${escape(languageHref)}" class="nav-lang" aria-label="${escape(languageAria)}">${escape(languageLabel)}</a>`;
91    const drawerLanguageLink = `<a href="${escape(languageHref)}" class="nav-drawer-lang" aria-label="${escape(languageAria)}">${escape(languageLabel)}</a>`;
92    const linkAttrs = (item) => item.external ? ' target="_blank" rel="noopener"' : '';
93    const productSeries = (series) => series.clickable === false
94      ? `<span class="product-menu-series is-static" aria-disabled="true"><strong>${escape(series.label)}</strong></span>`
95      : `<a href="${escape(series.href)}
95" class="product-menu-series"${linkAttrs(series)}><strong>${escape(series.label)}</strong></a>`;
96    const drawerSeries = (series) => series.clickable === false
97      ? `<span class="drawer-series is-static" aria-disabled="true">${escape(series.label)}</span>`
98      : `<a href="${escape(series.href)}" class="drawer-series"${linkAttrs(series)}>${escape(series.label)}</a>`;
99    const productMenu = (menu) => menu.map((series) => `
100      <section class="product-menu-group">
101        ${productSeries(series)}
102        ${(series.children || []).length ? `<div class="product-menu-children">
103          ${(series.children || []).map((link) => `
104            <a href="${escape(link.href)}" class="product-menu-child"${linkAttrs(link)}>
105              <strong>${escape(link.label)}</strong>
106            </a>
107          `).join('')}
108        </div>` : ''}
109      </section>
110    `).join('');
111    const navigation = shared.nav.map((item) => {
112      const menu = item.menu && shared[item.menu];
113      if (menu && menu.length) {
114        const isProductMenu = item.menu === 'productMenu';
115        const dropLinks = isProductMenu
116          ? productMenu(menu)
117          : menu.map((link) => `<a href="${escape(link.href)}"${linkAttrs(link)}>${escape(link.label)}</a>`).join('');
118        const triggerClass = `${active === item.key ? 'active ' : ''}primary nav-trigger`;
119        const trigger = item.href && item.href !== '#'
120          ? `<a href="${escape(item.href)}" class="${triggerClass}" aria-haspopup="true">${escape(item.label)}</a>`
121          : `<button type="button" class="${triggerClass}" aria-haspopup="true">${escape(item.label)}</button>`;
122        return `<div class="nav-dd${isProductMenu ? ' product-nav-dd' : ''}">${trigger}<div class="nav-dd-panel${isProductMenu ? ' nav-product-panel' : ''}">${dropLinks}</div></div>`;
123      }
124      return `<a href="${escape(item.href)}"${active === item.key ? ' class="active"' : ''}>${escape(item.label)}</a>`;
125    }).join('');
126    const drawer = shared.nav.map((item) => {
127      if (item.menu === 'productMenu') {
128        const productRoot = item.href && item.href !== '#'
129          ? `<a href="${escape(item.href)}" class="drawer-series">${escape(item.label)}</a>`
130          : '';
131        return `${productRoot}${shared[item.menu].map((series) => `
132          ${drawerSeries(series)}
133          ${(series.children || []).map((link) => `<a href="${escape(link.href)}" class="drawer-sub"${linkAttrs(link)}>${escape(link.label)}</a>`).join('')}
134        `).join('')}`;
135      }
136      if (item.menu === 'caseMenu') {
137        const caseSeries = item.href && item.href !== '#'
138          ? `<a href="${escape(item.href)}" class="drawer-series">${escape(item.label)}</a>`
139          : `<a class="drawer-series is-static" aria-disabled="true">${escape(item.label)}</a>`;
140        return `${caseSeries}
141          ${shared[item.menu].map((link) => `<a href="${escape(link.href)}" class="drawer-sub">${escape(link.label)}</a>`).join('')}`;
142      }
143      if (item.menu && shared[item.menu]) {
144        const genericSeries = item.href && item.href !== '#'
145          ? `<a href="${escape(item.href)}" class="drawer-series">${escape(item.label)}</a>`
146          : `<a class="drawer-series is-static" aria-disabled="true">${escape(item.label)}</a>`;
147        return `${genericSeries}
148          ${shared[item.menu].map((link) => `<a href="${escape(link.href)}" class="drawer-sub"${linkAttrs(link)}>${escape(link.label)}</a>`).join('')}`;
149      }
150      return `<a href="${escape(item.href)}">${escape(item.label)}</a>`;
151    }).join('');
152    return `
153      <nav class="nav${dark ? ' on-dark' : ''}" id="nav">
154        <div class="nav-left"><a href="${escape(shared.homeHref || './')}" class="nav-logo">${logoMarkup()}</a></div>
155        <div class="nav-center">${navigation}</div>
156        <div class="nav-right">${languageLink}<a href="${escape(shared.actions.demo.href)}" class="nav-cta"><span class="nav-cta-label" data-mobile-label="${escape(shared.actions.demo.mobileLabel || shared.actions.demo.label)}">${escape(shared.actions.demo.label)}</span></a><button class="nav-ham" id="ham" aria-label="${escape(shared.menuLabel || '菜单')}"><span></span><span></span><span></span></button></div>
157      </nav>
158      <div class="nav-drawer" id="drawer">${drawer}<div class="nav-drawer-foot">${drawerLanguageLink}${button(shared.actions.demo, 'btn-primary')}</div></div>`;
159  }
160
161  function announcement(content) {
162    if (!content.notice) return '';
163    return `<div class="home-announcement"><span>${escape(content.notice.label)}</span>
163<p>${escape(content.notice.text)}</p></div>`;
164  }
165
166  function footer() {
167    const columns = shared.footerColumns.map((column) => `
168      <div class="ft-col"><h5>${escape(column.label)}</h5><ul>${column.links.map((link) =>
169        `<li><a href="${escape(link.href)}"${link.businessPartnership ? ' data-business-partnership' : link.topic ? ` data-quick="${escape(link.topic)}"` : ''}${external(link)}>${escape(link.label)}</a></li>`
170      ).join('')}</ul></div>`).join('');
171    const registrations = shared.registrations.map((item) => {
172      if (typeof item === 'string') return `<span>${escape(item)}</span>`;
173      const icon = item.icon ? `<img class="ft-legal-icon" src="${escape(item.icon)}" alt="" loading="lazy">` : '';
174      return `<a href="${escape(item.href)}" target="_blank" rel="noopener">${icon}${escape(item.label)}</a>`;
175    }).join('<span>|</span>');
176    return `
177      <footer class="ft ft-compact"><div class="ft-inner"><div class="ft-grid">
178        <div class="ft-brand"><div class="nav-logo">${logoMarkup()}</div><p>${escape(shared.footerStatement)}</p></div>
179        ${columns}
180      </div><div class="ft-bottom"><div class="ft-legal"><span>${formatCopyright(shared.copyright)}</span>${registrations ? `<span>|</span>${registrations}` : ''}</div><div class="mono t-small text-on-dark-dim">${escape(shared.location)}</div></div></div></footer>`;
181  }
182
183  function hero(content, secondaryAction) {
184    const secondaryButton = secondaryAction ? button(secondaryAction, 'btn-ghost') : '';
185    const note = content.hero.ctaNote ? `<p class="hero-contact-note">${escape(content.hero.ctaNote)}</p>` : '';
186    const variant = content.page === 'home' ? ' home-hero' : '';
187    const slides = content.hero.slides || [];
188    const media = slides.length
189      ? `<div class="hero-backdrops" aria-hidden="true">${slides.map((slide, index) =>
190        `<div class="hero-backdrop${index === 0 ? ' is-active' : ''}" data-hero-backdrop="${index}"><img src="${escape(asset(slide.media))}" alt=""></div>`
191      ).join('')}<div class="hero-media-shade"></div></div>`
192      : content.hero.media ? `<div class="hero-media" aria-hidden="true"><img src="${escape(asset(content.hero.media))}" alt=""><div class="hero-media-shade"></div></div>` : '';
193    const selector = slides.length && content.page !== 'home' ? `<div class="industry-selector" aria-label="${escape(shared.industryAria || '覆盖行业场景')}">
194      <div class="industry-selector-label">${escape(shared.industryLabel || '覆盖行业')}</div>
195      <div class="industry-tabs" role="tablist">${slides.map((slide, index) =>
196        `<button class="industry-tab${index === 0 ? ' is-active' : ''}" type="button" role="tab" aria-selected="${index === 0}" tabindex="${index === 0 ? '0' : '-1'}" data-hero-slide="${index}">${escape(slide.label)}</button>`
197      ).join('')}</div>
198    </div>` : '';
199    const metrics = '';
200    const summary = content.page === 'home'
201      ? `<div class="hero-summary"><p class="hero-sub">${heroDescription(content.hero.description)}</p><div class="hero-actions">${button(shared.actions.demo, 'btn-accent')}${secondaryButton}</div>${note}</div>${selector}`
202      : `<p class="hero-sub">${escape(content.hero.description)}</p><div class="hero-actions">${button(shared.actions.demo, 'btn-accent')}${secondaryButton}</div>${note}`;
203    const eyebrow = content.page === 'home' ? '' : `<div class="eyebrow on-dark">${escape(content.eyebrow)}</div>`;
204    const scrollCue = content.page === 'home'
205      ? `<a href="#home-products" class="hero-scroll-cue" aria-label="${escape(shared.scrollCueAria || '向下浏览更多内容')}"><i aria-hidden="true"></i></a>`
206      : '';
207    return `
208      <section class="hero${variant} bg-night">${media}<div class="hero-grid"></div><div class="hero-content">
209        <div class="hero-copy">
210          ${eyebrow}
211          <h1 class="hero-display">${content.hero.lines.map((line) => `<span class="line">${segments(line)}</span>`).join('')}</h1>
212          ${summary}
213        </div>
214        ${metrics}
215      </div>${scrollCue}</section>`;
216  }
217
218  function sectionHead(content, showEyebrow = true) {
219    const eyebrow = showEyebrow ? `<div class="eyebrow">${escape(content.eyebrow)}</div>` : '';
220    const description = content.description ? `<p class="sec-head-desc">${escape(content.description)}</p>` : '';
221    return `<div class="sec-head reveal"><div class="sec-head-title">${eyebrow}<h2>${segments(content.title)}</h2></div>${description}</div>`;
222  }
223
224  function closeSection(content, surface = 'bg-paper') {
225    const note = content.note ? `<p class="final-note">${escape(content.note)}</p>` : '';
226    return `
227      <section class="section tight ${surface}"><div class="wrap"><div class="reveal centered max-xl final-cta">
228        <h2 class="t-h2">${segments(content.title)}</h2>
229        <p class="t-lead mt-5 max-md mx-auto">${escape(content.description)}</p>
230        ${note}
231        <div class="flex gap-3 justify-center fwrap mt-7">${button(shared.actions.demo, 'btn-primary')}</div>
232      </div></div></section>`;
233  }
234
235  function aiConsultSubcard(item) {
236    return `<div class="home-ai-consult-subcard">
237      <h4>${escape(item.title)}</h4>
238      <p>${escape(item.text)}</p>
239    </div>`;
240  }
241
242  function aiConsultPanel(panel) {
243    return `<article class="home-ai-consult-panel">
244      <div class="home-ai-consult-panel-head">
245        <span class="home-ai-consult-badge oai-icon-box" aria-hidden="true">${window.OAI_ICON ? window.OAI_ICON(panel.icon, 'sm') : icon(panel.icon)}</span>
246        <div>
247          <h3>${escape(panel.title)}</h3>
248          <p class="home-ai-consult-panel-tag">${escape(panel.tagline)}</p>
249        </div>
250      </div>
251      <p class="home-ai-consult-panel-lead">${escape(panel.text)}</p>
252      <div class="home-ai-consult-subcards">${panel.items.map(aiConsultSubcard).join('')}</div>
253    </article>`;
254  }
255
256  function renderAiConsultDiagramMarkup(data) {
257    const diagram = data.diagram;
258    return `
259      <div class="home-ai-consult-shell reveal d1">
260        <header class="home-ai-consult-head">
261          <div class="home-ai-consult-headline">
262            <h2>
263              <span class="home-ai-consult-title-accent">${segments(data.title)}</span>
264              <span class="home-ai-consult-title-sub">${escape(data.subtitle)}</span>
265            </h2>
266          </div>
267          <p class="home-ai-consult-intro">${escape(data.intro)}</p>
268        </header>
269        <div class="home-ai-consult-canvas" aria-label="${escape(data.ariaLabel || '战略咨询与 FDE 共创架构')}">
270          <svg class="home-ai-consult-connectors" viewBox="0 0 1200 500" preserveAspectRatio="none" aria-hidden="true">
271            <defs>
272              <linearGradient id="home-consult-flow-in" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="#315f49" stop-opacity=".28"/><stop offset=".72" stop-color="#8fe85d" stop-opacity=".82"/><stop offset="1" stop-color="#c8f64a"/></linearGradient>
273              <linearGradient id="home-consult-flow-out" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="#c8f64a"/><stop offset="1" stop-color="#5fbd62" stop-opacity=".4"/></linearGradient>
274              <linearGradient id="home-consult-flow-mid-in" gradientUnits="userSpaceOnUse" x1="286" y1="250" x2="470" y2="250"><stop offset="0" stop-color="#8fbd61" stop-opacity=".95"/><stop offset=".72" stop-color="#a8e95d"/><stop offset="1" stop-color="#c8f64a"/></linearGradient>
275              <linearGradient id="home-consult-flow-mid-out" gradientUnits="userSpaceOnUse" x1="730" y1="250" x2="914" y2="250"><stop offset="0" stop-color="#c8f64a"/><stop offset="1" stop-color="#8fbd61" stop-opacity=".95"/></linearGradient>
276              <filter id="home-consult-flow-glow" x="-30%" y="-30%" width="160%" height="160%"><feGaussianBlur stdDeviation="5" result="blur"/><feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
277            </defs>
278            <g class="flow-lines" fill="none" stroke="url(#home-consult-flow-in)" stroke-width="10" stroke-linecap="round" filter="url(#home-consult-flow-glow)">
279              <path class="flow-mid" d="M286 250 H470" stroke="url(#home-consult-flow-mid-in)"/>
280            </g>
281            <g class="flow-lines" fill="none" stroke="url(#home-consult-flow-out)" stroke-width="10" stroke-linecap="round" filter="url(#home-consult-flow-glow)">
282              <path class="flow-mid" d="M730 250 H914" stroke="url(#home-consult-flow-mid-out)"/>
283            </g>
284          </svg>
285          ${aiConsultPanel(diagram.left)}
286          <div class="home-ai-consult-center">
287            <span class="home-ai-consult-pill">${escape(diagram.center.pill)}</span>
288            <div class="home-ai-consult-ring">
289              ${diagram.center.core.map((line) => `<span>${escape(line)}</span>`).join('')}
290            </div>
291            <p class="home-ai-consult-center-note">${escape(diagram.center.note)}</p>
292          </div>
293          ${aiConsultPanel(diagram.right)}
294        </div>
295        <footer class="home-ai-consult-foot">
296          <p>${escape(data.footer)}</p>
297          ${button(shared.actions.demo, 'btn-accent')}
298        </footer>
299      </div>`;
300  }
301
302  function renderAiConsultDiagram(data) {
303    if (window.OAI_USE_DIAGRAM_IMAGES === false) {
304      return renderAiConsultDiagramMarkup(data);
305    }
306    return `
307      <div class="home-ai-consult-shell reveal d1">
308        <header class="home-ai-consult-head">
309          <div class="home-ai-consult-headline">
310            <h2>
311              <span class="home-ai-consult-title-accent">${segments(data.title)}</span>
312              <span class="home-ai-consult-title-sub">${escape(data.subtitle)}</span>
313            </h2>
314          </div>
315          <p class="home-ai-consult-intro">${escape(data.intro)}</p>
316        </header>
317        ${diagramImage('home-ai-consult')}
318        <footer class="home-ai-consult-foot">
319          <p>${escape(data.footer)}</p>
320          ${button(shared.actions.demo, 'btn-accent')}
321        </footer>
322      </div>`;
323  }
324
325  function renderEcosystemSectionMarkup(data) {
326    const partnerCard = (item) => `
327      <article class="home-ecosystem-partner home-ecosystem-partner--${escape(item.slot)}">
328        <span class="home-ecosystem-partner-icon oai-icon-box" aria-hidden="true">${window.OAI_ICON ? window.OAI_ICON(item.icon, 'md') : icon(item.icon)}</span>
329        <h3>${escape(item.title)}</h3>
330      </article>`;
331    const tierRow = (item, index) => `
332      <div class="home-ecosystem-tier-row home-ecosystem-tier-row--${index + 1}">
333        <div class="home-ecosystem-tier-bar">
334          <strong>${escape(item.name)}</strong>
335          <span>${escape(item.threshold)}</span>
336        </div>
337        <div class="home-ecosystem-tier-benefit">
338          <p>${escape(item.text)}</p>
339        </div>
340      </div>`;
341    return `
342      <div class="home-ecosystem-map reveal d1">
343        <section class="home-ecosystem-block" aria-label="${escape(data.partners.label)}">
344          <div class="home-ecosystem-block-label">${escape(data.partners.label)}</div>
345          <div class="home-ecosystem-partners-body">
346            ${data.partners.items.map(partnerCard).join('')}
347            <div class="home-ecosystem-hub">
348              ${(Array.isArray(data.partners.hub) ? data.partners.hub : [data.partners.hub]).map((line) => `<p>${escape(line)}</p>`).join('')}
349            </div>
350          </div>
351        </section>
352        <section class="home-ecosystem-block" aria-label="${escape(data.tiers.label)}">
353          <div class="home-ecosystem-block-label">${escape(data.tiers.label)}</div>
354          <div class="home-ecosystem-tiers-body">
355            ${data.tiers.items.map(tierRow).join('')}
356          </div>
357        </section>
358      </div>
359      ${data.cta ? `<div class="home-ecosystem-action reveal d2">${button(data.cta, 'btn-accent')}</div>` : ''}`;
360  }
361
362  /* Preserved markup for export regen — see renderEcosystemSectionMarkup. */
363  function renderEcosystemSection(data) {
364    if (window.OAI_USE_DIAGRAM_IMAGES === false) {
365      return renderEcosystemSectionMarkup(data);
366    }
367    return `
368      ${diagramImage('home-ecosystem')}
369      ${data.cta ? `<div class="home-ecosystem-action reveal d2">${button(data.cta, 'btn-accent')}</div>` : ''}`;
370  }
371
372  function renderHome() {
373    const solutions = page.solutions.items.map((item, index) => `
374      <article class="solution-card">
375        <span class="oai-icon-box oai-icon-box--home">${icon(solutionIcons[index])}</span>
376        <h3>${escape(item.title)}</h3>
377        <p>${escape(item.text)}</p>
378        <ul class="split-list">${item.points.map((point) => `<li>${escape(point)}</li>`).join('')}</ul>
379        <a href="${escape(item.href)}" class="solution-link">${escape(shared.productLearnMore || '了解产品')} ${arrow}</a>
380      </article>`).join('');
381    const customers = `
382      <div class="home-solution-tabs reveal d1" data-home-solution-tabs>
383        <div class="home-solution-selector industry-selector" aria-label="${escape(shared.solutionAria || '场景方案分类')}">
384          <div class="home-solution-tablist industry-tabs" role="tablist">
385            ${page.customers.items.map((item, index) => `
386              <button class="home-solution-tab industry-tab${index === 0 ? ' is-active' : ''}" type="button" role="tab" id="home-solution-tab-${index}" aria-selected="${index === 0 ? 'true' : 'false'}" aria-controls="home-solution-panel-${index}" tabindex="${index === 0 ? '0' : '-1'}" data-home-solution-tab="${index}">${escape(item.label)}</button>
387            `).join('')}
388          </div>
389        </div>
390        <div class="home-solution-panels">
391          ${page.customers.items.map((item, index) => `
392            <article class="home-solution-panel${index === 0 ? ' is-active' : ''}" role="tabpanel" id="home-solution-panel-${index}" aria-labelledby="home-solution-tab-${index}" ${index === 0 ? '' : 'hidden'} data-home-solution-panel="${index}">
393              <div class="home-solution-copy">
394                <p class="home-solution-scenario">${escape(item.label)}</p>
395                <h3>${escape(item.text)}</h3>
396                <a href="${escape(item.href)}" class="home-solution-link">${escape(shared.learnMore || '了解方案')} ${arrow}</a>
397              </div>
398              <figure class="home-solution-media">
399                <img src="${escape(asset(item.media))}" alt="${escape(item.label)}${escape(shared.solutionAltSuffix || '场景方案')}">
400              </figure>
401            </article>
402          `).join('')}
403        </div>
404      </div>`;
405    const valueItems = page.value.items.map((item, index) => `
406      <article class="ai-value-card">
407        <span class="oai-icon-box oai-icon-box--home">${icon(valueIcons[index])}</span>
408        <h3>${escape(item.title)}</h3>
409        <p>${escape(item.text)}</p>
410      </article>`).join('');
411    const newsCards = (page.news.items || []).slice(0, 3).map((item) => `
412      <a href="${escape(item.href)}" class="home-news-card"${item.external ? ' target="_blank" rel="noopener"' : ''}>
413        <figure class="home-news-thumb">
414          <img src="${escape(asset(item.media))}" alt="">
415        </figure>
416        <div class="home-news-body">
417          <h3>${escape(item.title)}</h3>
418          <p>${escape(item.date)} →</p>
419        </div>
420      </a>`).join('');
421    const aiConsultingDiagram = renderAiConsultDiagram(page.aiConsulting);
422    const aboutMilestones = page.aboutHome.milestones.map((item) => `
423      <article class="home-about-milestone">
424        <time>${escape(item.date)}</time>
425        <div>
426          <h3>${escape(item.title)}</h3>
427          <p>${escape(item.text)}</p>
428        </div>
429      </article>`).join('');
430    return `
431      ${navigation('home', true)}
432      ${hero(page)}
433      <section class="section bg-paper home-customers" id="home-products"><div class="wrap">${sectionHead(page.solutions, false)}
434        <div class="solution-grid reveal d1">${solutions}</div>
435      </div></section>
436      <section class="section bg-night home-ai-consulting" id="home-ai-consulting"><div class="wrap">${aiConsultingDiagram}</div></section>
437      <section class="section snug bg-paper home-solutions" id="home-industry-solutions"><div class="wrap">${sectionHead(page.customers, false)}
438        ${customers}
439      </div></section>
440      <section class="section bg-night home-ai-value" id="one-project"><div class="wrap">${sectionHead(page.value, false)}
441        <div class="ai-value-grid reveal d1">${valueItems}</div>
442        <div class="home-ai-value-action reveal d2"><a href="${escape(page.value.more.href)}" class="home-ai-value-more">${escape(page.value.more.label)} ${arrow}</a></div>
443      </div></section>
444      <section class="section bg-night home-news"><div class="wrap">${sectionHead(page.news, false)}
445        <div class="home-news-grid reveal d1">${newsCards}</div>
446        <div class="home-news-action reveal d2"><a href="${escape(page.news.more.href)}" class="home-news-more">${escape(page.news.more.label)} ${arrow}</a></div>
447      </div></section>
448      <section class="section tight bg-paper home-about"><div class="wrap">${sectionHead(page.aboutHome, false)}
449        <div class="home-about-layout reveal d1">
450          <div class="home-about-intro">
451            ${page.aboutHome.intro.map((text) => `<p>${escape(text)}</p>`).join('')}
452            <a href="${escape(page.aboutHome.more.href)}" class="home-about-more">${escape(page.aboutHome.more.label)} ${arrow}</a>
453          </div>
454          <div class="home-about-milestones">${aboutMilestones}</div>
455        </div>
456      </div></section>
457      ${footer()}`;
458  }
459
460  function renderEnterprise() {
461    const productVisual = (item) => `
462      <div class="product-visual product-visual-${escape(item.visual || item.id)} reveal d1" aria-label="${escape(item.name)} ${escape(shared.visualPlaceholder || '产品视觉占位')}">
463        <div class="product-visual-top">
464          <span>${escape(item.name)}</span>
465          <span>${escape(item.tagline)}</span>
466        </div>
467        <div class="product-orbit" aria-hidden="true">
468          <span class="orb orb-a"></span>
469          <span class="orb orb-b"></span>
470          <span class="orb orb-c"></span>
471          <span class="orb-center"></span>
472          <span class="orbit-line line-a"></span>
473          <span class="orbit-line line-b"></span>
474          <span class="orbit-line line-c"></span>
475        </div>
476        <div class="product-visual-bottom">
477          <span>INPUT</span>
478          <span>ANALYZE</span>
479          <span>ACT</span>
480        </div>
481      </div>`;
482    const products = page.products.map((item) => `
483      <section class="section ${item.theme === 'night' ? 'bg-night' : 'bg-paper'} enterprise-product enterprise-product-${escape(item.id)}" id="${escape(item.id)}">
484        <div class="wrap">
485          <div class="product-layout">
486            <div class="product-copy reveal">
487              <div class="eyebrow">${escape(item.eyebrow)}</div>
488              <h2>${segments(item.title)}</h2>
489              <p class="product-tagline">${escape(item.tagline)}</p>
490              <p class="product-lead">${escape(item.description)}</p>
491              <a href="${escape(item.ctaHref)}" class="btn ${item.theme === 'night' ? 'btn-primary' : 'btn-accent'}">${escape(item.cta)}</a>
492            </div>
493            ${productVisual(item)}
494          </div>
495        </div>
496      </section>`).join('');
497    const stages = page.delivery.stages.map((item) => `
498      <div class="delivery-step">
499        <div class="delivery-code">${escape(item.code)}</div>
500        <h3>${escape(item.title)}</h3>
501        <p>${escape(item.text)}</p>
502      </div>`).join('');
503    return `
504      ${navigation('enterprise', true)}
505      ${hero(page)}
506      ${products}
507      <section class="section bg-night enterprise-delivery"><div class="wrap">${sectionHead(page.delivery)}<div class="delivery-grid reveal d1">${stages}</div></div></section>
508      ${closeSection(page.close, 'bg-night')}
509      ${footer()}`;
510  }
511
512  if (pageKey === 'home') {
513    // Skip client re-render when the markup was already baked at build time
514    // (scripts/prerender.js sets data-prerendered). Interactive enhancements
515    // below still run against the prerendered DOM.
516    if (!mount.dataset.prerendered) mount.innerHTML = renderHome();
517    window.OAIEnhanceDiagramExports?.();
518    if (window.location.hash) {
519      window.requestAnimationFrame(() => {
520        const target = document.querySelector(window.location.hash);
521        if (target) target.scrollIntoView();
522      });
523    }
524  }
525})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.