npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@austencloud/tka-pictograph

v0.2.1

Published

Draws The Kinetic Alphabet's pictographs as SVG, in Node or a browser, from Austen Cloud's own renderer and art.

Readme

@austencloud/tka-pictograph

Draws The Kinetic Alphabet's pictographs as SVG: the grid, props, arrows, turn numbers and letter, from Austen Cloud's own renderer and art. The same renderer makes the pictographs in the TKA knowledge server. It runs in a browser, a desktop webview or Node, and works offline.

Use

import { pictographsForLetter, renderPictographSvg } from "@austencloud/tka-pictograph";

const [a] = pictographsForLetter("A", { start: "alpha" });
const svg = await renderPictographSvg(a, { darkMode: true, leftPropType: "staff", rightPropType: "staff" });

renderPictographSvg returns an SVG document 950 units square (PICTOGRAPH_VIEWBOX). Put it in the page as markup or as an image source.

A pictograph is a PictographInput: the letter, the start and end placements, the grid mode, and one MotionInput per hand (motion type, rotation direction, start and end location, turns and start orientation). End orientations are worked out when they are left out. pictographsForLetter returns every version of a letter from the TKA dataframe with no turns and both props starting in; start keeps those that start at one placement ("alpha3") or a group ("alpha").

handColor(hand, darkMode) gives the colour each hand is drawn in, so the rest of an app can match.

Laying TKA out

These are the canonical layouts, the ones the Flow Arts Composer, the Codex and the guide use. An app that shows TKA follows them rather than wrapping pictographs or letters to whatever fits, so the alphabet looks the same wherever it appears.

  • Letters. LETTER_ROWS is the alphabet in the Codex's rows: Dual-Shift six to a row (A-F, G-L, M-R, S-V), Shift and Cross-Shift four (W-Z, Σ Δ Θ Ω, and their dash forms), Dash, Dual-Dash and Static three. A letter picker draws these rows as they are, on a grid LETTER_ROW_COLUMNS (6) wide, each row under its type's name in TKA's colours (getColoredTextParts). renderLetterSvg(letter) draws a key's letter, dash included. alphabetSections() groups the same letters by type.
  • A sequence. The start position takes column 1 of the first row. The beats fill the columns beside it in the rows getStepFrameLayout(beats, wide) gives: 16 beats are 4 by 4 in the standard table and 2 rows of 8 in the wide one. Use the wide table where width is plenty and height is short, such as a strip under a stage. calculateStepPosition(i, columns) places beat i. The count is the sequence's beats, so the shape of the grid shows the shape of the sequence: a quarter-turn loop of 16 reads as four rows of four.
  • A sequence that comes round more than once. When a sequence only closes after playing it again (rotated, mirrored or swapped), show the beats it plays to come round as well, in the same grid and counted in its layout, drawn apart from the written ones (faded, dashed edge, not pickable) so it is plain they follow from the written beats and change when those do.
  • Reversals. A hand reverses on a beat where its prop spins the other way from the last beat it spun in, and each hand is judged apart. markReversals(beats, { loop }) sets each beat's leftReversal and rightReversal by the Composer's rule (a looping sequence reads round its seam), and renderPictographSvg(beat, { showReversals: true }) draws them as the Composer does: a dot in the hand's colour at the left edge, red above blue when both reverse. Show reversals this way, never as one mark for the whole beat that cannot say which hand turned.
  • The letters that can come next. sectionsByLetterType gives one section per type in compareOptionLetters order. Each type takes a row of optionColumns(width) (eight on a wide picker, four otherwise), and Types 4, 5 and 6 share the last row (type456Columns).
  • Changing a whole sequence. transformBeats(beats, change) mirrors, flips, rotates an eighth (onto the other grid), swaps hands, inverts or rewinds, and reletters each beat from the dataframe, as the Composer's sequence tools do.
  • Elements. ELEMENTS holds the six TKA elements, one per timing and direction between the hands (Earth together-same, Air together-opposite, Water split-same, Fire split-opposite, Sun quarter-same, Moon quarter-opposite), each with its colour and the path of its icon in the art (images/elements/norm/water.webp, the app's icon with its code, SS, drawn in). elementOf(beat) reads a beat's element from the hands' paths round the grid, so it works on the diamond and the box; a static or dash hand has none. renderPictographSvg(beat, { showElemental: true }) draws the hands' element in the bottom-right corner, as the TKA app does. Show an element with its icon and colour, never its timing and direction alone.
  • Playing a sequence. While a sequence plays, exactly one tile is lit: the beat being played. When playback reaches a beat the sequence plays to come round, the copy lights in place of the written beat it repeats, never alongside it, so the eye follows one tile at a time.

Generate

A second entry makes sequences the way the Composer's Generate tab does, with the same engine. It is a separate bundle (about 690 KB, 83 KB gzipped, with the diamond and box dataframes and the letter mappings inside), so an app that only draws never loads it.

import { generateSequence } from "@austencloud/tka-pictograph/generate";
import { renderPictographSvg } from "@austencloud/tka-pictograph";

const result = generateSequence({ length: 16, level: 2, loop: { kind: "rotated" }, seed: 42 });
if (result.ok) {
  const svg = await renderPictographSvg(result.beats[0]);
} else {
  console.log(result.why, result.suggestions);
}

Nothing here throws for a request that cannot be met. It returns { ok: false, why, suggestions }, with why a sentence a person can read and suggestions what would make it work, when that is known.

  • generateSequence(options) returns { ok: true, start, beats, bridges, word, loop }. start is the start position and beats the beats, each a PictographInput with turns and orientations filled, ready for renderPictographSvg. bridges lists the beats added to join two letters of a word. word is the sequence's letters. loop, for a LOOP, gives its kind, its period, the seedWord that repeats, the derivedWord it adds to come round, and derived, the beats it added.
  • minimumLength(options) is the fewest beats the options allow, such as 8 for a quartered rotated LOOP at level 2.
  • nextLetterOptions(beats, { grid }) is every pictograph that can follow the last beat: those that start where it ends, carrying its orientations on. It is the rule the Composer's option picker uses.
  • wordFeasibility(word, { grid, handPath, propSpin }) reads a word into letters and says whether it can keep the hand path and prop spin asked for (fits), with the fewest and most reversals it needs or allows.

The options, all optional except a length or a word:

  • length: how many beats, not counting the start position.
  • word: a word to spell, such as "ABC", "AΣ-B" or "A sigma B". With a LOOP, the word is what repeats. Letters are joined with bridge letters where they do not meet.
  • level: 1 has no turns, 2 adds whole turns, 3 half turns too, 4 everything. Defaults to 1.
  • turnIntensity: the most turns a prop takes in one beat.
  • matchHandTurns: give both hands the same turns on every beat.
  • turnPattern: turns to repeat instead of choosing them, per hand, such as { left: [0, 1], right: [0.5] }. "fl" is a float.
  • grid: "diamond" (the default) or "box". The skewed grid is not available yet and returns ok: false.
  • handPath: how often the hands' paths turn back: "smooth" (never, the default), "mixed" or "choppy" (every beat).
  • propSpin: the same for the props' spin.
  • dashes: dash beats "allow"ed (the default), "avoid"ed or "prefer"red.
  • handRelationship: timing and direction between the hands: "free" (the default), or T, S or Q (together, split, quarter) followed by S or O (same, opposite), such as "SO".
  • propRelationship: the same between the props' spins.
  • start: the placement to start from, such as "alpha1".
  • blockedStarts: placements never to start from.
  • ends: placements the last beat may end at. Any, when empty.
  • mustContain and mustNotContain: letters that must or must not appear.
  • startOrientation: which way each prop faces at the start, { left, right }, each "in", "out", "clock" or "counter". Defaults to in.
  • allowStatic: allow static letters as beats when they carry turns. Defaults to true.
  • layerPattern: which layers the props pass through, written like "1:.XB.". Needs level 3.
  • loop: make the sequence a LOOP:
    • kind: what it does each time it comes round: "rotated", "mirrored", "flipped", "swapped", "inverted" or "rewound", or a combination such as "mirrored_swapped" or ["mirrored", "swapped"].
    • period: "halved" comes round twice (the default), "quartered" four times. Only rotation quarters.
    • inversionInterval: how many repeats an inversion takes to come back, 2 or 4.
    • inversionMode: "expand" adds the inverted repeats; "overlay" inverts repeats in place.
    • reflectionAxis: the axis a mirrored LOOP reflects across.
    • spec: a full per-hand spec, used as given in place of the settings above.
  • seed: a number. The same seed and options give the same sequence.

Art

The art ships in the package's assets/ folder, about 5 MB, and loads only when a pictograph needs it.

  • Default: with no art option, files are fetched from assets/ next to the package's dist/. This works in development and in Node.

  • A production web build: copy node_modules/@austencloud/tka-pictograph/assets/ into your public folder and pass its URL:

    import { urlArtSource } from "@austencloud/tka-pictograph";
    const art = urlArtSource("/tka-pictograph/");
    await renderPictographSvg(input, { art });

    Reuse one source; it caches what it has fetched.

  • Node, from disk: const art = await fsArtSource(pathToAssets).

  • Your own source: any object with read(path): Promise<string | null>, returning null for a file that does not exist.

License

The code (dist/) and the placement data (assets/data/) are Elastic License 2.0; see LICENSE. Austen Cloud's MIT-licensed render-core calculations are bundled in dist/.

The pictograph art (assets/images/) is CC BY 4.0; see LICENSE-ART.md. Keep the credit "The Kinetic Alphabet by Austen Cloud" with a link to https://tkaflowarts.com wherever the pictographs appear ("TKA by Austen Cloud" with the TKA logo where space is tight). The names and the logo are Austen Cloud's marks, usable for that credit and nothing else.