Using extensions
Install a module from the store or from a file, open it, run it on the section in your analysis, and decide what to do with any section it proposes. Nothing a module does changes your analysis unless you say so.
Where Extensions is#
- On a desktop or tablet: the Extensions tab in the analysis card, after Tube buckling.
- On a phone: More in the bottom bar, then the Extensions switch at the top (beside Nodes & elements).
The Extensions view has four parts: the install box, Installed, Store, and New module…, which opens the module builder. The ? beside the heading opens this guide in a new tab, so your analysis stays as it is.
Installing a module#
From the store#
The Store lists the modules published with the app. Each row has a button:
- Install: not installed yet;
- Update: installed, but the store has a different version;
- Installed (disabled): you have the store's version.
The store only ever lists Verified modules: the store build leaves out any module whose worked examples do not reproduce.
From a file#
Drop a .ckext file on the dashed box, or press Choose a file…. The app reads the
bundle, checks its manifest, and runs its worked examples in the sandbox to decide the badge. The status line under the
box then reads, for example:
Installed Squash load 1.0.0 (Verified).
or, when an example does not reproduce its numbers, why:
Installed Squash load 1.0.0 (Community). Worked example lipped-c-150-60-40: Py: expected 236.25, got 240
A bundle that is not a module for this app is refused, and nothing is installed. The common refusals are listed under
install errors; a module written for CivilKit Studio gets
This module is for CivilKit Studio: ….
Installing a module whose id is already installed replaces it (a new version, or your own edited copy).
A fork has its own id, so it installs beside the original.
The badges#
| Badge | Means |
|---|---|
| Verified | The module has at least one worked example, and every one reproduced its cited numbers within 0.1 % when it was installed, in this browser. |
| Community | Anything else: no worked examples, one that failed, or one that stopped with an error. |
Hover over (or long-press) a badge and its tooltip says exactly what it is worth:
Verified: every worked example reproduced its cited numbers. This is a test gate, not a review.
Verified tells you that the module reproduces the numbers its author cited. It does not tell you that those examples are the right ones, that the module covers your case, or that its clause references are current. Read its examples (in View code) before you rely on it. Worked examples and the badge has the rules.
Opening and running a module#
Press Open on an installed module. Its view replaces the Extensions list (full screen on a phone), with a bar across the top: ‹ Extensions to go back, the module's name, its badge, its version and View code.
- The form is the module's own. Fill it in and press its run button (a module labels it; often Run). Changing a field also runs the module again.
- While it runs, Running… shows and its buttons are disabled.
- Results, calc lines and charts appear under the form. A calc block has a Copy button that copies its lines as plain text, ready for a calc sheet.
- An error shows in a red box at the top of the module, beginning with the module's name. The rest of the app is unaffected.
What a module sees#
Each run gets a copy of the analysis as it stands: the nodes, elements, materials, springs and constraints, the reference loads and fy from the Loads panel, and the analysis settings (signature curve or general BC, end conditions, terms, lengths). If the app has solved the curve, the module can also read it and its classified minima. It works on a copy: nothing it does reaches your model, except a section it proposes that you accept.
View code and fork#
View code opens the module's files read-only: main.py (highlighted, with line
numbers), its manifest and its worked examples. Read the examples' source lines here before relying on the
module.
Edit & run as a fork copies the module into the builder and runs it. The copy gets its own
id (the original's with -fork) and name (with (fork)), so installing it never replaces the
original. If the builder held a draft of yours, the fork replaces it, and the toast offers Undo.
The ? in View code opens the capability reference.
Section proposals#
A module with the proposeModel capability can offer a section to the analysis, as the
Rounded C / Z section module does. The app never applies it on
its own. A banner appears in the module view:
Rounded C / Z section proposes a section: 25 nodes, 24 elements. [Preview] [Use it] [Dismiss]
- Preview draws the proposed section, dashed, over the current one in the section card (on a phone, inside the banner). Press it again (Hide preview) to stop. Nothing changes.
- Use it puts the section into the analysis, with the proposal's loads, fy and analysis
settings when it carries them. The app recomputes the reference stresses from the loads, and solves. A toast says
The section from ‹module› is now in the analysis.with Undo. It is also one step in the app's undo history, so ↶ takes it back too. - Dismiss removes the banner.
The app validates every proposal before it is offered. One that refers to a node that does not exist, has an
element of zero thickness, an undefined material, more than 5000 nodes, or coordinates that are not finite numbers is
not offered; the module view shows ‹module› proposed an invalid section: ‹reason› instead.
After you use a proposal, a note in the module view says The section in the analysis has changed: Run the
module again to update its results. Its earlier results were computed on the old section.
Uninstalling#
Uninstall removes the module straight away; the toast that says
Uninstalled ‹module›. has Undo, which installs the same files again (and runs the
worked examples again for the badge).
Where installed modules live#
In this browser, for this site: the app keeps installed modules in the browser's own storage (IndexedDB). They
are not uploaded anywhere, and they do not follow you to another browser or device. Clearing the site's data removes
them; a private window forgets them when it closes. To move a module, keep its .ckext file (the builder's
Export .ckext makes one) and install it again.
The builder's draft is kept the same way, in this browser's local storage.
What the sandbox prevents#
A module's Python never runs on the page. It runs in a separate Web Worker with MicroPython and the engine, started
under the page's Content Security Policy. Before any module code runs, the worker removes what a module could otherwise
reach through MicroPython's js module:
- No network:
fetch,XMLHttpRequest,WebSocket,EventSource,WebTransportandimportScriptsare gone, and the page's policy allows connections only to the app's own site. - No storage: no IndexedDB, no cache storage, and a worker has no
localStorageor cookies. - No page: a worker has no DOM. A module returns plain data; the app draws every element and sets all text as text, so a module cannot inject markup.
- No new workers, no
eval, nonavigator. - No forged messages: the worker's channel to the page is removed from module reach, and the page only accepts messages that carry a token module code cannot read.
- Only declared capabilities: a call to a capability the manifest does not list stops the module.
- Time limits: each call (opening the module, each run, each worked example at install) has 20 seconds.
A module that takes longer, or loops forever, is stopped with
The module stopped responding and was stopped.The worker restarts and the app keeps working; the next Run starts the module afresh.
The Python import statement is not the boundary: the worker and the page's policy are. A module can import
js; it finds nothing there worth having.
On a phone#
- More › Extensions opens the list.
- A module opens full screen; the system back gesture (or ‹ Extensions) closes it.
- A proposal's preview draws inside its banner, since the section card is not on screen.
- The builder works, but says
Best on a tablet or desktop: code is easier to write on a larger screen. View code works everywhere.