Repository navigation
Releases: egatari/components
Release list
v2.1.1
Components 2.1.1, for Egatari Studio v0.6.4. Fixes only: no new part. One part's code changes (m-orbit 2.0.1); the rest is demos, a README marker and tests.
Fixed
m-orbit2.0.1: the person on Earth no longer spins a full turn on a step between two positions held at the same observer angle (e.g.start1 →visit[2] with 8 positions, both at evening). A full turn is added only when the step passes position 0 (new moon), e.g. 7 → 1 or 2 → 1.m-orbit's README closes its<!-- llm: omit -->block (the notes for authors at the end). Studio already read the unclosed block to the end of the file, so its AI instructions do not change.
Demos
m-timer: the first slide's body has a 10px inset, so the clock's 0 no longer sits on the left edge of Studio's part-list picture. The part is unchanged.m-tape: the demo opens with a two-row comparison (架空), which fills Studio's part-list picture; the □ equation follows.
Tests
tools/test-orbit.mjs: the observer angle through four steps ofm-orbit.- Lint: every
<!-- llm: … -->block in a README is closed by<!-- llm: end -->. - The subset reference (
tools/subset-produce.mjs) parses the slide source with parse5 8.0.1 and walks it in tree order (egatari-spec c6024bf). This is the reference for Studio's subset by name.
For Studio
- Pack bytes (
node tools/pack-bytes.mjs --base v2.1.0): onlym-orbitchanges, −504 bytes. The tool counted the unclosed block as visible; Studio already left it out. - README bytes since v2.1.0: m-bars 0, m-flow 0, m-menu 0, m-curves 0, m-quad 0, m-kpi 0.
sha256 29cfc2c344ddf4b785469e8634a7f7cf31e3d307e3bcf71ec4b6ed0166b9a6a7 egatari-components-v2.1.1.tar.gz
v2.1.0
Components 2.1.0, for Egatari Studio v0.6.4. New parts only. No part released in 2.0.0 changes, except m-keyboard, which is now 2.0.1 and gives a clearer error.
Added
m-cards2.0.0 (#142): 2–6 cards in a row, or in two rows withlayout="grid"(2×2, or 3×2 for 5–6 cards). Each card has a badge, an icon looked up by name, a title and a text, and the cards appear one per step.arrowsshows the order (Z order in a grid), andhilitemarks a card.- Japanese text wraps at likely phrase boundaries and keeps numbers with their counters. Text that does not fit is cut with … and reported.
- Variants: rise, fade and draw. Purposes:
processandgrouping.
- Library part
icons1.0.0: line icons by name, from Tabler Icons outline 3.49.0 (MIT, 4,808 icons). Brand and filled icons are left out.- The data is subset by name (spec §6.2
match: "name"). A lesson naming a few icons carries about 5 KB of the 870 KB set. buildis declared on the value the factory returns (spec 3d4ead0), and the manifest's library entry repeats it.- The MIT notice (
_notice) survives subsetting.
- The data is subset by name (spec §6.2
m-orbit2.0.0: the phases of the Moon and of Venus, as a top view beside the view from Earth. It sits in a new specialized set,science(理科), with a new purpose,model(仕組みをモデルで見る).
Changed
m-keyboard2.0.1: when keys are outsiderange, the error lists them and names a range that covers them all (e.g.use C4-D5).
For Studio
- Subset by name must land before lessons use
m-cards. Without it, a lesson carries the wholeiconsblock. The reference istools/subset-produce.mjs. For the current spec, including c6024bf (the slide source parsed by parse5 and walked in tree order), use its version onc2-base(c004416); it ships with the next release that changes a part. - Pack bytes (
node tools/pack-bytes.mjs --base v2.0.0):m-cardsadds 3,406 bytes andm-orbitadds 5,498 (both new). Every other part is unchanged. - README bytes since v2.0.0: m-bars 0, m-flow 0, m-menu 0, m-curves 0, m-quad 0, m-kpi 0.
sha256 53b86b055b6905b3aad26e88ab0222ab76f518c0ba4a005e6bb237b2e14760cc egatari-components-v2.1.0.tar.gz
v2.0.0
Components 2.0, for Egatari Studio v0.6.3 (its 2.0 host). Lessons built with Studio up to v0.6.2 keep 1.13.x.
- Parts are named, versioned files (spec §6.1). Every part is defined with
egatariParts.define({name, version, requires, element?}). Parts reach the player only through the context of §8.4 (ctx.report,ctx.lang,ctx.entered,ctx.reset,layout(ctx),ctx.extend…); they no longer use DECK globals. There are 36 element parts and 10 library parts. Formulas and music are rendered at build time (KaTeX, abcjs). m-kakijun's stroke data is cut down to what each lesson uses. - Part versions. Every part keeps its 2.0.0-rc.1 version and hash, except the five that changed since then:
m-timerandm-predict:layout(ctx), with focus kept;m-flowandm-quad: their text keeps clear of other text and lines (#140);m-cycle: the 1.13.1 fix.
These five are 2.0.1. A publishedname@versionnever gets a second hash (published.json, RELEASING.md).
- Manifest (spec §6 Registry manifest, egatari-spec 0fcc556): every part carries
license, andwithdrawnis listed per part version.kind,tierandsetare as in rc.1. - Viewer input: m-predict takes
input(choice, count). m-timer's ±1 min buttons work throughctx.extend. Both sendegatari-inputevents for the presenter's view.
Full list: CHANGELOG.md (2.0.0, 1.13.1, 2.0.0-rc.1).
README bytes since v2.0.0-rc.1 (Studio's free pack): m-bars +0, m-flow +0, m-menu +0, m-curves +0, m-quad +0, m-kpi +0. Pack-visible bytes (node tools/pack-bytes.mjs --base v2.0.0-rc.1): +0 for every part.
sha256 a6bf864ca7b4034af2125f2c8f67d51bb6671a9f7a8c543ca16d288f283bd7db egatari-components-v2.0.0.tar.gz
v1.13.1
A bug fix only (1.x takes fixes only until Egatari Studio v0.6.3).
Fixed
m-cycle: render writes an attribute only when its value changes. Writing the same value again still made Chrome repaint, and on macOS re-entering the same step moved two pixels on a box's edge by up to 54/255 while the DOM stayed byte-identical (Egatari Studio'stools/test-step-reset.mjs, demo slide 1 step 5; about 1 run in 3). The DOM at every step is unchanged.
Tests
tools/test-cycle-rewrite.mjs(intools/test-all.mjs): on every step of every m-cycle demo slide, entering the same step again makes no attribute mutation and keeps the DOM (19 steps; v1.13.0 fails all 19). Checked with a MutationObserver, so on every platform
Pack-visible bytes (Egatari Studio's AI pack), change since v1.13.0
Counted with node tools/pack-bytes.mjs --base v1.13.0: +0 for every part.
sha256 388604d82852a572e23a22d08017c13b033c3cbbcc741b821f02bcd1b54ef7ef egatari-components-v1.13.1.tar.gz
v2.0.0-rc.1
Pre-release for building Egatari Studio's 2.0 host (v0.6.3). Not for lessons: Studio up to v0.6.2 stays on 1.13.x. The final 2.0.0 ships with Studio v0.6.3.
2.0 alpha.3
Every element part is at 2.0.0: the six parts that drew math at play time move to build-time KaTeX (c2-a3a), and m-score joins with build-time abcjs, subset blocks, tiers and the manifest fields (c2-a3b); both follow egatari-spec ce96072, pinned once.
Summary
- 36 element parts at 2.0.0: alpha.2's 29, the six
texparts (m-collect, m-cycle, m-fishbone, m-flow, m-timeline, m-tree) and m-score. Library parts at 1.0.0: shape, base, plot, expr, markup-reader (new) and hist-core, boxplot-core, heatmap-core, kanbun-core, codetree-core. Identity: 50 decks (35 demos and 15 fixtures; m-collect's fixture replaces its demo), 4271 frames, 4982 component DOMs; DOM byte-identical but for 18951 ids rewritten as allowed, 1172 data scripts equal as data (DATA_REWRITE) and 2568 empty KaTeX classes (KATEX_EMPTY_CLASS), and m-score's 288 frames pixel-identical to cc0e60a. - Build-time formulas (c2-a3a; spec §6.2): each
texpart declaresstatic build = {fields: {…: "katex"}, options: {katex: {output: "html"}}}and draws the producer'stexHtmlthrough markup-reader 1.0.0, which admits exactly egatari-spec'sschema/rendered-markup-1.json(generated into it bytools/markup-sync.mjs), uses no browser parser, and reports drops once per instance and kind with the count; withouttexHtmlthe source shows as text and is reported.tools/katex-produce.mjsis the stand-in producer (KaTeX 0.19.0); identity compares the data as data (DATA_REWRITE), KaTeX's empty classes (KATEX_EMPTY_CLASS) and svg style text (KATEX_SVG_STYLE), approved by standards. m-collect's demo writes its data in the source; its fixture replaces the v1.13.0 demo - One spec pin:
tools/spec.json(egatari-spec ce96072, with the SHA-256 ofschema/rendered-markup-1.json, checked bytools/spec.mjs) replaces c2-a3b'stools/spec-schema.mjs; the two wrote under.spec/in different layouts and could remove each other's files. markup-reader's list is regenerated from ce96072 (paint onsvgandg,strokeontextandtspan) - One list: m-score requires markup-reader 1.0.0 and takes its
MARKUPfrom markup-reader's generatedLIST(svg entries). It keeps its own tree reader, which its step plan reads without a DOM. Still 288 of 288 frames pixel-identical to cc0e60a - Corpus tests on ce96072: KaTeX's 1209 formulas (html and htmlAndMathml) drop only their documented colour losses, and the pinned schema must still name them; abcjs's fixtures drop only text
font-familyandtext-decoration, which the pinned list must not admit - Subset reports: m-kakijun's stroke-meta block starts with
"_keys"(every published character; a subset keeps_members unchanged), so a character the subset left out is reported "no stroke data for "い" (not in this lesson's subset: …)"; one without data keeps the 1.13.0 message - Pack bytes (
node tools/pack-bytes.mjs --base v1.13.0): +0 for every part but the known deltas: m-codetree +119 (its README's 文脈木 / Context tree line), m-collect, m-flow, m-timeline, m-tree +22 and m-cycle, m-fishbone +32 (thetexHtmlandrenderersfields their shapes now allow), m-scatter −2 (alpha.2's README wording); m-score is new - Lint: 0 warnings (m-timeline's deduplicating reporter dispatches literal codes)
- Tests:
tools/test-c2-noreports.mjsplays once and waits until no font face is loading before it records (m-syntax reports measured sizes only once fonts are loaded); newtools/test-markup-reader.mjs,tools/test-katex-produce.mjs,tools/test-subset.mjs,tools/test-score.mjs,tools/test-score-noclass.mjs
c2-a3b in detail
- m-score 2.0.0 (new; never released in 1.x): the branch
m-scoremerged and migrated with the recipe (components/score/CHANGELOG.md). Its data format changed with egatari-spec 8a410b0 (renderers: {abcjs: {version, options}}at the top; the normative rendered-markup list), so by the identity rule (egatari-spec ce96072) it is compared at 0 pixels against cc0e60a, the last commit before that change (recorded in its CHANGELOG): all 288 frames equal (tools/test-c2-identity.mjs,tools/parts.mjsC2_BASELINE_OF). Abc without rendered output shows its source as text and is reported (spec §6.2 Missing output) - Rendered markup (spec §6.2, egatari-spec ce96072): m-score's reader list equals
schema/rendered-markup-1.json's svg part (paint onsvgandg,strokeon text, style shorthands,xmlnschecked and never set, drops reported once per kind); the spec file was pinned bytools/spec-schema.mjs(nowtools/spec.json, above);tools/score-fixtures.mjsrenders withforegroundColor: "currentColor"and leaves out abcjs's<style>,<title>and own attributes; the corpus test (with the new test-onlyfixtures/extras.json: dynamics, articulations, chord symbols, lyrics, title, tempo) fails on anything dropped but the expected losses (textfont-family,text-decoration) - Subset blocks (spec §6.2): m-kakijun's data are
/*@egatari-block strokes*/(OFL, the notice comment before it) and/*@egatari-block stroke-meta*/(MIT), both declared inbuild.subset(an array) with keychar, plusglyphs;tools/subset-produce.mjsis the stand-in producer (canonicalJSON.stringifyof the kept value,_members first, every byte outside the markers kept; recordssubset: {keys, sha256});tools/test-subset.mjs(in test-all). あさ: 35.3 KB, the demo: 64.5 KB, full: 207.9 KB - Tiers (owner decision, parts-tiers-2026-10-27 §1): README frontmatter
tier(standard/specialized/extra) and, for specialized parts,set(stats,math,maps,kokugo,english,music,business,tools), checked by lint; the manifest gives every partkind(element/library) and element partstierandset, plusdisplay,buildandglyphswhen the part has them; CATALOG.md shows 段 (標準・専門(束)・特殊) per part and a "By tier" table.seriesstays for now - m-codetree is shown as 文脈木 / Context tree (frontmatter
display, README, CATALOG.md); its tag and folder are unchanged - Lint: no warnings left: m-boxplot, m-heatmap, m-hissan, m-hist, m-kakijun and m-map-world forward their collected notes with a literal code per
ctx.reportcall
m-score before 2.0 (as on the branch m-score)
m-score(series music 音楽, purposemusic; not in the free pack for now): music notation per step, with sound. The first user of build-time rendering (components 2.0 design §4.1): the author writesabc(ABC notation); the build renders it with abcjs (add_classes: true) and addsabcSvg,abcMap(tempoin quarter notes per minute; per notecls,measure,pitch[],beatanddurin quarter notes,box;beamsas lists of note indices;arcs[{kind: "tie" | "slur", from, to, pitch?, n}], a tie per pitch, with the build tagging every drawn arc linedata-arc="n") andrenderer; the part carries no abcjs. Until Studio has that build step the data is written inline as the build would (the demo carriescomponents/score/fixtures/*.json, rendered with abcjs 6.7.2); data withabconly shows the placeholder. The SVG is not trusted: it is rebuilt from allowed elements and attributes only (no innerHTML or DOMParser; style, title, other colours, links and handlers dropped).by="note"(default; one note, chord or rest per step) orby="measure"; staff, clef, key and time signature from step 0; bar lines with the last note of their measure; elements found only by the build's tags, never by an abcjs class (clsstays in abcMap as the adapter's record):data-note="i"on each note and rest,data-beam="k"on each beam path (with the first note ofbeams[k]),data-measure="m"on each bar line (with the last note of its measure),data-arc="n"on each drawn tie or slur line (a tie with itstonote, a slur with itsfromnote); untagged elements show from step 0, and a note, beam or arc without a tagged element, or an unknown tag value, warns; a staff line is one child of the root svg.events(k): onenoteper pitch (vel0.7, a chord at one t),durfrom beats and tempo, a pitch tied by a tie arc sounding on past the end of its step (through a chain of ties), rests and the tied pitch at a tie'stosilent (so[C-EG] [CEG]sounds E and G again but not C).names="solfa|abc|iroha|none"(default none) under the noteheads at 26 px, from the frozen notehead boxes; chords top note first; a measure where any names collide puts all its names in a zigzag (odd notes on the upper row, even notes on the lower), other measures stay on one row. The current note in--emph, earlier ones--fg; under preview later notes at--preview-opacity. Readable layer 「楽譜:ド レ ミ ファ|…」, drawing aria-hidden. Variantlight. Demo: a scale, a rhythm exercise, かえるの合唱 (German folk song, public domain) by measure, and I–IV–V–Itools/test-score.mjs(intools/test-all.mjs): m-score without a browser on the fixtures: the SVG reader keeps only allowed elements and attributes, abcMap errors, steps by note and by measure, events (pitch, dur, chords at one t, notes of a measure at their beat, rests and ties), which note each SVG element appears with (from the data- tags only, the same with everyabcjs-*class stripped; untagged notes and beams, unknown and duplicate tags reported; the test-only fixturefixtures/ties.jsonhas ties in a chord, a chain of ties, a tie and a slur from one note, a chord tie and a slur across a line break, and a tie on one pitch of a chord, checked against the classes abcjs writes on each line), sound per pitch from tie arcs, note names and their placement (the zigzag of crowded measures), the readable layer, and the demo carrying the fixtures unchangedtools/score-fixtures.mjs: the stand-in for Studio's buil...
v1.13.0
Added
m-heatmap(series academic 数理・統計, purposescompare,correlation; paid packs only, not in the free pack for now): a grid of cells coloured by value, for confusion matrices, correlation matrices and attention maps. Child JSON{"rows": [labels], "cols": [labels], "values": [[…]], "unit"?, "digits"?, "highlight"?: [[row, col] or [row, col, step]]}(0-based; a row or column count that does not match the labels is an error and shows the placeholder). Colours are theme colours only, mixed withcolor-mix(in oklab, …, var(--bg)):scale="sequential"(default) from--bgtotone(termdefault,emph,accent2),scale="diverging"aroundcenter(default 0) withtoneabove andlowtone(emphdefault) below;range="[lo,hi]"fixes the scale (otherwise [min(0, smallest), largest], or symmetric around the centre). Cell colours follow the scale exactly (the colour is the data). Each cell's number is drawn in--fgor--bg, whichever has the higher computed contrast against that cell; where even that is under 4.5:1 (mid lightness) the number gets a 3 px halo in the other colour (paint-order: stroke). A legend bar on the right (min, centre, max).normalize="row"(proportions per row, confusion matrix; numbersshow="percent" | "count" | "both"),diag="on"(diagonal outlined in--fg), highlights outlined in--emph(both over a--bghalo),numbers="auto" | "on" | "off". Steps:build="rows"(one row per step; the default withnormalize="row"),"whole","cells"(the grid, then one highlight per step; the default with highlights). Labels at 26 px or 24 px, never smaller: long column labels turn vertical (rotate="auto" | "0" | "90"), and when there are too many only every k-th label is shown, with a warning; above 12×12 the cell numbers turn off automatically, with a warning, and they turn off whenever they would need less than 24 px. Row labels, column labels, the legend and the empty grid show from step 0; underctx.previewlater cells and outlines at the theme's--preview-opacity. Readable layer: a<table>of the values (the standard visually-hidden pattern: absolute, 1 px, clip, overflow hidden; highlighted cells marked); the drawing is aria-hidden. Variantsfade(0) andsweep(cells of a step from the top left, within the same step length)m-map-world(series social 社会, purposespatial; not in the free pack for now): the countries and regions of the world, the companion ofm-map-japan(docs/map-design.md). Equal Earth, central meridian 150°E (Pacific-centred only, map-design §6 2; the seam is at 30°W and a flow whose short way crosses it warns). Child JSON as inm-map-japan:regions(id= ISO alpha-3 / Natural Earth code / Japanese name, orgroup= the six regions 六州 from Natural Earth'sREGION_UN; overseas parts are coloured with the region of their geography: the overseas departments and territories フランス領ギアナ → 南アメリカ州 and レユニオン → アフリカ州, while parts of a country's own territory stay with it: ハワイ州 and アラスカ州 with the United States in 北アメリカ州, カナリア諸島 (an autonomous community) with Spain in ヨーロッパ州; Antarctica is in no region, grey, and named 南極大陸 withlabels="all"),categories(sets of countries with a legend, up to 4 series colours),values+classes(choropleth with a legend; classes as inm-map-japan),points,flows,shapes;grid="equator|graticule"; variantsfadesweepdraw; readable layer- Territory and names (map-design §4.5, §4.8; a fixed property of the data): data from Natural Earth 5.1.1's Japan point-of-view admin-0, so 北方領土・竹島・尖閣諸島 are Japan (竹島・尖閣諸島・沖ノ鳥島・南鳥島 drawn as dots of Japan); 南樺太 (south of 50°N) and the Kurils from 得撫島 north are cut out of Russia as 帰属未定地 (
XUD): ground-coloured, never coloured by a lesson, no name, with the four dashed boundary lines. Country names are the authorised-atlas names oftools/map/atlas-names.csv(15 differ from Natural Earth'sNAME_JA: 中国, 韓国, 北朝鮮, 台湾, ホンコン, …; ヴ is written with バ行 as in the atlases, dependencies too: イギリス領バージン諸島, アメリカ領バージン諸島). Taiwan is coloured with China in country colourings (regions,categories) and by its own value invalues(map-design §4.8.4) tools/map/build-world.mjs(withatlas-names.csvandworld.sha256): builds the embedded data (Visvalingam 22 km, 2 km for Japan and 帰属未定地; data block 54,568 bytes) and checks the owner of key points on the source and the final geometry;--cache <dir>downloads outside the repository.map-data-worldintools/test-all.mjschecks the block's sha256m-tree: branch labels and a highlighted path (GA item 7, owner-approved via standards). Nodebranchputs text on the link from its parent (a probability, a condition, yes/no): 24 px--fg, on the link into the child, clear of the line and of other labels (elbow: the bend moves to 20 px from the parent and the label sits on the longer last segment, above it withorient="right", beside it on the outer side withdown; the level gap widens to fit the labels anddownreserves their width beside the boxes; children are not folded into two rows;straight: beside the middle of the line on the outer side). Top-levelpath: ["root", …, "leaf"](parent to child from the root; otherwise the placeholder) is highlighted in--emph: a 6 px line traced over the link, a 4 px frame around each box it reaches, and that link'sbranchturned--emph; by default one link per step after the tree's last step (the step count grows), or all links in turn withinpathStep.pathNote(for example the product of the probabilities) appears beyond the last box (right of it withorient="right", below it withdown) at the box text size once the last link arrives; room for it is kept beyond the deepest level. The lecture view shows later steps' path at the theme's--preview-opacity. A tree without these fields renders as before (tools/test-default-variant.mjs). Demo slide 「確率の木:雨の日に遅れる確率」. Pack-visible bytes (tools/pack-bytes.mjs --base v1.11.0) +197 form-tree(one README bullet,branch?path?pathStep?pathNote?in the shape summary; details in anllm: omitblock); docs/conventions(.ja).md §2.2m-flow: decision nodes and loop-back edges for algorithm flowcharts (GA item 7, owner-approved via standards). Nodeshape: "diamond"draws a diamond inscribed in the node'sxywh(same tones,class="box"), and arrows are cut at its sides; yes/no go in the outgoing edges'labelas before. Edgeloop(true,"left","right","top","bottom";trueisrightwhen the ends are stacked vertically,bottomwhen side by side) routes an edge back to an earlier node around the outside instead of straight through boxes: it leaves and enters at the middle of that side of both boxes and runs 34 px beyond every box between the two ends (right angles), drawn from its start with the arrowhead riding its tip; itslabelgoes outside the long run (inside when outside would leave the figure),amountinside, andpulsedots follow the bends. Without these fields a lesson's DOM is byte-identical to v1.11.0 at every step in the talk and lecture views (checked on the v1.11.0 demo; m-flow has no variants, sotools/test-default-variant.mjsdoes not compare it). Demo slide 「1 から n までの和を求める手順」. Pack-visible bytes (tools/pack-bytes.mjs --base v1.11.0) −50 form-flow:shape:"diamond"(判断) andloop:true(戻る辺) named in the node and edge bullets, the details in anllm: omitblock, the shape schema unchanged; paid for by moving the colour bullet's history note (「v1.2.0 から。前は…薄かった」, not an authoring rule) into anllm: omitblockm-bars: negative values and 100 % stacked bars (GA item 7, owner-approved via standards). Negative values (bars that are not stacked): the value axis includes 0 and the bars grow from a--fgzero baseline, downwards (leftwards withorient="h") for negative values; ticks run both ways from 0 at the same interval and the 0 tick label follows the baseline; the range below 0 leaves room for the lowest bar's value label (40 px, or the label's width + 24 px across); value labels sit outside the bar end on its own side (above or right for positive values, below or left for negative ones), and so do series names. Before, a negative value drew no bar and its label fell below the axis; values that are all ≥ 0 render as before. 100 % stacked bars:stack="percent"divides each group's values by the group's total, on a 0–100 % axis (ticks with %), with each segment's share asdigits-digit % inside it, drawn only when its estimated text box (bold 24 px digit widths) fits inside the segment with at least 6 px on every side (ordinary stacks keep the v1.11.0 rule: under this rule the v1.11.0 demo would lose 「1.0」 and 「1.1」 of 卸 in 1 年目 and 2 年目, 31 and 34 px tall); the total at the bar end is not drawn (always 100 %).stackstays aboolprop ("percent"reads as true, so older releases draw an ordinary stack). Without these, a lesson's DOM is byte-identical to v1.11.0 at every step in the talk and lecture views (checked on the v1.11.0 demo; m-bars has no variants, sotools/test-default-variant.mjsdoes not compare it). Demo slide 「前の年からの増減と、答えの割合」 (both, side by side). Pack-visible bytes (tools/pack-bytes.mjs --base v1.11.0) −12 form-bars:"percent"named in the stack bullet, negative values and the details in anllm: omitblock, paid for by shortening the stack bullet's usage example
Tests
tools/test-heatmap.mjs(intools/test-all.mjs): m-heatmap's scale mapping (sequential, diverging, centre, clamping), row normalisation, the per-cell text colour and halo over full ramps (no browser), label thinning and rotation, number sizes and steps; in a browser in the default, kokugo and business themes, cell colours equal the scale exactly, every cell's number ≥ 4.5:1 against its own cell or its halo (the halo case occurs and reaches 4.5:1 against the text), fills onl...
v1.12.0
Added
m-syntax(series english 英語, purposetext-structure; not in the free pack for now): English sentence structure for 中学・高校 English lessons, the English counterpart ofm-kobun/m-gendai. Short marked-up text inside the element, one sentence per line,= …the Japanese translation of the sentence above.[S …] [V …] [O …] [C …] [M …](alsoO1O2) mark the sentence elements: an underline under the words and the letter under it (28 px; colours--series-1..4, M--muted, the letter always carries the role); elements inside a bracket show in lower case (s v o c m) one row above, so the sentence's S V O C line up on one row.{形 …}{副 …}{名 …}mark phrases and clauses, drawn as ( ) < > [ ] (shape and name both carry the kind) with the name (形容詞句, 副詞節, …, 24 px) above the opening bracket; 句 or 節 is decided by a[V …]inside, or written ({形節 …}). Modifier arrows (--emph):{形^ …}to the word before the bracket,tall^to the next word,{副^plays …}to the nearestplaysoutside the bracket; overlapping arrows take separate lanes, arrows to one word are spread over its width.boy[名]parts of speech (名 代 動 助 形 副 冠 前 接 関 間), shown under the words withpos="on". Steps: (parts of speech) → each element present, in the order S V O C M (shared by all sentences) → brackets (with the lower-case elements inside) → arrows → translation;build="whole"puts them all in one step, one after another;yaku="false"drops the translation step. Words are HTML invar(--font-sans)(36 px by default, never below 27; translation 28 px) and wrap between words; the space for brackets is kept from step 0 so the sentence never moves, underlines are cut per line and brackets stay beside their words across a wrap. Writing errors (unclosed or crossed brackets, unknown letters, kinds or parts of speech, an arrow head not found, a translation before any sentence), an arrow across lines and a sentence taller than the element are reported withconsole.warn. Lecture view: later steps at the theme's--preview-opacity. Readable layer (sr-only): sentence, elements, brackets, arrows, parts of speech, translation. Variantsfade(0) anddraw(underlines, brackets and arrows drawn as lines). README pack-visible 941 bytes (tools/pack-bytes.mjs)- Series
english(英語, a subject series like kokugo and music) intools/lint.mjs(SERIES,SERIES_LABEL) and CONTRIBUTING. No new purpose:m-syntaxdeclarestext-structurelike the kokugo parts (pending the owner's and standards' approval)
Fixed
m-predict,m-timer: viewer input follows egatari-spec §8.4 (881bf76):ctx.reset(a touched part entering a step) no longer clears the counts, the learner's prediction or the ±1 分 extension; it only drops focus inside the part. Viewer input is cleared only on the render withctx.entered, or, with a player that never passesctx.entered, whendeck:posshows the slide entered from another slide. With Studio main@03eaf06 (which resets touched parts on every step entry) a prediction or count clicked at step 1 used to be gone at the answer step.m-timeralso no longer re-applies a storedctx.resetwhen it redraws after ±1 分. Notes in the READMEs'llm: omitblocks only: pack-visible bytes +0 for both (tools/pack-bytes.mjs)
Tests
- The tests pin Egatari Studio by commit instead of by tag:
tools/studio.jsonholds the full sha (now03eaf06on Studio'smain, was v0.4.38419183), andtools/studio.mjsfetches exactly that commit (shallow fetch by sha), checksHEADand refuses a short sha.EGATARI_STUDIO=still uses a checkout of your own. The overlay goes tovendor/components/<name>/0.0.0-test/, the default incomponents.lock.json tools/test-studio-check.mjs(intools/test-all.mjs): Studio's own checker (kit/check.mjs) on every demo; any error fails, R-narr-steps warnings are ignored (demos have no narration), other warnings are listedtools/test-contrast.mjs: the business theme's--emphknown issue is gone (business 1.0.1 reaches 4.66:1);tools/test-predict.mjs: digits typed into a counter (Studio #69) are now testedtools/test-predict.mjsandtools/test-timer.mjs: real clicks with the pinned Studio (touch, next step, answer step keeps the value; a jump away and back clears it);ctx.resetkeeps viewer input,ctx.enteredclears ittools/test-syntax.mjs(intools/test-all.mjs): reading the mark-up (words and punctuation, roles and O1/O2, lower case inside brackets, nested brackets and 句/節, arrows to the next / previous / named nearest word and their lanes, parts of speech, translations), every writing error's warning, the steps (order S V O C M, two sentences sharing a step, pos, yaku, build="whole"), and in a browser: the arrow ends on top of its head word and starts on its bracket's name, brackets between the right words, the clause's s above the sentence's S, underlines and brackets across a wrapped line, console.warn for errors and for an arrow across lines, the readable layertools/test-shape.mjs: m-syntax's wrong-shape case (JSON instead of text);tools/variant-sync.mjsUSERS: syntax
Pack-visible bytes (Egatari Studio's AI pack), change since v1.11.0
Counted with node tools/pack-bytes.mjs --base v1.11.0.
- Free core (
m-bars,m-flow,m-menu,m-predict): +0 each - Free by subject (
m-curves,m-kpi,m-quad): +0 each - Kokugo (
m-gendai,m-kanbun,m-kobun): +0 each - New, paid only:
m-syntax941; every other part +0
sha256 2ca2387ce51c7943192e60a4e205eb02c0a21ba1aea67ec82049406c066b20bd egatari-components-v1.12.0.tar.gz
v1.11.0
Added
m-keyboard(series music 音楽, purposemusic; not in the free pack for now): a piano keyboard for school music lessons. Child JSON{"range": "C4-C6", "names": "solfa" | "abc" | "iroha" | "none", "cumulative": bool, "dur": s, "steps": [{"keys": ["C4", "E4", "G4"], "label", "t": [s per key], "tone", "dur"}]}.rangecovers 1–3 octaves (12–36 semitones) and starts and ends on white keys; the part draws its own SVG keyboard: white keys as rectangles, black keys 0.58 wide and 0.62 long, on top, centred as on a real keyboard (the C–E group split into fifths and the F–B group into sevenths: C♯/D♯ and F♯/A♯ lean outwards, G♯ is centred). White-key names under the keyboard (ドレミファソラシ, CDEFGAB or ハニホヘトイロ); black-key names (ド♯ / C♯ / 嬰ハ, レ♭ / D♭ / 変ニ) only on lit keys, above the keyboard (a second row when two would touch). Each step lights its keys in--emph(or the step'stone) with a filled dot; a lit black key keeps its dark rim around the coloured inside;cumulative: truekeeps earlier steps' keys lit, faded, with a ring instead of the dot (never colour alone). Per-keytstaggers a scale or arpeggio, equaltis a chord.events(k)(spec §8.4 "Component sounds"): onenoteper key,pitchthe key name,vel0.7,durfromdur(step, then top level) or else to the next latert(0.8 s for the last);duration(k)reaches the end of the last note. Sound is never the only carrier: the lit keys show the same. Step labels 30 px above the keyboard. The lecture view (ctx.preview, orctx.mode === "lecture"from older players) shows later steps' keys faint without the dot, at the theme's--preview-opacityread with getComputedStyle (spec §8.4 "Answers under preview"; 0.45 only when the variable is missing). The part has no controls. Variantslight(0, the light fades in),press(the key dips 4 px and comes back),rise(the light fills the key from the bottom), all within 0.3 s and within the note. Range, key-name andt-length errors show the placeholder- Series
music(音楽, a subject series like kokugo) intools/lint.mjs(SERIES,SERIES_LABEL) and CONTRIBUTING; purposemusic(「音楽(音の高さ・和音・リズム)」 / "Music (pitch, chords, rhythm)",tile: "none"liketext-structure, icon keymusic) inpurposes.jsonand docs/conventions(.ja).md §4.tools/lint.mjsnow also fails when a series has no label tools/test-keyboard.mjs(intools/test-all.mjs): m-keyboard's key geometry without a browser (black-key centres 0.9, 2.1, 3+6/7, 5, 3+22/7 in white-key widths, width 0.58, over the line between their two white keys, the same offsets in every octave and from a range starting on D), key names (solfa, abc, iroha with 嬰・変, none, ♯ and ♭, E♯/B♯/F♭/C♭ refused), the events per step (a chord at one t, a scale with increasing t, pitches, dur to the next t or 0.8 s, step dur and top-level dur, the step length), the key state per step and time (current, cumulative, and the lecture preview: later steps faint, the current step's unlit keys and keys lit now not marked) and the range errors (one key, not key names, black ends, under 1 or over 3 octaves, backwards)tools/test-keyboard-preview.mjs(intools/test-all.mjs): m-keyboard's lecture preview in a browser: later steps' keys faint without the dot at the theme's--preview-opacity(0.45 when missing; 0.3 when set), also withctx.mode === "lecture", keys lit now unchanged, nothing without previewtools/test-shape.mjs: m-keyboard's wrong-shape case (notesinstead ofkeys)m-timeline: project-plan (Gantt) features, as an extension of the timeline (standards decision, owner-approved; not a new part). Nodeafter: ["id", …]draws a finish-to-start arrow (--muted, 3 px, right angles) from the end of each predecessor to the start of the dependent item, in the step where the dependent item appears, drawn while it appears; vertical runs are placed so as not to cross other bands or their names where that is possible; a dependent that starts on its predecessor's end day is entered from its edge near the start. With anyafter, each item of a lane gets its own row (author order). Nodeprogress(0–100) fills the band from its start in a stronger tone, with the % after the name when it fits (24 px). Attributetoday="2026-11-02"draws a vertical--accent2line with 今日 / Today (with periods only). Attributeunit="day" | "week" | "month"chooses the axis ticks: labels at the finest interval whose 24 px labels do not overlap, short unlabelled ticks between, weekends shaded lightly in day mode; withoutunitthe ticks are as before. A lesson that uses none of these renders as before (tools/test-seed0.mjs). The today line is drawn beneath the bars and their names, so it never strikes through bar text. Demo slide 「アプリ開発の工程表(架空)」. Pack-visible bytes (tools/pack-bytes.mjs) +278 form-timeline(README one bullet, theunit/todayprop docs,after?progress?in the shape summary; details in anllm: omitblock)tools/pack-bytes.mjs: the pack-visible bytes of each component (README outsidellm: omitwithout lines about demo.html, examples/, tools/ or the motion-components skill; frontmatter name, summary, steps; each prop's type, default and doc; the shape summary), at a git ref or the working tree, with--base <ref>for the difference to report in release notestools/test-timeline-gantt.mjs(intools/test-all.mjs): arrows start at the predecessor's end and end at the dependent's start with right angles and without crossing bands, the progress fill is progress % of the band, the today line sits at the date's position, and day / week / month tick labels do not overlap and stay at 24 px (the demo's plan and four made-up cases, includingorient="v")m-kakijun(series kokugo 国語, purposeprocess; not in the free pack for now): stroke order (書き順) of kana.text="あさ"(ひらがな・カタカナ, 濁音・半濁音, small kana, ー; 166 characters), one step per character with its strokes drawn one by one within the step (about 0.6 s a stroke, scaled by its inked length;per="stroke": one step per stroke; cues at each stroke start). The shapes are derived from strokesvg (Klee One), SIL OFL 1.1:data/kana/strokes.ofl.json, embedded verbatim (its_licensefirst) in index.js as the only thing between/* BEGIN OFL-1.1 data … */and/* END OFL-1.1 data */; the part's licence isMIT AND OFL-1.1(READMElicense:, manifestcomponents.kakijun.license), withOFL.txt,LICENSE-strokesvg.txtandstrokes-CHANGES.mdin the part's folder and aNOTICEentry (Studio inlines only a part's index.js, so a separate data file cannot ship yet). Each stroke is drawn as strokesvg does (data/kana/proto.html): a round brush along the centreline, clipped by the stroke's own outline, advanced by dash offset, no fleck behind the start; finished strokes in full, nothing of a later stroke early.grid="cross" | "none"(box with dashed 十字 guides),ghost(unwritten strokes faint),nums(circled stroke numbers at each start, 24 px, placed off each other, off the ink and without crossing leaders),ends="on"(とめ・はね・はらい at each end, 24 px, with a dotted leader when moved away),writing="tate"(top to bottom, columns right to left, boxes of a column touching; small kana in the upper-right quarter, lower-left in horizontal writing; a small kana's numbers and ending labels stay inside its own square on the empty side, and other characters' labels keep out of it; a warning when they cannot fit),size. A character without data warns and is drawn plainly in the theme font. The drawing is aria-hidden; accessible name 「あさ(書き順)」 and a readable layer (characters, stroke counts, endings) in real kana. Underctx.preview, later steps at the theme's--preview-opacity(0.45 without it). Variantsdraw(the default, first),pen(no fade: the order and direction are the content); the chooser is the seedless one. The part is about 210 KB (the shapes about 175 KB) Without numbers and ending labels (nums="off", noends), the margin around the boxes shrinks from 36 to 8 px.tools/kana-embed.mjs: writescomponents/kakijun/index.js's two data blocks (kakijun-data, MIT: count, ends, place and each stroke's inked length fromdata/kana/kana.json; the OFL-1.1 data between/* BEGIN OFL-1.1 data … */and/* END OFL-1.1 data */:data/kana/strokes.ofl.jsonverbatim) and copies the licence files into the part's folder;--checkcompares themtools/test-kakijun.mjs(intools/test-all.mjs): both embedded blocks equal the data files (the OFL block verbatim,_licensefirst) and the licence files are in place; for all 166 characters the final state covers 100 % of the outlines and nothing outside them, and in the middle of a stroke the ink stays inside the outlines drawn so far (no bleed); small kana inside their quarter in both writings, and their labels inside their own square on the empty side; the OFL-1.1 data markers and the manifest licence; steps, unknown characters, the accessible name and readable layer in real kanaNOTICE: lists the licence of m-kakijun's stroke shapes (SIL OFL 1.1) next to the repository's MIT licence; README.md / README.ja.md say thatcomponents/kakijun/index.jscontains an OFL-1.1 data block- README frontmatter
license:(optional SPDX expression,MIT AND <id>; checked bytools/lint.mjs, the licence text must be in the part's folder) goes into manifest.json ascomponents.<name>.license(tools/release.mjs)
Changed
- Visible change: preview views. In the lecture or preview view (
ctx.preview, orctx.mode === "lecture"from the current bundled player) every component exceptm-predict,m-hissanandm-timernow shows its later steps faintly, at the theme's--preview-opacity; 13 components do so for the first time and the others change how faint they are (details below). Talk, learn and video views are unchanged m-predict,m-hissan: visible change. Under previ...
v1.10.0
Added
m-numberline(series academic 数理・統計, purposecompare; not in the free pack for now): number line.lines(1 or 2;from,to,step,sub,label,unit,labels: "all" | "ends" | "none" | [values]; by default both line ends are always labelled and only the generated labels between them are thinned, never a label the author named); values are numbers or fractions written"1/3", computed exactly and drawn as stacked fractions (numerator and denominator 24 px), negative numbers with the minus sign (−).marks(dot,open,box= □),jumps(arcs with arrowheads, either direction; nested arcs are raised above the inner arc and its label),ranges(incl: [bool, bool], a missing end runs to the edge with an arrow; overlapping ranges at stacked heights, the shared part drawn thick on the line and shaded), two lines aligned at 0 (比例数直線) withlink(dashed correspondence lines, or an arrow with a label such as 「×3」),magnify(an interval grows into a longer line drawn below, with funnel lines; 10 subdivisions by default; a second entry magnifies the first, 0.1 → 0.01; the motion is a part effect, the same in both variants).buildorders the kinds (defaultticks,marks,links,jumps,ranges,magnify, one item per step) orwhole; an item'sshowsets its step.arrow="on". Variantsfade,draw. The draft namezoombecamemagnify(m-bars already haszoom)m-tape(series academic, purposespart-whole,compare; not in the free pack for now): tape diagram (テープ図) and line-segment diagram (線分図,kind="line").rows: [{label, segs: [{v, label, unknown: "?" | "□"}]}]on one shared scale (an unknown segment still has itsv; otherunknownvalues warn and draw "?"),brace: [{row, from, to, label, side: "above" | "below"}]over segment numbers (nested braces stacked),times: [{from, to, label: "2 倍"}]between rows (drawn at the rows' left ends, which always line up).build="steps"(rows, then braces, then arrows, one per step),rows(annotations with their row) orwhole;showper item. Variantsfade,growtools/test-numberline.mjs(intools/test-all.mjs): m-numberline's geometry without a browser: fractions and decimals, tick positions and labels (common denominator, no trailing zeros, the minus sign), sub-ticks, two lines aligned at 0, splitting labels into text and stacked fractions, label thinning (line ends, named labels and □ marks are never dropped), range and jump levels, the shared part of ranges, arc heightsm-hissan(series academic 数理・統計, purposeprocess; paid packs only, not in the free pack for now): written column arithmetic (筆算) as taught in Japanese elementary school. The author writes onlyexpr(487+356,1003-457,38×24,851÷23,3.6×2.4,7.56÷1.8;*and/accepted) and the part computes and writes every step. + and −: one step per place from the ones, くり上がり as a small 1 in the column it goes to, just above the answer line (carry="top": above the first number), くり下がり as a slash, the reduced digit small above and the borrowed 1 at the left shoulder of the receiving digit (beside its reduced digit when it has one, reading 「12」), chained through zeros as in the textbook (1003−457), leading zeros of the answer not written, decimals aligned at the point with zeros appended where the first number is short. ×: one partial product per multiplier digit (fine="on": digit by digit with small carries), shifted by place, the zero row of a multiplier skipped, trailing zeros of integers set out to the right and brought down (340×26), decimals multiplied as integers and the point placed by counting both factors' decimal places (labels and numbered arcs), trailing zeros after the point struck. ÷: the Japanese layout (divisor, 「)」, bar, quotient above), the quotient starting above the first digit where division is possible, rounds of たてる・かける・ひく・おろす (per="round", default: one step per quotient digit, the step name changing within the step;per="phase": one step each),kari="on"(for the first round whose estimate is off, the divisor rounded to the nearest ten (23→20, 27→30): each try written, multiplied (and subtracted when too small; a too-big product wider than the partial dividend, such as 126 under 99, is given in the words only so that no column is reserved), crossed out and corrected by 1 with words saying why: 「ひけないので、1 小さくする」 or 「あまりが 27 より大きいので、1 大きくする」), a decimal divisor's point moved with arrows and the dividend's moved the same (zeros appended), the quotient's point above the moved point,rem="on"(the remainder read at the dividend's original point: 7.5÷2.3 = 3 あまり 0.6) ordigitsdecimal places (integers default to the remainder; decimals withoutdigitsrun until exact within the slide body's height, with a warning if they do not end).build="steps" | "whole",focus(a tint on the place or row being worked), step words beside the figure (words="off"hides them). All SVG text (52 px digits, 26 px small marks, nothing below 24 px), no KaTeX. Variantsfade,drawtools/test-hissan.mjs(intools/test-all.mjs): about 20,000 checks over a sweep of exercises (2–4 digit + and −, borrowing across zeros, 2–3 digit × 1–2 digit with and withoutfine, decimals × decimals, ÷ by 1- and 2-digit divisors with and without remainders and todigitsplaces, decimal ÷ decimal, 仮の商 rounds too big and too small by 1 and by 2): the written answer, partial products, rounds (P − q×d = r) and remainders reproduce exact arithmetic, and every digit stands in the column of its place, the quotient digits above the right dividend digitstools/test-shape.mjs: a part whose data are attributes only can give its whole element as the wrong-shape case (m-hissan:digits="2けた");m-hissanexpressions that are not one calculation and negative differences show the placeholder
Changed
- Previewing later steps (egatari-spec §8.4): it is now a flag,
ctx.preview === true, andctx.modeis "talk" | "learn" | "video". The 13 components that showed later steps faintly whenctx.mode === "lecture"(m-boxplotm-comparem-cyclem-fishbonem-histm-map-japanm-menum-piem-predictm-scatterm-timelinem-treem-venn) now testctx.preview || ctx.mode === "lecture", so they work with the current bundled player and the next one (m-predictalso keepspreviewin the context it re-renders with after input). Drawing is unchanged in every mode the pinned Studio v0.4.3 passes. READMEs, docs/conventions(.ja).md and docs/input-components.ja.md sayctx.previewinstead of?mode=lecture/lecture. Pack-visible README text:m-cyclem-fishbonem-piem-scatterm-timelinem-tree−2 bytes each; the other changed lines are inllm: omitblocks (pack-visible bytes unchanged) m-timer: visible change. The built-in Japanese label at the end of a phase is now 「時間」 (was 「時間です」): slides are written in plain style, and Egatari Studio's checker flagged it (R-style). Lessons that setlabels.done(or the olddone) are unchanged; lessons pinned to an earlier version keep 「時間です」. English unchanged.m-timerhas no variants, sotools/test-seed0.mjsdoes not compare itm-predict: visible change. The −1 / +1 buttons and the count field use 27 px text (was 26 px). Egatari Studio's checker requires at least 26.6 px for HTML text outside tables and figures (smallText, R-fit) and flagged the buttons on every slide. Buttons and field keep their size (60 × 48 and 80 × 48 px).tools/test-seed0.mjscomparesm-predictwith releases before 1.10.0 with its controls hidden (the drawing must still be pixel-identical)m-timer: the +1 min / −1 min buttons use 27 px text (was 26 px), for the same checker rule. They appear only when the player passesctx.extend(not in the pinned Studio v0.4.3), so no demo or test screenshot changes; button size unchanged (at least 112 × 52 px)
Fixed
- Demos flagged by Egatari Studio's checker (Studio 77588a4,
kit/check.mjs):m-boxplot's first conclusion line was 36.5 units long (limit 35, R-concl), now 「→ 小さい順に並べ、中央値と前半・後半の中央値(四分位数)で箱にする」 (34.5);m-predict's body ran 9, 7 and 17 px past the conclusion line on its three slides (R-fit), the elements are now 390, 440 and 2 × 210 px high (were 400, 450, 2 × 220);m-timer's 「時間です」 (above);m-timer's second demo slide setslabelsin plain style, 「合図で始める」 and 「そこまで。次へ進む」 (were 「合図で始めます」 and 「そこまで。次へ進みます」; the checker only sees the final state, so it did not flag them)
README size (Egatari Studio's free-plan pack), change since v1.9.1
m-barsREADME: 0 bytesm-flowREADME: 0 bytesm-menuREADME: 0 bytesm-curvesREADME: 0 bytesm-quadREADME: 0 bytesm-kpiREADME: 0 bytes
(New, not in the free pack for now: m-hissan 952 bytes, m-numberline 1013 bytes and m-tape 972 bytes of README text outside the llm: omit blocks.)
sha256 bf11ca819221e8014f65ca00405149c6972ad512967f490426c036c8c44d5338 egatari-components-v1.10.0.tar.gz
v1.9.1
Changed
- README text only, no code or behaviour change (Egatari Studio's free ja kokugo pack, with
m-predictadded to its core, was 40.2 KB against the 40 KB cap):m-kobun's section 「押すと出る札」 (a player interaction) and, inm-kanbun, the line on the 明朝 font and the console warning for不without{=ず}move intollm: omitblocks. They stay for human readers. Pack-visible text:m-kobun−645 bytes,m-kanbun−163 bytes
README size (Egatari Studio's free-plan pack), change since v1.9.0
m-barsREADME: 0 bytesm-flowREADME: 0 bytesm-menuREADME: 0 bytesm-curvesREADME: 0 bytesm-quadREADME: 0 bytesm-kpiREADME: 0 bytes
(Free ja kokugo pack: m-kobun −645 bytes, m-kanbun −163 bytes.)
sha256 c256a472d47ac6ec5228a31f0776da7fc781b6817cbe6d1682cbe12c9aea58c6 egatari-components-v1.9.1.tar.gz