alphabell-research commited on
Commit
d834e38
·
verified ·
1 Parent(s): 4777430

Publish MiniMax video placeholder inspector

Browse files
Files changed (13) hide show
  1. .gitattributes +1 -0
  2. LICENSE +21 -0
  3. NOTICE +12 -0
  4. README.md +31 -5
  5. budget.js +145 -0
  6. cover.html +3 -0
  7. cover.png +3 -0
  8. favicon.svg +1 -0
  9. index.html +25 -17
  10. package.json +9 -0
  11. sources.json +19 -0
  12. style.css +1 -28
  13. tests/budget.test.cjs +63 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ cover.png filter=lfs diff=lfs merge=lfs -text
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2026 alphaBell
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
NOTICE ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MiniMax Video Budget
2
+ Copyright 2026 alphaBell. Viewer code is licensed under MIT.
3
+
4
+ Model and processor reference:
5
+ MiniMaxAI/MiniMax-M3.1-Flash, MiniMax
6
+ https://huggingface.co/MiniMaxAI/MiniMax-M3.1-Flash
7
+ Revision 262ae6830934f3512211081b8a3f16425b93a239
8
+
9
+ This independent viewer derives a small arithmetic fact from the public
10
+ processor implementation and links to the exact publisher files. It does
11
+ not redistribute MiniMax processor source, model weights, examples or media.
12
+ The MiniMax model repository states its own separate license terms.
README.md CHANGED
@@ -1,10 +1,36 @@
1
  ---
2
  title: MiniMax Video Budget
3
- emoji: 🏆
4
- colorFrom: blue
5
- colorTo: red
6
  sdk: static
7
- pinned: false
 
 
 
 
 
 
 
 
 
 
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: MiniMax Video Budget
3
+ emoji: 🎞️
4
+ colorFrom: green
5
+ colorTo: gray
6
  sdk: static
7
+ app_file: index.html
8
+ license: mit
9
+ short_description: "Video frame-to-placeholder budget for MiniMax M3.1 Flash"
10
+ thumbnail: https://huggingface.co/spaces/alphabell/MiniMax-Video-Budget/resolve/main/cover.png
11
+ models:
12
+ - MiniMaxAI/MiniMax-M3.1-Flash
13
+ tags:
14
+ - minimax
15
+ - video
16
+ - multimodal
17
+ - tokenization
18
+ - visualization
19
+ - developer-tools
20
  ---
21
 
22
+ # MiniMax Video Budget
23
+
24
+ **How many vision placeholders does a sampled video create in MiniMax M3.1 Flash?**
25
+
26
+ [Open the interactive inspector](https://huggingface.co/spaces/alphabell/MiniMax-Video-Budget) to enter the number of sampled frames and their post-resize dimensions. The page shows two-frame groups, odd-frame repetition, spatial patch merging, a shareable URL and a JSON export.
27
+
28
+ The calculation is `ceil(sampled_frames / 2) × (processed_height / 28) × (processed_width / 28)`. For 16 sampled frames already processed at 672 × 672 pixels, that is 8 groups × 576 placeholders = **4,608 vision placeholders**. A single frame also occupies one temporal group: its final frame is repeated, yielding 576 placeholders at this size.
29
+
30
+ This is a source-derived count of repeated vision placeholders. It is not total prompt tokens, memory, speed, video quality or a prediction of automatic frame sampling or resizing. Timestamp and wrapper tokens are additional. No video, image or model weights are uploaded or run by this Space.
31
+
32
+ The formula follows the pinned [video processor](https://huggingface.co/MiniMaxAI/MiniMax-M3.1-Flash/blob/262ae6830934f3512211081b8a3f16425b93a239/video_processor.py#L122), [placeholder expansion](https://huggingface.co/MiniMaxAI/MiniMax-M3.1-Flash/blob/262ae6830934f3512211081b8a3f16425b93a239/processing_minimax.py#L209), [image merge setting](https://huggingface.co/MiniMaxAI/MiniMax-M3.1-Flash/blob/262ae6830934f3512211081b8a3f16425b93a239/image_processor.py#L89) and [model card](https://huggingface.co/MiniMaxAI/MiniMax-M3.1-Flash/blob/262ae6830934f3512211081b8a3f16425b93a239/README.md). The exact revision and checked source hashes are in [sources.json](sources.json).
33
+
34
+ Built by **alphaBell** as an independent educational tool. MiniMax publishes the model and processor. No publisher source code or model weights are included. [Source attribution](NOTICE) · [Viewer license](LICENSE).
35
+
36
+ Serve this directory over HTTP to run locally. Run `node --test tests/*.test.cjs` for calculation and release checks. The viewer uses no backend, analytics, font CDN or API key.
budget.js ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use strict';
2
+
3
+ const REVISION = '262ae6830934f3512211081b8a3f16425b93a239';
4
+ const MODEL = 'MiniMaxAI/MiniMax-M3.1-Flash';
5
+ const PATCH = 14;
6
+ const MERGE = 2;
7
+ const TEMPORAL = 2;
8
+ const SPATIAL_UNIT = PATCH * MERGE;
9
+ const DEFAULT_MAX_PIXELS = 768 * 28 * 28;
10
+ const DEFAULT_MIN_PIXELS = 4 * 28 * 28;
11
+
12
+ function validate(frames, height, width) {
13
+ if (!Number.isSafeInteger(frames) || frames < 1 || frames > 240) return 'Enter 1 to 240 sampled frames.';
14
+ for (const [label, value] of [['height', height], ['width', width]]) {
15
+ if (!Number.isSafeInteger(value) || value < 28 || value > 2016 || value % SPATIAL_UNIT !== 0) {
16
+ return `Enter a processed ${label} from 28 to 2,016 in steps of 28 pixels.`;
17
+ }
18
+ }
19
+ return '';
20
+ }
21
+
22
+ function calculate(frames, height, width) {
23
+ const error = validate(frames, height, width);
24
+ if (error) throw new RangeError(error);
25
+ const groups = Math.ceil(frames / TEMPORAL);
26
+ const gridHeight = height / PATCH;
27
+ const gridWidth = width / PATCH;
28
+ const placeholdersPerGroup = (gridHeight * gridWidth) / (MERGE * MERGE);
29
+ return {
30
+ frames, height, width, groups, gridHeight, gridWidth,
31
+ placeholdersPerGroup,
32
+ placeholders: groups * placeholdersPerGroup,
33
+ repeatedLastFrame: frames % TEMPORAL === 1,
34
+ framePairs: Array.from({length: groups}, (_, index) => {
35
+ const first = index * TEMPORAL + 1;
36
+ const second = Math.min(first + 1, frames);
37
+ return {group: index + 1, first, second, repeated: first === second, placeholders: placeholdersPerGroup};
38
+ }),
39
+ outsideDefaultPixelRange: height * width < DEFAULT_MIN_PIXELS || height * width > DEFAULT_MAX_PIXELS,
40
+ };
41
+ }
42
+
43
+ function exportRecord(result) {
44
+ return {
45
+ schema_version: 1,
46
+ model: MODEL,
47
+ publisher_revision: REVISION,
48
+ inputs: {sampled_frames: result.frames, processed_frame_height: result.height, processed_frame_width: result.width},
49
+ formula: 'ceil(sampled_frames / 2) * (processed_frame_height / 28) * (processed_frame_width / 28)',
50
+ assumptions: ['Dimensions are after any resizing and are divisible by 28.', 'An odd final frame is repeated to complete the last two-frame group.', 'This counts vision placeholders only, not timestamp or wrapper tokens, total prompt tokens, memory, runtime or quality.'],
51
+ result: {temporal_groups: result.groups, vision_placeholders_per_group: result.placeholdersPerGroup, total_vision_placeholders: result.placeholders, repeated_final_frame: result.repeatedLastFrame, groups: result.framePairs},
52
+ };
53
+ }
54
+
55
+ if (typeof module !== 'undefined' && module.exports) module.exports = {calculate, validate, exportRecord, REVISION, MODEL};
56
+
57
+ if (typeof document !== 'undefined') {
58
+ const number = new Intl.NumberFormat('en-US');
59
+ const form = document.querySelector('#budget-form');
60
+ const frameInput = document.querySelector('#frames');
61
+ const heightInput = document.querySelector('#height');
62
+ const widthInput = document.querySelector('#width');
63
+ const errorEl = document.querySelector('#error');
64
+ const resultEl = document.querySelector('#result');
65
+ const groupsEl = document.querySelector('#groups');
66
+ const exportButton = document.querySelector('#export');
67
+ const copyButton = document.querySelector('#copy');
68
+ const statusEl = document.querySelector('#status');
69
+ let current = null;
70
+
71
+ function readQuery() {
72
+ const query = new URLSearchParams(location.search);
73
+ const parse = (name, fallback) => /^\d+$/.test(query.get(name) || '') ? Number(query.get(name)) : fallback;
74
+ const frames = parse('frames', 16), height = parse('height', 672), width = parse('width', 672);
75
+ if (!validate(frames, height, width)) {
76
+ frameInput.value = frames;
77
+ heightInput.value = height;
78
+ widthInput.value = width;
79
+ }
80
+ }
81
+
82
+ function render() {
83
+ const frames = Number(frameInput.value), height = Number(heightInput.value), width = Number(widthInput.value);
84
+ const error = validate(frames, height, width);
85
+ errorEl.textContent = error;
86
+ resultEl.hidden = Boolean(error);
87
+ exportButton.disabled = Boolean(error);
88
+ copyButton.disabled = Boolean(error);
89
+ if (error) { current = null; return; }
90
+ current = calculate(frames, height, width);
91
+ document.querySelector('#total').textContent = number.format(current.placeholders);
92
+ document.querySelector('#per-group').textContent = number.format(current.placeholdersPerGroup);
93
+ document.querySelector('#group-count').textContent = number.format(current.groups);
94
+ document.querySelector('#grid').textContent = `${current.gridHeight} × ${current.gridWidth} patches, merged 2 × 2`;
95
+ document.querySelector('#padding').textContent = current.repeatedLastFrame
96
+ ? `Frame ${frames} is repeated in the last group to complete a pair.`
97
+ : 'No frame is repeated.';
98
+ document.querySelector('#range-warning').hidden = !current.outsideDefaultPixelRange;
99
+ const visible = current.framePairs.length <= 12
100
+ ? current.framePairs
101
+ : [...current.framePairs.slice(0, 11), current.framePairs.at(-1)];
102
+ groupsEl.replaceChildren(...visible.map(pair => {
103
+ const card = document.createElement('li');
104
+ card.className = 'group-card';
105
+ if (pair.repeated) card.classList.add('repeated');
106
+ card.innerHTML = `<span class="group-index">Group ${pair.group}</span><strong>${pair.first} <span aria-hidden="true">+</span> ${pair.second}</strong><small>${pair.repeated ? 'Final frame repeated' : 'Two sampled frames'}</small>`;
107
+ return card;
108
+ }));
109
+ document.querySelector('#group-overflow').textContent = current.framePairs.length > 12
110
+ ? `Showing the first 11 and final group of ${current.groups}. The JSON export includes every group.`
111
+ : `Showing all ${current.groups} groups.`;
112
+ const url = new URL(location.href);
113
+ url.searchParams.set('frames', String(frames));
114
+ url.searchParams.set('height', String(height));
115
+ url.searchParams.set('width', String(width));
116
+ history.replaceState(null, '', url);
117
+ }
118
+
119
+ readQuery();
120
+ form.addEventListener('input', render);
121
+ form.addEventListener('submit', event => event.preventDefault());
122
+ document.querySelectorAll('[data-preset]').forEach(button => button.addEventListener('click', () => {
123
+ frameInput.value = button.dataset.preset;
124
+ heightInput.value = 672;
125
+ widthInput.value = 672;
126
+ render();
127
+ frameInput.focus();
128
+ }));
129
+ exportButton.addEventListener('click', () => {
130
+ if (!current) return;
131
+ const blob = new Blob([JSON.stringify(exportRecord(current), null, 2) + '\n'], {type: 'application/json'});
132
+ const link = document.createElement('a');
133
+ link.href = URL.createObjectURL(blob);
134
+ link.download = `minimax-video-budget-${current.frames}frames.json`;
135
+ link.click();
136
+ setTimeout(() => URL.revokeObjectURL(link.href), 1000);
137
+ statusEl.textContent = 'JSON downloaded.';
138
+ });
139
+ copyButton.addEventListener('click', async () => {
140
+ if (!current) return;
141
+ try { await navigator.clipboard.writeText(location.href); statusEl.textContent = 'Share link copied.'; }
142
+ catch { statusEl.textContent = 'Copy the page address to share this view.'; }
143
+ });
144
+ render();
145
+ }
cover.html ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ <!doctype html><html lang="en"><head><meta charset="utf-8"><style>
2
+ *{box-sizing:border-box}html,body{width:1280px;height:720px;margin:0}body{font-family:Arial,Helvetica,sans-serif;background:#111827;color:#effaf8;overflow:hidden}.frame{height:100%;padding:48px 58px;background:radial-gradient(circle at 1080px 115px,#1c756440,transparent 38%),#111827}.top{display:flex;justify-content:space-between;align-items:center}.brand{display:flex;align-items:center;gap:12px;font-weight:740;font-size:22px}.mark{width:39px;height:39px;display:grid;place-items:center;background:#89e5d0;color:#12323b;border-radius:10px;font-size:30px}.tag{color:#93dac9;font-size:15px;text-transform:uppercase;letter-spacing:.17em;font-weight:750}h1{font-size:64px;letter-spacing:-.055em;line-height:1.02;margin:42px 0 16px;max-width:900px}h1 span{color:#8de6d0}.lead{font-size:23px;color:#b9d3d6;max-width:900px;line-height:1.3;margin:0}.body{display:grid;grid-template-columns:1.15fr .85fr;gap:18px;margin-top:34px}.panel{border:1px solid #3b646c;background:#18313e;border-radius:16px;min-height:300px;padding:24px}.panel .label{color:#94c7c8;font-weight:700;font-size:14px;text-transform:uppercase;letter-spacing:.12em}.equation{display:flex;align-items:center;gap:13px;margin-top:65px;font-size:27px;font-weight:720}.equation b{color:#7be0c7;font-size:22px}.equation small{display:block;font-weight:550;color:#a7c6ca;font-size:14px;margin-top:12px}.result .number{font-size:75px;font-weight:800;color:#93ecd2;letter-spacing:-.07em;line-height:1;margin:55px 0 6px}.result p{font-size:17px;color:#b7d6d5;margin:0}.bottom{display:flex;justify-content:space-between;margin-top:28px;color:#96b8be;font-size:14px}.bottom strong{color:#c9e8e0}
3
+ </style></head><body><div class="frame"><div class="top"><div class="brand"><span class="mark">α</span>alphaBell / MiniMax Video Budget</div><div class="tag">Source-pinned model lens</div></div><h1>One video. <span>Many visual slots.</span></h1><p class="lead">See how sampled frames become vision placeholders in MiniMax M3.1 Flash.</p><div class="body"><div class="panel"><div class="label">16 sampled frames · 672 × 672 processed pixels</div><div class="equation"><div>8 groups<small>two frames each</small></div><b>×</b><div>576<small>placeholders per group</small></div><b>=</b></div></div><div class="panel result"><div class="label">Vision placeholders</div><div class="number">4,608</div><p>From the pinned public processor</p></div></div><div class="bottom"><span><strong>Processor arithmetic.</strong> Excludes text, timestamps, memory and speed.</span><span>Interactive inspector ↗</span></div></div></body></html>
cover.png ADDED

Git LFS Details

  • SHA256: d1e85d072ad1af4cffa033fe0842ffecf547ee10fe6256b0a28b197322c1eeca
  • Pointer size: 131 Bytes
  • Size of remote file: 165 kB
favicon.svg ADDED
index.html CHANGED
@@ -1,19 +1,27 @@
1
  <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
19
  </html>
 
1
  <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="theme-color" content="#111827">
7
+ <meta name="description" content="See how sampled video frames expand into vision placeholders in MiniMax M3.1 Flash, using its pinned public processor. Built by alphaBell.">
8
+ <meta property="og:title" content="MiniMax Video Budget | alphaBell">
9
+ <meta property="og:description" content="A source-pinned visual calculator for MiniMax M3.1 Flash video placeholders.">
10
+ <meta property="og:image" content="https://huggingface.co/spaces/alphabell/MiniMax-Video-Budget/resolve/main/cover.png">
11
+ <title>MiniMax Video Budget | alphaBell</title>
12
+ <link rel="icon" href="favicon.svg">
13
+ <link rel="stylesheet" href="style.css">
14
+ <script src="budget.js" defer></script>
15
+ </head>
16
+ <body>
17
+ <header class="topbar"><a class="brand" href="https://alphabell.com" aria-label="alphaBell home"><span class="mark">α</span><span>alphaBell <i>/</i> video budget</span></a><a class="top-link" href="https://huggingface.co/MiniMaxAI/MiniMax-M3.1-Flash" target="_blank" rel="noopener noreferrer">Publisher model ↗</a></header>
18
+ <main>
19
+ <section class="hero" aria-labelledby="title"><div class="hero-copy"><p class="eyebrow">Source-pinned model lens <span>01 / MiniMax M3.1 Flash</span></p><h1 id="title">One video.<br><em>Many visual slots.</em></h1><p class="lead">MiniMax M3.1 Flash groups sampled frames in pairs, then expands each group into visual placeholders. Enter the frame count and <strong>processed</strong> frame dimensions to see the exact arithmetic.</p><div class="hero-rule"><span class="pulse" aria-hidden="true"></span><span>Processor arithmetic, not an inference benchmark</span></div></div><div class="hero-visual" aria-hidden="true"><div class="filmstrip"><span>01</span><span>02</span><span>03</span><span>04</span></div><div class="connector">↓ two-frame groups</div><div class="pixel-grid"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div><div class="visual-label">Frames → groups → placeholders</div></div></section>
20
+ <section class="workspace" aria-labelledby="tool-title"><div class="section-head"><p class="eyebrow">01 / Try a video shape</p><h2 id="tool-title">Count the visual placeholders</h2><p>Use the number of frames <em>after sampling</em> and the height and width <em>after resizing</em>. Dimensions must be multiples of 28 pixels.</p></div><div class="tool-grid"><form id="budget-form" novalidate><div class="input-grid"><label for="frames">Sampled frames <small>1 to 240</small><input id="frames" name="frames" type="number" min="1" max="240" step="1" value="16" inputmode="numeric"></label><label for="height">Processed height <small>pixels, step 28</small><input id="height" name="height" type="number" min="28" max="2016" step="28" value="672" inputmode="numeric"></label><label for="width">Processed width <small>pixels, step 28</small><input id="width" name="width" type="number" min="28" max="2016" step="28" value="672" inputmode="numeric"></label></div><p class="field-error" id="error" role="alert"></p><div class="presets" role="group" aria-label="Example frame counts"><span>Try:</span><button type="button" data-preset="1">1 frame</button><button type="button" data-preset="3">3 frames</button><button type="button" data-preset="16">16 frames</button></div><p class="field-note" id="range-warning" hidden>These dimensions are outside the processor's default video resize area of 3,136 to 602,112 pixels. Check the actual processed dimensions before using this result.</p></form><div id="result" class="result" aria-live="polite"><div class="result-label">Vision placeholders</div><div class="big-number" id="total">4,608</div><div class="result-equation"><span id="group-count">8</span> two-frame groups <b>×</b> <span id="per-group">576</span> per group</div><div class="result-facts"><div><span>Spatial patch grid</span><strong id="grid">48 × 48 patches, merged 2 × 2</strong></div><div><span>Odd-frame padding</span><strong id="padding">No frame is repeated.</strong></div></div><div class="actions"><button id="copy" type="button">Copy view link</button><button id="export" type="button">Download JSON</button></div><p id="status" class="action-status" role="status"></p></div></div></section>
21
+ <section class="timeline" aria-labelledby="timeline-title"><div class="section-head"><p class="eyebrow">02 / Temporal groups</p><h2 id="timeline-title">Where the frames go</h2><p>An odd final frame is repeated to complete the last pair. Each group receives the same placeholder count when processed dimensions are constant.</p></div><ol id="groups" class="groups" aria-label="Two-frame video groups"></ol><p id="group-overflow" class="group-overflow"></p></section>
22
+ <section class="explanation" aria-labelledby="math-title"><div class="section-head"><p class="eyebrow">03 / How it is calculated</p><h2 id="math-title">Three factors, one count</h2></div><div class="formula"><span>ceil(sampled frames ÷ 2)</span><b>×</b><span>(processed height ÷ 28)</span><b>×</b><span>(processed width ÷ 28)</span></div><div class="explain-grid"><article><strong>01</strong><h3>Pair the frames</h3><p>The processor pads an odd frame count by repeating its last frame, then groups frames in twos.</p></article><article><strong>02</strong><h3>Merge spatial patches</h3><p>Each 14-pixel patch grid is merged 2 by 2. One placeholder covers a 28 by 28 processed-pixel region.</p></article><article><strong>03</strong><h3>Count placeholders</h3><p>The text processor repeats a vision placeholder for every merged spatial location in every temporal group.</p></article></div><div class="scope"><strong>What this number covers</strong><p>This counts the repeated vision placeholders in the pinned MiniMax processor. It excludes timestamps, vision wrapper tokens, text, total prompt tokens, automatic frame sampling, resize decisions, model memory, speed and visual understanding. It does not require model weights or upload a video.</p></div></section>
23
+ <section class="sources" aria-labelledby="sources-title"><div class="section-head"><p class="eyebrow">Pinned publisher sources</p><h2 id="sources-title">Inspect the implementation</h2><p>All source links point to MiniMax M3.1 Flash revision <code>262ae6830934f3512211081b8a3f16425b93a239</code>.</p></div><div class="source-grid"><a href="https://huggingface.co/MiniMaxAI/MiniMax-M3.1-Flash/blob/262ae6830934f3512211081b8a3f16425b93a239/video_processor.py#L122" target="_blank" rel="noopener noreferrer"><span>Video processor</span><strong>Frame padding and grids ↗</strong></a><a href="https://huggingface.co/MiniMaxAI/MiniMax-M3.1-Flash/blob/262ae6830934f3512211081b8a3f16425b93a239/processing_minimax.py#L209" target="_blank" rel="noopener noreferrer"><span>Text processor</span><strong>Placeholder expansion ↗</strong></a><a href="https://huggingface.co/MiniMaxAI/MiniMax-M3.1-Flash/blob/262ae6830934f3512211081b8a3f16425b93a239/README.md" target="_blank" rel="noopener noreferrer"><span>Model card</span><strong>MiniMax M3.1 Flash ↗</strong></a></div></section>
24
+ </main>
25
+ <footer><span>Built by <a href="https://alphabell.com">alphaBell</a></span><span>Independent processor visualization. Model and processor by MiniMax.</span><a href="https://huggingface.co/alphabell" target="_blank" rel="noopener noreferrer">More lab projects ↗</a></footer>
26
+ </body>
27
  </html>
package.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "alphabell-minimax-video-budget",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "description": "Source-pinned MiniMax video placeholder inspector",
6
+ "author": "alphaBell",
7
+ "license": "MIT",
8
+ "scripts": {"test": "node --test tests/*.test.cjs"}
9
+ }
sources.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "publisher_model": "MiniMaxAI/MiniMax-M3.1-Flash",
3
+ "revision": "262ae6830934f3512211081b8a3f16425b93a239",
4
+ "checked_files": {
5
+ "README.md": "c49a7cca92321066bc20e25ce720260242dcb112baf1d09c7c213899e39d2151",
6
+ "processing_minimax.py": "0706ae8b93b3489a3b3bc7f48a5f29fb34b1449ebebb37586250e4d5fa8f5e35",
7
+ "video_processor.py": "ced0f8d85d73f8722fecb26033d2d91ecf4a4e5112c91ce1b1522ca7edd0943d",
8
+ "image_processor.py": "8218f98634c365608a98ea887bfebac37131ec2acdb8445188350490de7cf994",
9
+ "preprocessor_config.json": "36785da1dc7a00324048bd7c537c24247fca97c626884818257fd0b92287de31"
10
+ },
11
+ "observed_parameters": {
12
+ "video_patch_size": 14,
13
+ "video_temporal_patch_size": 2,
14
+ "video_merge_size": 2,
15
+ "image_merge_size_used_by_text_processor": 2,
16
+ "default_video_min_pixels": 3136,
17
+ "default_video_max_pixels": 602112
18
+ }
19
+ }
style.css CHANGED
@@ -1,28 +1 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
- }
5
-
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
- }
10
-
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
- }
17
-
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
- }
25
-
26
- .card p:last-child {
27
- margin-bottom: 0;
28
- }
 
1
+ :root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#152333;background:#f5f8f9;font-synthesis:none}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0}button,input{font:inherit}button{cursor:pointer}a{color:inherit}a:focus-visible,button:focus-visible,input:focus-visible{outline:3px solid #ffcc67;outline-offset:3px}.topbar{height:72px;background:#111827;color:#eaf8f7;display:flex;align-items:center;justify-content:space-between;padding:0 max(24px,calc((100vw - 1152px)/2))}.brand{text-decoration:none;display:flex;align-items:center;gap:11px;font-size:15px;font-weight:720}.brand i{font-style:normal;color:#78a0a9;padding:0 3px}.mark{width:31px;height:31px;display:grid;place-items:center;border-radius:9px;background:#89e5d0;color:#12323b;font-size:26px;line-height:1}.top-link{color:#b4cbd2;text-decoration:none;font-size:13px;font-weight:600}.top-link:hover,footer a:hover{text-decoration:underline}main{max-width:1152px;margin:auto;padding:0 24px 105px}.eyebrow{color:#0a8d77;text-transform:uppercase;letter-spacing:.16em;font-size:11px;font-weight:800;margin:0 0 18px}.eyebrow span{color:#7a9ca4;margin-left:14px}.hero{display:grid;grid-template-columns:minmax(0,1.45fr) minmax(300px,.85fr);gap:40px;align-items:center;padding:75px 0 65px}.hero h1{font-size:clamp(54px,6.3vw,85px);line-height:1.015;letter-spacing:-.065em;margin:0;font-weight:770}.hero h1 em{font-style:normal;color:#0b9c83}.lead{font-size:19px;line-height:1.58;color:#486473;margin:26px 0 25px;max-width:660px}.lead strong{color:#153f49}.hero-rule{display:flex;gap:11px;align-items:center;color:#547777;font-size:13px;font-weight:660}.pulse{width:9px;height:9px;flex:none;background:#0aa883;border-radius:50%;box-shadow:0 0 0 5px #d3f0e7}.hero-visual{background:#142532;border-radius:23px;padding:38px 28px 30px;min-height:340px;color:#d8f4f0;box-shadow:0 22px 40px #153c481c;position:relative;overflow:hidden}.hero-visual:before{content:"";position:absolute;width:320px;height:320px;right:-130px;top:-160px;border-radius:50%;background:#25867750;filter:blur(45px)}.filmstrip{position:relative;display:flex;gap:8px}.filmstrip span{flex:1;display:grid;place-items:center;height:70px;border:1px solid #4c7580;border-radius:9px;background:linear-gradient(145deg,#31525c,#172d3e);font-size:22px;font-weight:740;color:#a5e8d7}.filmstrip span:nth-child(3),.filmstrip span:nth-child(4){color:#79cbb7}.connector{text-align:center;color:#a4c4c8;font-size:12px;letter-spacing:.07em;margin:20px 0 13px}.pixel-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;max-width:172px;margin:0 auto}.pixel-grid i{aspect-ratio:1;border-radius:4px;background:#60cdb1}.pixel-grid i:nth-child(3n){background:#91e5d4}.pixel-grid i:nth-child(5n){background:#278e80}.visual-label{position:relative;text-align:center;color:#8caeb6;font-size:12px;margin-top:24px}.section-head h2{font-size:clamp(31px,4vw,49px);letter-spacing:-.055em;line-height:1.1;margin:0 0 14px}.section-head>p:last-child{max-width:760px;color:#5a7580;line-height:1.55;font-size:16px;margin:0}.workspace,.timeline,.explanation,.sources{margin-top:62px}.tool-grid{display:grid;grid-template-columns:1fr .88fr;gap:16px;align-items:stretch;margin-top:31px}.tool-grid form,.result{border-radius:17px;padding:27px 29px}.tool-grid form{background:#fff;border:1px solid #dce8eb;box-shadow:0 6px 24px #1436460a}.input-grid{display:grid;gap:18px}.input-grid label{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:4px;color:#1d3540;font-size:14px;font-weight:730}.input-grid label small{font-size:11px;font-weight:570;color:#73909a}.input-grid input{width:100%;margin-top:7px;border-radius:10px;border:1px solid #c8dadd;background:#f9fcfc;padding:13px 14px;font-size:22px;font-weight:690;font-variant-numeric:tabular-nums;color:#123b42}.input-grid input:focus{border-color:#159a85;background:#fff}.field-error{min-height:22px;color:#b34034;font-size:12px;line-height:1.4;margin:12px 0 4px}.presets{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding-top:14px;border-top:1px solid #e5eef0}.presets span{color:#73909a;font-size:12px;font-weight:700;margin-right:4px}.presets button{border:1px solid #d1e2df;background:#edf6f3;color:#117365;border-radius:20px;padding:7px 12px;font-size:12px;font-weight:730}.presets button:hover{background:#d9eee6}.field-note{color:#846012;background:#fff5d9;border:1px solid #f5dda2;border-radius:9px;padding:10px 12px;font-size:12px;line-height:1.4;margin:17px 0 0}.result{background:#152b39;color:#fff;display:flex;flex-direction:column;min-height:487px}.result-label{font-size:12px;text-transform:uppercase;letter-spacing:.15em;font-weight:790;color:#8fe1ca}.big-number{font-size:clamp(60px,7vw,96px);font-weight:770;letter-spacing:-.08em;line-height:1;margin:18px 0 12px;font-variant-numeric:tabular-nums;color:#9af0d5}.result-equation{font-size:15px;color:#c3d8dc}.result-equation b{color:#75a7ad;padding:0 6px}.result-facts{border-top:1px solid #395765;margin-top:28px;padding-top:20px;display:grid;gap:14px}.result-facts div{display:grid;gap:4px}.result-facts span{color:#8faeb7;font-size:12px}.result-facts strong{font-size:14px;font-weight:620;line-height:1.35}.actions{display:flex;gap:9px;flex-wrap:wrap;margin-top:auto;padding-top:25px}.actions button{border:1px solid #69bca8;background:#86e4ca;color:#123b3a;border-radius:9px;padding:10px 13px;font-size:12px;font-weight:790}.actions button+button{background:transparent;color:#b0e8d7}.actions button:hover:not(:disabled){filter:brightness(1.1)}.actions button:disabled{opacity:.4;cursor:not-allowed}.action-status{min-height:16px;color:#acd9c7;font-size:12px;margin:12px 0 0}.groups{list-style:none;margin:31px 0 0;padding:0;display:grid;grid-template-columns:repeat(4,1fr);gap:10px}.group-card{background:#fff;border:1px solid #dce8eb;border-radius:12px;padding:15px 17px;min-height:100px;display:grid;align-content:start;gap:5px}.group-card.repeated{background:#e9f7ef;border-color:#a5dac1}.group-index{font-size:11px;color:#188673;font-weight:790;text-transform:uppercase;letter-spacing:.09em}.group-card strong{font-size:22px;letter-spacing:-.03em;font-variant-numeric:tabular-nums;color:#1b3843}.group-card strong span{color:#93aeb5;font-weight:500}.group-card small{font-size:11px;color:#6b838c}.group-overflow{color:#718791;font-size:12px;margin:13px 0 0}.formula{margin-top:29px;background:#172b39;color:#e4f8f4;border-radius:16px;padding:25px 28px;display:flex;gap:16px;align-items:center;justify-content:space-between;flex-wrap:wrap;font-size:17px;font-weight:720}.formula span{white-space:nowrap}.formula b{color:#88e4cb;font-size:22px}.explain-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:26px}.explain-grid article{padding:16px 3px}.explain-grid article>strong{display:inline-block;font-size:13px;color:#0d987e;margin-bottom:9px}.explain-grid h3{margin:0 0 8px;font-size:19px;letter-spacing:-.025em}.explain-grid p{color:#59737e;line-height:1.55;margin:0;font-size:14px}.scope{background:#e2f3ee;border:1px solid #bbe0d4;border-radius:13px;padding:21px 24px;margin-top:21px}.scope strong{color:#0b685c;font-size:14px}.scope p{margin:8px 0 0;line-height:1.55;font-size:14px;color:#466d6b}.source-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:27px}.source-grid a{display:grid;gap:8px;text-decoration:none;border:1px solid #c6e2d9;background:#e4f4ee;border-radius:12px;padding:20px 21px}.source-grid a:hover{background:#d6eee4}.source-grid span{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:#569186;font-weight:720}.source-grid strong{color:#086b5a;font-size:15px}.sources code{overflow-wrap:anywhere;font-size:13px;color:#217766}footer{background:#111827;color:#a7bdc4;display:flex;justify-content:space-between;gap:20px;padding:25px max(24px,calc((100vw - 1152px)/2));font-size:12px}footer a{color:#c7ece2;text-decoration:none}@media(max-width:850px){.hero{grid-template-columns:1fr}.hero-visual{min-height:280px;max-width:600px}.tool-grid{grid-template-columns:1fr}.result{min-height:425px}.groups{grid-template-columns:repeat(3,1fr)}.formula{justify-content:flex-start}.explain-grid{gap:12px}}@media(max-width:560px){.topbar{height:62px}.top-link{font-size:0}.top-link:after{content:"↗";font-size:19px}.brand{font-size:13px}main{padding:0 18px 74px}.hero{padding:55px 0 18px;gap:27px}.hero h1{font-size:clamp(43px,12vw,60px)}.lead{font-size:16px;margin:20px 0}.hero-visual{min-height:270px;padding:26px 22px}.filmstrip span{height:52px;font-size:17px}.workspace,.timeline,.explanation,.sources{margin-top:57px}.tool-grid form,.result{padding:21px}.result{min-height:425px}.big-number{font-size:70px}.groups{grid-template-columns:repeat(2,1fr)}.group-card{padding:13px}.formula{font-size:14px;gap:9px;padding:21px}.formula span{white-space:normal}.formula b{font-size:16px}.explain-grid{grid-template-columns:1fr;gap:4px}.explain-grid article{padding:12px 3px}.source-grid{grid-template-columns:1fr}footer{display:grid;padding:23px 18px}.eyebrow span{display:block;margin:5px 0 0}}@media(max-width:360px){.groups{grid-template-columns:1fr 1fr;gap:6px}.group-card strong{font-size:19px}.formula{display:grid;grid-template-columns:1fr auto;align-items:center}.formula b{display:none}.formula span{grid-column:1/-1}.actions button{flex:1}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tests/budget.test.cjs ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use strict';
2
+ const test = require('node:test');
3
+ const assert = require('node:assert/strict');
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+ const {calculate,validate,exportRecord,REVISION,MODEL} = require('../budget.js');
7
+
8
+ test('temporal groups repeat an odd final frame and preserve exact placeholder arithmetic', () => {
9
+ const cases = [[1,672,672,1,576,true],[2,672,672,1,576,false],[3,672,672,2,1152,true],[16,672,672,8,4608,false],[16,448,672,8,3072,false]];
10
+ for (const [frames,height,width,groups,placeholders,repeated] of cases) {
11
+ const result = calculate(frames,height,width);
12
+ assert.equal(result.groups,groups);
13
+ assert.equal(result.placeholders,placeholders);
14
+ assert.equal(result.repeatedLastFrame,repeated);
15
+ assert.equal(result.framePairs.length,groups);
16
+ assert.equal(result.framePairs.at(-1).second,frames);
17
+ }
18
+ assert.deepEqual(calculate(3,672,672).framePairs.map(pair => [pair.first,pair.second,pair.repeated]),[[1,2,false],[3,3,true]]);
19
+ });
20
+
21
+ test('the grid uses 14-pixel patches merged two by two', () => {
22
+ const result=calculate(16,672,672);
23
+ assert.equal(result.gridHeight,48);
24
+ assert.equal(result.gridWidth,48);
25
+ assert.equal(result.placeholdersPerGroup,576);
26
+ assert.equal(result.placeholders,result.groups*result.gridHeight*result.gridWidth/4);
27
+ assert.equal(calculate(16,28,28).outsideDefaultPixelRange,true);
28
+ assert.equal(calculate(16,672,672).outsideDefaultPixelRange,false);
29
+ });
30
+
31
+ test('invalid frames and processed dimensions are rejected before calculation', () => {
32
+ for (const args of [[0,672,672],[241,672,672],[1.5,672,672],[4,671,672],[4,672,673],[4,0,672],[4,672,2044]]) {
33
+ assert.ok(validate(...args));
34
+ assert.throws(()=>calculate(...args),RangeError);
35
+ }
36
+ });
37
+
38
+ test('JSON export retains the pinned source and excludes unsupported cost claims', () => {
39
+ const record=exportRecord(calculate(3,672,672));
40
+ assert.equal(record.model,MODEL);
41
+ assert.equal(record.publisher_revision,REVISION);
42
+ assert.equal(record.result.total_vision_placeholders,1152);
43
+ assert.equal(record.result.groups[1].repeated,true);
44
+ assert.match(record.assumptions.join(' '),/not timestamp or wrapper tokens, total prompt tokens, memory, runtime or quality/);
45
+ const manifest=JSON.parse(fs.readFileSync(path.join(__dirname,'../sources.json'),'utf8'));
46
+ assert.equal(manifest.revision,REVISION);
47
+ assert.equal(manifest.observed_parameters.video_patch_size,14);
48
+ assert.equal(manifest.observed_parameters.image_merge_size_used_by_text_processor,2);
49
+ });
50
+
51
+ test('static release includes local assets and clear source scope', () => {
52
+ const root=path.resolve(__dirname,'..');
53
+ const html=fs.readFileSync(path.join(root,'index.html'),'utf8');
54
+ const readme=fs.readFileSync(path.join(root,'README.md'),'utf8');
55
+ for (const asset of ['budget.js','style.css','favicon.svg','sources.json','NOTICE','LICENSE']) assert.ok(fs.statSync(path.join(root,asset)).size>0,asset);
56
+ assert.match(html,/processed.*frame dimensions/i);
57
+ assert.match(html,/excludes timestamps, vision wrapper tokens, text, total prompt tokens/i);
58
+ assert.match(readme,/MiniMaxAI\/MiniMax-M3\.1-Flash\/blob\/262ae6830934f3512211081b8a3f16425b93a239/);
59
+ for (const name of ['index.html','style.css','budget.js','README.md','NOTICE']) {
60
+ const text=fs.readFileSync(path.join(root,name),'utf8');
61
+ assert.doesNotMatch(text,/rotem|nimrod|nimo|grabo|—/i,name);
62
+ }
63
+ });