PageSourceSearch

https://guangyusun.com/flat-website/static-demo/demo.js

js guangyusun.com collected 2026-10-09 22:07:56 UTC 11,343 bytes, 257 lines download raw bytes

1(() => {
2  "use strict";
3
4  const DATA_ROOT = "static-demo/data/";
5  const MODEL_ID = "flex-arm-ft";
6  const TASK_LABELS = {
7    text_to_image: "Text → Image",
8    image_captioning: "Image → Text",
9    interpolation: "Interpolation",
10    latent_arithmetic: "Latent arithmetic",
11  };
12  const DEFAULT_EXAMPLE_INDEX = { text_to_image: 2 };
13
14  const state = {
15    manifest: null,
16    plan: null,
17    task: "text_to_image",
18    exampleIndex: 0,
19    kIndex: 0,
20    pointIndex: 0,
21  };
22
23  const byId = (id) => document.getElementById(id);
24  const stage = byId("flat-demo-stage");
25  const examples = byId("flat-demo-examples");
26  const slider = byId("flat-demo-k");
27  const kOutput = byId("flat-demo-k-output");
28  const ticks = byId("flat-demo-ticks");
29  const status = byId("flat-demo-status");
30
31  if (!stage || !examples || !slider || !kOutput || !ticks || !status) return;
32
33  const record = (key) => state.manifest.records[key] || null;
34  const assetUrl = (entry) => entry && entry.path ? DATA_ROOT + entry.path : "";
35  const taskConfig = () => state.plan.tasks[state.task];
36  const currentExample = () => taskConfig().examples[state.exampleIndex];
37  const kValues = () => taskConfig().k_values;
38  const currentK = () => kValues()[state.kIndex];
39
40  function setStatus(message, isError = false) {
41    status.textContent = message;
42    status.classList.toggle("error", isError);
43  }
44
45  function imageMarkup(src, alt) {
46    if (!src) {
47      return `<div class="flat-demo-placeholder">Output is not available yet.</div>`;
48    }
49    return `<img src="${src}" alt="${escapeHtml(alt)}" loading="eager">`;
50  }
51
52  function displayCaption(value) {
53    const caption = String(value || "").trim();
54    if (!caption) return "Output is not available yet.";
55    return /[.!?]$/.test(caption) ? caption : caption + "…";
56  }
57
58  function pairMarkup({ leftTitle, image, imageAlt, promptLabel, prompt, rightTitle, caption, meta, extras = "" }) {
59    const k = currentK();
60    return `${extras}<div class="flat-demo-pair">
61      <article class="flat-demo-card flat-demo-visual-card">
62        <div class="flat-demo-card-head"><span>${leftTitle}</span><span class="flat-demo-k-badge">K = ${k}</span></div>
63        <div class="flat-demo-image-wrap">${imageMarkup(image, imageAlt)}</div>
64        <div class="flat-demo-copy">
65          <span class="flat-demo-label">${promptLabel}</span>
66          <p>${escapeHtml(prompt)}</p>
67        </div>
68      </article>
69      <div class="flat-demo-bridge" aria-hidden="true"><span></span><strong>same prefix</strong><span></span></div>
70      <article class="flat-demo-card flat-demo-text-card">
71        <div class="flat-demo-card-head"><span>${rightTitle}</span><span class="flat-demo-k-badge">K = ${k}</span></div>
72        <div class="flat-demo-caption-wrap"><span class="flat-demo-quote">“</span><p id="flat-demo-caption">${escapeHtml(displayCaption(caption))}</p></div>
73        <div class="flat-demo-copy flat-demo-caption-meta">
74          <span class="flat-demo-label">Decoded caption</span>
75          <p>${escapeHtml(meta)}</p>
76        </div>
77      </article>
78    </div>`;
79  }
80
81  function renderTextToImage(example, k) {
82    const imageEntry = record(`${MODEL_ID}/text_to_image/${example.id}/k${k}`);
83    const captionEntry = record(`${MODEL_ID}/text_to_image/${example.id}/caption/k${k}`);
84    stage.innerHTML = pairMarkup({
85      leftTitle: "Generated image",
86      image: assetUrl(imageEntry),
87      imageAlt: `Generated image for ${example.prompt} at K=${k}`,
88      promptLabel: "Input prompt",
89      prompt: example.prompt,
90      rightTitle: "Decoded text",
91      caption: captionEntry && captionEntry.caption,
92      meta: "Decoded from the same text representation used to generate the image.",
93    });
94  }
95
96  function renderCaptioning(example, k) {
97    const captionEntry = record(`${MODEL_ID}/image_captioning/${example.id}/k${k}`);
98    stage.innerHTML = pairMarkup({
99      leftTitle: "Input image",
100      image: assetUrl(captionEntry && { path: captionEntry.input_path }),
101      imageAlt: example.label,
102      promptLabel: "Input",
103      prompt: example.label,
104      rightTitle: "Generated text",
105      caption: captionEntry && captionEntry.caption,
106      meta: "Decoded from the truncated image representation.",
107    });
108  }
109
110  function renderInterpolation(example, k) {
111    const points = taskConfig().points;
112    const cells = points.map((alpha, index) => {
113      const imageEntry = record(`${MODEL_ID}/interpolation/${example.id}/k${k}/p${index}`);
114      const captionEntry = record(`${MODEL_ID}/interpolation/${example.id}/k${k}/p${index}/caption`);
115      return `<figure class="flat-demo-interp-cell">
116        <div class="flat-demo-interp-alpha">α = ${alpha}</div>
117        <div class="flat-demo-interp-image">${imageMarkup(
118          assetUrl(imageEntry),
119          `Interpolation from ${example.start} to ${example.end} at alpha ${alpha}`
120        )}</div>
121        <figcaption>${escapeHtml(displayCaption(captionEntry && captionEntry.caption))}</figcaption>
122      </figure>`;
123    }).join("");
124    stage.innerHTML = `<div class="flat-demo-sequence">
125      <div class="flat-demo-sequence-head">
126        <span>${escapeHtml(example.start)}</span>
127        <span class="flat-demo-sequence-arrow" aria-hidden="true">→</span>
128        <span>${escapeHtml(example.end)}</span>
129      </div>
130      <div class="flat-demo-interp-grid">${cells}</div>
131      <div class="flat-demo-sequence-note">Decoded captions are shown beneath their corresponding generated images.</div>
132    </div>`;
133  }
134
135  function renderArithmetic(example, k) {
136    const stageIndex = example.terms.length - 1;
137    const resultEntry = record(`${MODEL_ID}/latent_arithmetic/${example.id}/stage${stageIndex}/k${k}`);
138    const captionEntry = record(`${MODEL_ID}/latent_arithmetic/${example.id}/final_caption/k${k}`);
139    const operands = example.terms.map((term, index) => {
140      const entry = record(`${MODEL_ID}/latent_arithmetic/${example.id}/term${index}/k${k}`);
141      const source = assetUrl(entry);
142      const isImage = term.modality === "image";
143      const modality = isImage ? "Image input" : "Text input";
144      const operator = index === 0 ? "" : `<span class="flat-demo-arith-operator" aria-hidden="true">${term.sign > 0 ? "+" : "−"}</span>`;
145      return `${operator}<figure class="flat-demo-arith-cell">
146        <div class="flat-demo-arith-head"><span>Input ${index + 1}</span><span>Decoded · K=${k}</span></div>
147        <div class="flat-demo-arith-image">${imageMarkup(source, term.text)}</div>
148        <figcaption><strong>${modality}</strong>${isImage ? escapeHtml(term.text) : `“${escapeHtml(term.text)}”`}</figcaption>
149      </figure>`;
150    }).join("");
151    const modalities = [...new Set(example.terms.map((term) => term.modality === "image" ? "image" : "text"))];
152    const modeLabel = example.operation_label || (modalities.length === 1 ? `${modalities[0]}–${modalities[0]}` : "image–text");
153    stage.innerHTML = `<div class="flat-demo-arithmetic">
154      <div class="flat-demo-arithmetic-meta">
155        <span class="flat-demo-operation-badge">${escapeHtml(modeLabel)}</span>
156        <span>Register-wise arithmetic in the shared representation space</span>
157      </div>
158      <div class="flat-demo-equation">
159        ${operands}
160        <span class="flat-demo-arith-operator flat-demo-arith-equals" aria-hidden="true">=</span>
161        <figure class="flat-demo-arith-cell flat-demo-arith-result">
162          <div class="flat-demo-arith-head"><span>Output</span><span>K = ${k}</span></div>
163          <div class="flat-demo-arith-image">${imageMarkup(assetUrl(resultEntry), `Arithmetic result at K=${k}`)}</div>
164          <figcaption><strong>Decoded caption</strong>${escapeHtml(displayCaption(captionEntry && captionEntry.caption))}</figcaption>
165        </figure>
166      </div>
167    </div>`;
168  }
169
170  function renderStage() {
171    const example = currentExample();
172    const k = currentK();
173    document.querySelectorAll("[data-flat-k]").forEach((el) => { el.textContent = `K = ${k}`; });
174    kOutput.textContent = `K = ${k} · ${k * 64} dimensions`;
175    slider.style.setProperty("--flat-demo-progress", `${state.kIndex / Math.max(kValues().length - 1, 1) * 100}%`);
176    [...ticks.children].forEach((el, index) => el.classList.toggle("active", index === state.kIndex));
177
178    if (state.task === "text_to_image") renderTextToImage(example, k);
179    else if (state.task === "image_captioning") renderCaptioning(example, k);
180    else if (state.task === "interpolation") renderInterpolation(example, k);
181    else renderArithmetic(example, k);
182
183    setStatus(`Precomputed output · ${TASK_LABELS[state.task]} · K=${k}`);
184  }
185
186  function renderExamples() {
187    examples.innerHTML = taskConfig().examples.map((example, index) =>
188      `<button class="flat-demo-example${index === state.exampleIndex ? " active" : ""}" type="button" data-example="${index}">${escapeHtml(example.label)}</button>`
189    ).join("");
190    examples.querySelectorAll("[data-example]").forEach((button) => {
191      button.addEventListener("click", () => {
192        state.exampleIndex = Number(button.dataset.example);
193        renderExamples();
194        renderStage();
195      });
196    });
197  }
198
199  function renderSlider() {
200    const values = kValues();
201    state.kIndex = Math.min(state.kIndex, values.length - 1);
202    slider.max = String(values.length - 1);
203    slider.value = String(state.kIndex);
204    const denominator = Math.max(values.length - 1, 1);
205    ticks.innerHTML = values.map((k, index) =>
206      `<span style="left:${index / denominator * 100}%">${k}</span>`
207    ).join("");
208  }
209
210  function selectTask(task) {
211    state.task = task;
212    state.exampleIndex = DEFAULT_EXAMPLE_INDEX[task] || 0;
213    state.kIndex = taskConfig().k_values.length - 1;
214    state.pointIndex = 0;
215    document.querySelectorAll(".flat-demo-task").forEach((button) => {
216      const active = button.dataset.task === task;
217      button.classList.toggle("active", active);
218      button.setAttribute("aria-selected", String(active));
219    });
220    renderExamples();
221    renderSlider();
222    renderStage();
223  }
224
225  function escapeHtml(value) {
226    return String(value || "").replace(/[&<>'"]/g, (character) => ({
227      "&": "&amp;", "<": "&lt;", ">": "&gt;", "'": "&#39;", '"': "&quot;",
228    })[character]);
229  }
230
231  async function loadDemo() {
232    try {
233      const [manifestResponse, planResponse] = await Promise.all([
234        fetch(DATA_ROOT + "manifest.json"),
235        fetch(DATA_ROOT + "source_plan.json"),
236      ]);
237      if (!manifestResponse.ok || !planResponse.ok) throw new Error("precomputed asset manifest is unavailable");
238      state.manifest = await manifestResponse.json();
239      state.plan = await planResponse.json();
240      document.querySelectorAll(".flat-demo-task").forEach((button) => {
241        button.addEventListener("click", () => selectTask(button.dataset.task));
242      });
243      slider.addEventListener("input", () => {
244        state.kIndex = Number(slider.value);
245        renderStage();
246      });
247      selectTask(state.task);
248    } catch (error) {
249      stage.innerHTML = `<div class="flat-demo-stage-loading">The static demo assets are being prepared for release.</div>`;
250      examples.innerHTML = '<span class="flat-demo-loading">Examples unavailable</span>';
251      slider.disabled = true;
252      setStatus(error.message, true);
253    }
254  }
255
256  loadDemo();
257})();

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.