# STRVCT — Full Documentation STRVCT implements the naked objects pattern for JavaScript. You write domain model classes with annotated properties — the framework automatically generates the user interface, handles persistence, and keeps everything synchronized. See also: /llms.txt (curated index) and /sitemap.xml. --- Source: / A naked objects framework for JavaScript with automatic UI generation, persistence, and cloud sync. ## About STRVCT implements the [naked objects](http://downloads.nakedobjects.net/resources/Pawson%20thesis.pdf) pattern for JavaScript. You write domain model classes with annotated properties — the framework automatically generates the user interface, handles persistence, and keeps everything synchronized. The model layer is completely independent of the UI, allowing the same application code to run in a browser, on a command line, or headlessly in Node.js for testing and server-side processing. For a detailed treatment of this approach, see [Closing the Usability Gap in Naked Objects](docs/Naked%20Objects/index.html). ## Key Features - **Automatic UI** — Views are generated from the model graph using a Miller Column inspired navigation pattern. Custom views can override defaults when needed. - **Slot System** — Properties are declared as slots with annotations that control type checking, persistence, UI generation, view synchronization, and other features. - **Notification-Based Sync** — The model layer communicates to the views layer through deferred, deduplicated notifications with automatic sync loop detection. - **Transparent Persistence** — No custom serialization code required. Declare which objects and slots to persist, and the framework handles dirty tracking, automatic commits, and garbage collection via IndexedDB. - **Cloud Sync** — Object pools sync to Firebase Storage using a write-ahead log of delta files for efficient incremental updates. - **Gesture System** — Unifies mouse and touch input gestures. - **Internationalization** — AI-powered translation of UI text with no per-component wiring. The naked objects pattern means every slot value is translated at the model-to-view boundary automatically. - **Accessibility** — Automatic ARIA roles, labels, and states derived from the model. Slot metadata maps to aria-required, aria-valuemin/max, and aria-description; view classes emit landmark roles, live regions, and focus-visible styling. - **Content-Addressable Build** — Custom resource loading with content hashing for optimal caching and minimal network transfers. - Example App - FAQ - docs - Timeline - [GitHub Repository](https://github.com/stevedekorte/strvct.net) — Source code, issues, and contributions. For AI agents: [llms.txt](llms.txt) (curated index) and [llms-full.txt](llms-full.txt) (full content). --- Source: /docs/ # Documentation Guides, architecture, and API reference. - Naked Objects - Technical Overview - Implementation Overview - Slots - Getting Started - Lifecycle - Notifications - Views - Persistence - Events and Gestures - Accessibility - Internationalization - Services - Programming Idioms - Reference - Comparing to React - Inspirations - Future Work --- Source: /docs/Accessibility/ # Accessibility Automatic, framework-level ARIA support derived from the naked objects pattern. ## Overview STRVCT provides built-in accessibility support that works automatically for every application built on the framework. Because the UI is generated from model nodes through a small set of view classes, accessibility metadata is emitted at the framework level -- developers don't need to add ARIA attributes to individual components. This is a direct consequence of the naked objects architecture. In a conventional web framework, accessibility is a per-component concern: every button, list, and form field needs manual ARIA attributes, and the cost scales linearly with the number of components. In STRVCT, the same ~15 view classes render every application's UI, so fixing accessibility in those classes fixes it everywhere. ## Why the Naked Objects Pattern Helps Most frameworks require developers to manually add accessibility attributes to each component. STRVCT's architecture inverts this: since the framework generates views from the model, it can also generate accessibility metadata from the model -- automatically, in one place, for all applications. **The slot system already describes the data.** Slot metadata maps almost directly to ARIA attributes: | Slot metadata | ARIA attribute | |---|---| | `description()` | `aria-description` | | `isReadOnly()` | `aria-readonly` | | `isRequired()` | `aria-required` | | `slotType()` | informs the appropriate `role` | **JSON Schema annotations serve double duty.** The same annotations that generate JSON Schema for AI tool calls also drive accessibility attributes. A slot with `setMinimum(0)` and `setMaximum(100)` emits both JSON Schema constraints for AI and `aria-valuemin="0"` / `aria-valuemax="100"` for screen readers. The investment in richer slot annotations directly improves both AI integration and accessibility. **The node hierarchy maps to ARIA patterns.** The tile/stack navigation model (drill in, drill out, select with arrows) maps naturally to ARIA roles: | STRVCT concept | ARIA role | |---|---| | `SvTilesView` | `list` | | `SvTile` | `link` | | `SvFieldTile` | `group` | | Selected tile | `aria-current` | **Every new application inherits it.** When a developer creates a new `SvNode` subclass with slots, the framework automatically generates views with correct ARIA roles, labels, states, and metadata-derived attributes. No accessibility code required. ## Implementation ### ARIA Roles Each core view class emits an appropriate ARIA role: | View class | Role | Purpose | |---|---|---| | `SvTilesView` | `list` | Container for navigable tile items | | `SvTile` | `link` | Individual navigation item in a list | | `SvFieldTile` | `group` | Key-value field with label and value | | `SvBooleanFieldTile` | `checkbox` | Toggle field with checked/unchecked state | | `SvActionFieldTile` | `button` | Clickable action | | `SvOptionsNodeTile` | `listbox` | Container for selectable options | | `SvOptionNodeTile` | `option` | Individual selectable option | | `SvStackView` | `navigation` | Top-level navigation landmark | | `SvNavView` | `region` | Named content region | | `SvBreadCrumbsTile` | `navigation` | Breadcrumb navigation with `aria-label="Breadcrumb"` | ### Labels and Descriptions View classes derive ARIA labels from node metadata: | Source | ARIA usage | |---|---| | `node.nodeAriaLabel()` | `aria-label` on tiles, tile lists, and navigation regions | | `node.subtitle()` | `aria-description` on tiles | | `slot.description()` | `aria-description` on field tiles | | Key view text | `aria-label` on field tiles | `nodeAriaLabel()` is defined on `SvTitledNode` and returns `title()` by default. Domain objects can override it to provide a more descriptive label for screen readers without affecting the visible UI title. `subtitle()` and slot `description()` provide longer detail available on demand. ### Node-Level ARIA Overrides `SvTitledNode` provides methods that domain objects can override to customize accessibility behavior without modifying view code: | Method | Default | Purpose | |---|---|---| | `nodeAriaLabel()` | `title()` | Label announced by screen readers | | `nodeAriaRole()` | `null` (view's default) | Override the view class's default ARIA role | | `nodeAriaIsReadOnly()` | `null` (from slot editability) | Override read-only state | | `nodeAriaIsRequired()` | `null` (from slot `isRequired()`) | Override required state | Returning `null` from `nodeAriaRole()`, `nodeAriaIsReadOnly()`, or `nodeAriaIsRequired()` defers to the view's default behavior. Returning a value overrides it. This follows the same pattern as `setNodeViewClass()` -- the framework provides sensible defaults, the domain object overrides when it knows better. ### State Tracking ARIA states are updated dynamically through the framework's notification system: - **`aria-current`** -- Set to `"true"` on the selected tile, removed when deselected. The selected tile also receives focus. - **`aria-checked`** -- Updated on `SvBooleanFieldTile` when the boolean value changes. - **`aria-selected`** -- Updated on `SvOptionNodeTile` based on `isPicked()` state. - **`aria-disabled`** -- Set on `SvActionFieldTile` when the action's node is not enabled. - **`aria-readonly`** -- Set on `SvFieldTile` when the field is not editable. ### Slot Metadata to ARIA `SvFieldTile` includes a `syncAriaFromSlotMetadata()` method that reads slot annotations and emits corresponding ARIA attributes: | Slot annotation | ARIA attribute | |---|---| | `isRequired()` | `aria-required="true"` | | `getAnnotation("minimum")` | `aria-valuemin` | | `getAnnotation("maximum")` | `aria-valuemax` | | `description()` | `aria-description` | This wiring means that any slot configured with validation constraints automatically exposes those constraints to assistive technology. For example, a slot defined as: ```javascript { const slot = this.newSlot("hitPoints", 0); slot.setSlotType("Number"); slot.setIsRequired(true); slot.setAnnotation("minimum", 0); slot.setAnnotation("maximum", 999); slot.setDescription("Current hit points"); } ``` ...produces a field tile with `aria-required="true"`, `aria-valuemin="0"`, `aria-valuemax="999"`, and `aria-description="Current hit points"` -- with no accessibility-specific code from the developer. ### Live Regions Live regions announce dynamic content changes to screen readers without requiring focus. **Opt-in via nodes:** Any node can declare itself as a live region by implementing `nodeAriaLive()` returning `"polite"` or `"assertive"`. When `SvTilesView` syncs from a node with this method, it sets `aria-live` on the container. This is useful for status displays, notification lists, and progress indicators. **Direct on chat:** `SvChatMessageTile` sets `aria-live="polite"` directly, so new chat messages and AI responses are announced to screen readers as they arrive. ### Breadcrumb Navigation `SvBreadCrumbsTile` implements the ARIA breadcrumb pattern: - Container has `role="navigation"` and `aria-label="Breadcrumb"` - The last crumb (current location) is marked with `aria-current="location"` - Screen readers announce the breadcrumb trail as "Breadcrumb navigation" with the current item identified as "current location" ### Focus Management - **Tiles are programmatically focusable** via `tabindex=-1`. This makes them reachable by the framework's focus management without adding them to the Tab order. - **Focus indicators** use `:focus-visible` styling (2px solid cornflower blue outline) that appears only for keyboard navigation, not mouse clicks. - **High contrast mode** (`prefers-contrast: more`) increases the focus outline to 3px solid white for maximum visibility. - **Focus follows selection** -- when a tile is selected, it receives both `aria-current="true"` and DOM focus, ensuring screen readers announce the newly selected item. ### Visual Accessibility The framework's global CSS includes media query support for visual accessibility preferences: **Reduced motion** (`prefers-reduced-motion: reduce`): - All animations reduced to 0.01ms duration - All transitions reduced to 0.01ms duration - Animation iteration counts set to 1 - Scroll behavior set to auto (instant) **High contrast** (`prefers-contrast: more`): - Focus indicators enhanced to 3px solid white with tighter offset - Provides stronger visual distinction for keyboard navigation ### ARIA Landmarks Landmark roles provide structural navigation for screen readers: - `SvStackView` is marked as `navigation` -- the top-level navigation structure - `SvNavView` is marked as `region` with an `aria-label` derived from the current node's title - `SvBreadCrumbsTile` is marked as `navigation` with `aria-label="Breadcrumb"` Screen reader users can use landmark navigation (e.g., VoiceOver's VO+U landmarks menu) to jump between these regions. ## WCAG 2.2 Compliance The implementation targets WCAG 2.2 Level AA, which covers the requirements of most accessibility legislation (ADA, EAA, Section 508). ### Criteria Addressed | WCAG Criterion | How addressed | |---|---| | 1.3.1 Info and Relationships | ARIA roles and landmarks convey structure | | 1.3.2 Meaningful Sequence | DOM order matches visual order (flexbox layout) | | 2.1.1 Keyboard | Arrow keys, Enter, Escape for full navigation | | 2.3.3 Animation from Interactions | `prefers-reduced-motion` media query | | 2.4.1 Bypass Blocks | Landmark roles enable skip navigation | | 2.4.6 Headings and Labels | `aria-label` from node `title()` | | 2.4.7 Focus Visible | `:focus-visible` outline styling | | 3.2.1 On Focus | No context changes on focus | | 4.1.2 Name, Role, Value | ARIA roles, labels, and states on all interactive elements | ### Remaining for Full AA Compliance See [Accessibility Testing & Tuning](Future%20Work/Accessibility%20Testing%20%26%20Tuning/index.html) for details on remaining testing and tuning work, including VoiceOver validation, cross-screen-reader testing, focus management refinements, and per-application adjustments. ## Design Decisions ### ARIA Roles vs. Semantic Elements ARIA roles on div elements are equivalent to semantic HTML from the screen reader's perspective. Since STRVCT already handles keyboard activation and focus management on tiles, the native behaviors that semantic elements provide (space/Enter activation, default tab order) are redundant. Using ARIA attributes on existing div elements avoids disrupting existing CSS selectors and layout behavior. ### Default Roles from View Classes Default roles come from the view class, not the node, because the same node can appear in multiple views with different roles. For example, a node shown as a tile in a parent view has `role="link"`, while the same node as the root of its own tiles view has no tile role. Nodes can override the view's default role for cases where the node's semantics are more specific (e.g., `SvOptionsNodeTile` overrides to `listbox`). ### Label Priority | Source | ARIA attribute | Rationale | |---|---|---| | `title()` | `aria-label` | Short, instance-specific -- what the screen reader announces | | `subtitle()` | `aria-description` | Longer detail -- available on demand | | `jsonSchemaDescription()` | Fallback label | Describes the class when no instance title exists | | Node `description()` | Skipped | Intended for debugging, not user-facing | Slot-level `description()` (set via `setDescription()`) is distinct from node-level `description()` and is used for field-level `aria-description`. ## Files Modified The accessibility implementation touches the following framework files: | File | Changes | |---|---| | `_css.css` | `:focus-visible` styling, `prefers-reduced-motion`, `prefers-contrast` | | `SvTilesView.js` | `role="list"`, `aria-label`, opt-in `aria-live` | | `SvTile.js` | `role="link"`, `tabindex=-1`, `aria-label`, `aria-description`, `aria-current` | | `SvFieldTile.js` | `role="group"`, `aria-label`, `aria-readonly`, `syncAriaFromSlotMetadata()` | | `SvBooleanFieldTile.js` | `role="checkbox"`, `aria-checked` | | `SvActionFieldTile.js` | `role="button"`, `aria-label`, `aria-disabled` | | `SvOptionsNodeTile.js` | `role="listbox"` | | `SvOptionNodeTile.js` | `role="option"`, `aria-selected` | | `SvChatMessageTile.js` | `aria-live="polite"` | | `SvStackView.js` | `role="navigation"` | | `SvNavView.js` | `role="region"`, `aria-label` | | `SvBreadCrumbsTile.js` | `role="navigation"`, `aria-label="Breadcrumb"`, `aria-current="location"` | --- Source: /docs/Comparing%20to%20React/ # Comparing to React A guide for React developers exploring Strvct — what's different, what's similar, and when each approach makes more sense. ## The Core Difference React and Strvct solve the same fundamental problem — keeping a UI in sync with application state — but start from opposite ends. **React** is a view library. You describe what the UI looks like for a given state, and React makes the DOM match. Everything else — the model, persistence, routing, styling — is yours to choose. **Strvct** is a naked objects framework. You describe the domain model — its properties, relationships, and annotations — and the framework generates the UI, handles persistence, and manages navigation automatically. Custom views override the defaults when needed. They represent genuinely different philosophies about where developer effort should go. ## Architecture React is flexible about where it runs. A React app can be a client-side SPA, a server-rendered application, or a hybrid. The modern ecosystem includes server-side rendering (Next.js, Remix), static site generation, and server components — but none of these are required. Many React applications are purely client-side. Strvct is **local-first** by design. Data is persisted client-side in IndexedDB automatically, rendering happens entirely on the client, and the UI is responsive without waiting on network round trips. Cloud sync is available for backup and cross-device access, but the application works fully offline. ### What You Write In React, application code is primarily components — functions that return JSX describing the UI for a given state: ```jsx function Contact({ contact, onSave }) { const [name, setName] = useState(contact.name); const [email, setEmail] = useState(contact.email); return (
## 6. Architecture
Strvct is implemented as a client-side JavaScript framework. Applications run as single-page apps in the browser, making heavy use of client-side persistent storage — both for caching code and resources via a content-addressable build system, and for maintaining a persistent object database of application state in IndexedDB.
An important architectural distinction: Strvct does not compile or pre-render user interfaces. There is no build step that produces a view tree, no template system, and no static component hierarchy. Views are instantiated lazily at runtime — only when the user navigates to a node in the object graph. Each navigation step inspects the target node's class and slot annotations, discovers or creates an appropriate view, and binds it to the node for live bidirectional synchronization. Once created, a view persists as long as its node remains visible, staying in sync with the model through the notification system. The result is closer to a live object browser than a conventional render pipeline: the UI that exists at any moment is determined by the user's current navigation path through the object graph, and it responds immediately to changes in the underlying model.
### 6.1 Domain Model
The domain model is a graph of objects inheriting from a common base class. Each object has properties declared as *slots* with annotations, actions exposed as methods, a `subnodes` array of child objects, a `parentNode` reference, and a unique persistent identifier.
The model is fully independent of the UI layer. Model objects hold no references to views and communicate outward solely by posting notifications. This allows the same model code to run headlessly in Node.js for testing or server-side processing.
### 6.2 The Annotation Bridge
The slot system is what makes automatic UI and storage possible. Rather than using raw instance variables, properties carry metadata annotations that each framework layer consults independently:
- **Type** — selects the appropriate property tile and enables runtime type checking (every generated setter validates its argument against the declared type, catching type errors at the point of assignment rather than at compile time)
- **Persistence** — includes the slot in storage records
- **View synchronization** — triggers view updates when the value changes
- **Subnode relationship** — controls whether the value appears in the object's navigable hierarchy
- **Editability** — determines whether the property can be modified through the UI
- **Auto-initialization** — specifies a class to instantiate if no value was loaded from storage
- **Translation context** — provides semantic context for AI-powered translation
No single annotation knows about the others. The UI layer reads type and editability; the storage layer reads persistence; the synchronization layer reads sync flags. This separation means new layers can be added — internationalization, cloud sync, schema generation — without modifying existing annotations or the domain model itself.
### 6.3 Storage
Persistence is annotation-driven. The persistence layer monitors slot mutations, batches dirty objects at the end of each event loop into atomic transactions, and commits them to IndexedDB. On load, stored records are deserialized back into live object instances with relationships re-established.
A separate content-addressable blob store handles large binary data using SHA-256 hashes as keys, providing automatic deduplication. Objects store hash references rather than blob data directly.
Automatic garbage collection walks the stored object graph from the root; unreachable objects are removed.
### 6.4 Synchronization
Model and view layers communicate through a deferred, deduplicated notification system. When a model property changes, a notification is posted; observing views schedule a sync pass. Multiple changes within a single event loop are coalesced. Bidirectional sync stops automatically when values converge, preventing infinite loops. Observations use weak references, so garbage collection of either party automatically cleans up subscriptions.
## 7. Emergent Capabilities
When the framework controls the entire pipeline from model annotation to rendered view, capabilities that would normally require per-component effort become emergent properties of the architecture. Each capability described below exists because of the same structural fact: the framework has complete knowledge of the domain model and controls the single point where model data flows to the UI.
### 7.1 Transparent Internationalization
Because all UI text flows from model slot annotations through a single rendering pipeline, translation can be injected at the model-to-view boundary transparently. No per-component `t()` calls or translation key files are needed. New model classes are translatable by default.
This centralization also makes AI-powered translation practical. The framework discovers every translatable string by walking model class prototypes — an introspection that is only possible because all UI-visible text originates from annotated slots. Slot-level context annotations (e.g., "game mechanic" vs. "ui label") travel with the model, giving the AI translator domain-appropriate terminology without developer effort. Adding support for a new language becomes a configuration change rather than a translation project.
In a conventional framework, achieving automatic translation would require either instrumenting every component with translation calls, or building an extraction tool that parses component templates to find translatable strings. Both approaches scale linearly with the number of components. In Strvct, the cost is zero per component — the framework handles it structurally.
### 7.2 Transparent Persistence and Cloud Sync
Because the framework owns the complete object graph and understands the structure of every node through annotations, it can split persistence into two strategies transparently. The object pool — the graph of domain objects and their properties — is loaded synchronously, ensuring the model is immediately available for UI rendering. Large binary resources such as media and document files are stored separately in a content-addressable blob store and loaded asynchronously on demand, so they never block the UI.
This same structural knowledge enables transparent cloud synchronization. Subgraphs of the local object database can be lazily synced to cloud storage without the developer writing any sync logic — the framework knows which objects have changed, which blobs they reference, and how to reconcile local and remote state. The developer annotates what should persist; the framework decides how and when to load, store, and sync it.
### 7.3 JSON Schema Generation
Domain objects can automatically generate JSON Schema descriptions of themselves based on their slot annotations. This is particularly valuable for integration with large language models, which can use the schema to understand the structure of domain objects, validate their output, and generate patches or new instances that conform to the model's constraints. In Strvct's production use, AI assistants modify game state by generating JSON Patch operations validated against auto-generated schemas — a workflow that requires no hand-written schema definitions.
### 7.4 Automatic Accessibility
Because the framework generates the view hierarchy from model annotations and controls the rendering of every tile, field, and navigation structure, it can emit ARIA roles, labels, and states automatically — without any accessibility-specific code from the developer.
Each view class provides a default ARIA role derived from its function: tile stacks become `list` containers, individual tiles become `link` items, field tiles become `group` elements, boolean fields become `checkbox`, action fields become `button`. Slot metadata that already exists for type checking and schema generation — `isRequired()`, `isReadOnly()`, minimum/maximum constraints, `description()` — maps directly to ARIA attributes: `aria-required`, `aria-readonly`, `aria-valuemin`/`aria-valuemax`, `aria-description`. The node hierarchy provides landmarks (`navigation`, `region`) and breadcrumb structure. Dynamic content nodes can opt into `aria-live` announcements.
The parallel to internationalization (Section 7.1) is exact. Both capabilities exist because all UI-visible information flows from annotated model slots through a single framework-controlled pipeline. In a conventional framework, accessibility is a per-component obligation — every button, list, and form field needs manual ARIA attributes, and the cost scales linearly with the number of components. In Strvct, fixing accessibility in the ~15 core view classes fixes it for every application built on the framework.
### 7.5 Content-Addressable Resource Loading
The framework's build system produces a content-addressable bundle where source files are keyed by SHA-256 hash. The client caches resources locally in IndexedDB and uses hash comparison to determine what has changed between deployments. Unchanged resources are never re-downloaded, and identical content across different file paths is stored only once. This is a consequence of the framework controlling the full resource pipeline — analogous to how it controls the model-to-view pipeline — and provides caching granularity that standard bundlers cannot achieve.
## 8. Case Study: undreamedof.ai
Strvct has been used to build undreamedof.ai, an AI-powered virtual tabletop for Dungeons & Dragons and other tabletop roleplaying games. The application includes:
- **Character system**: hierarchical character sheets with ability scores, inventory, spellcasting, and equipment — approximately 30 domain classes
- **Campaign system**: adventure management with nested locations, NPCs, creatures, treasures, and narrative structure — approximately 20 domain classes
- **Session system**: real-time multiplayer game sessions with AI game master, dice rolling, voice narration, and peer-to-peer networking — approximately 25 domain classes
- **AI integration**: multiple AI service providers, tool calling, streaming responses, and prompt composition — approximately 15 domain classes
The application comprises roughly 90 domain model classes. Of these, fewer than 10 required custom view classes. The remainder — including character sheets, campaign hierarchies, settings panels, and administrative interfaces — use the framework's automatically generated views exclusively.
This ratio — approximately 90% auto-generated views — is the practical test of the composable primitive approach. The domain model is non-trivial: character sheets have deeply nested hierarchies (character → ability scores → individual scores → modifiers), campaigns contain recursive location trees, and the session system manages real-time state across multiple connected clients. Despite this complexity, the default tiles and master-detail views produce navigable, usable interfaces throughout.
The custom views that were needed fall into the category identified in Section 3 as outside the narrow design space: a chat interface for AI conversation, a 3D dice roller, and a map view. These are inherently graphical, domain-specific components that cannot be derived from model annotations. Their existence does not undermine the approach — it confirms that the boundary between auto-generated and bespoke views falls where predicted.
## 9. Related Work
**Naked objects implementations.** Apache Isis (now Apache Causeway) [3] is the most mature naked objects framework, providing automatic UI generation for Java domain models with both a web UI (Wicket viewer) and a REST API. JMatter [5] implemented naked objects for Java Swing. Both use form-and-table UI strategies and target enterprise/administrative use cases. Strvct differs in its UI strategy (composable spatial primitives rather than forms and tables) and its target (end-user applications rather than internal tools).
**Model-driven UI generation.** The broader field of model-driven development has produced approaches like IFML [6] (Interaction Flow Modeling Language) and UsiXML, which use abstract UI models to generate interfaces. These typically require separate UI models in addition to domain models — a layer of specification that naked objects explicitly eliminates. Strvct's approach is closer to naked objects in that the domain model itself, annotated with metadata, is the only specification needed.
**Miller Columns.** The column-based navigation pattern was introduced in NeXTSTEP and popularized by macOS Finder [4]. It provides spatial continuity when browsing hierarchical data. Strvct extends this pattern by making it recursive (columns can nest vertically or horizontally), orientation-flexible (each level can choose its own orientation), and self-composing (the layout is determined by model annotations rather than application code).
**Low-code and no-code platforms.** Modern low-code platforms (Retool, Appsmith, OutSystems) aim to reduce UI development cost through visual builders and pre-built components. They approach the same problem as naked objects — reducing the cost of UI development — but from the opposite direction: rather than eliminating bespoke UI, they make bespoke UI faster to produce. The result is still a collection of individually designed screens that must be maintained as the data model evolves. Naked objects eliminates this maintenance cost entirely.
**AI-generated UI.** Large language models can now generate UI code from natural language descriptions. This automates the *creation* of bespoke interfaces but does not address their *maintenance* — each generated screen is still a separate artifact that must be updated when the model changes. Naked objects is a fundamentally different approach: rather than automating the production of bespoke UIs, it eliminates the need for them.
## 10. Discussion
### The Crossover Point
Hand-crafted interfaces may appear more polished early in an application's life, when the number of screens is small and each can receive individual design attention. But as the domain model grows, the cost of maintaining bespoke screens grows with it, while inconsistencies accumulate. At some point — the crossover point — a consistent, automatically generated interface produces a better user experience than a patchwork of hand-crafted screens, because the user can rely on uniform navigation throughout the application.
The composable primitive approach shifts this crossover point earlier by improving the quality of the generated interface. The undreamedof.ai case study suggests the crossover may occur sooner than expected: at ~90 domain classes, auto-generated views were not merely acceptable but preferred for 90% of the interface, because they provided consistent navigation and interaction patterns that would have been difficult to maintain across hand-crafted screens.
### A Familiar Dynamic
This dynamic — general methods outperforming hand-crafted solutions as scale increases — appears in other domains. In his essay *The Bitter Lesson* [2], Rich Sutton observed that across 70 years of AI research, general methods that leverage computation consistently outperformed approaches that encoded human expertise, and the gap widened with scale.
The analogy to naked objects is instructive if imperfect. In AI, the scaling dimension is computation; in naked objects, it is domain model complexity. The principle is similar: investing in a general method that improves with scale — rather than in case-by-case engineering that must be repeated for each new component — produces compounding returns. But unlike AI scaling, which depends on hardware improvements, naked objects scaling depends on a design choice: whether the framework's primitives are good enough to make hand-crafted specialization unnecessary for most screens.
### Strengths
The approach is strongest in domains where the model itself is the volatile, high-value artifact — where requirements change frequently and the cost of keeping UI, storage, and synchronization in sync with a shifting model is the main engineering bottleneck. Because a model change propagates automatically to the UI, persistence, cloud sync, schema generation, and internationalization, the iteration cycle from "requirement changed" to "working software" is compressed to the time it takes to modify a class definition. Adding a property, restructuring a hierarchy, or introducing a new entity requires no corresponding changes to view code, form layouts, serialization logic, or API schemas.
This makes the approach particularly suited to exploratory or fast-evolving applications — tools for analysis, research, operations, or any domain where the data model is expected to grow and change throughout the application's life. The framework's headless execution capability reinforces this: the same model that drives the UI can be tested, simulated, or batch-processed in Node.js without any browser dependency, enabling rapid validation of model changes before they reach users.
### Limitations
The composable primitive approach is best suited to informational and navigational interfaces — applications centered on browsing, editing, and managing structured data. Highly graphical interfaces (data visualizations, design canvases, game renderers) require domain-specific rendering that cannot be derived from model annotations. Strvct supports custom view classes for these cases, but they fall outside the automatic generation pipeline.
The spatial conventions we rely on — top-to-bottom hierarchy, left-to-right depth — reflect Western reading order. Right-to-left languages would require mirrored layouts, which the framework's flexbox-based rendering can accommodate but which have not yet been fully validated.
## 11. Conclusion
The naked objects pattern has offered a compelling proposition for twenty-five years: write the domain model, and the rest follows. Its limited adoption is not a failure of this proposition but of the UI strategies that prior implementations chose. Generic forms and tables were sufficient for internal tools but did not meet the expectations set by modern consumer software.
We have argued that the gap is closable because the design space is narrow. Bespoke UI developers are converging on a small set of spatial conventions; a framework can apply these conventions uniformly through composable primitives — tiles, tile stacks, and recursively nested master-detail views — that produce familiar, navigable interfaces from annotated domain models alone.
Strvct demonstrates this approach in production. A non-trivial application with ~90 domain classes uses auto-generated views for approximately 90% of its interface, with custom views needed only for inherently graphical components that fall outside the narrow design space. The centralized model-to-view pipeline enables emergent capabilities — transparent internationalization, automatic accessibility, annotation-driven persistence with cloud sync, and automatic schema generation — that validate the architectural decision to invest in the general method.
The challenge remains making the general method good enough that hand-crafted specialization becomes the exception rather than the rule. We believe the evidence presented here — a narrow design space, a small set of composable primitives, and a production application that confirms both — suggests this goal is within reach.
## References
[1] Pawson, R. (2004). *Naked Objects.* PhD Thesis, Trinity College, Dublin.
[2] Sutton, R. (2019). *The Bitter Lesson.* Incomplete Ideas. http://www.incompleteideas.net/IncIdeas/BitterLesson.html
[3] Apache Software Foundation. *Apache Causeway* (formerly Apache Isis). https://causeway.apache.org/
[4] Becker, N. (2005). Miller Columns. Wikipedia. https://en.wikipedia.org/wiki/Miller_columns
[5] Arteaga, J. M. *JMatter: A Naked Objects Framework for Java Swing.* http://jmatter.org/
[6] Brambilla, M., & Fraternali, P. (2014). Interaction Flow Modeling Language. In *Proceedings of the 23rd International Conference on World Wide Web (WWW '14 Companion).* ACM.
---
Source: /docs/Notifications/
# Notifications
Event-driven communication between framework layers using observations, scheduling, and weak references.
STRVCT's notification system provides loose coupling between the model, view, and storage layers. Rather than holding direct references to each other, objects communicate through three complementary mechanisms: a deferred, deduplicated notification center for broadcast events; a sync scheduler that coalesces direct method calls; and a lightweight broadcaster for synchronous dispatch. All three use weak references for automatic cleanup — when an observer or sender is garbage collected, its registrations are removed without manual intervention.
These are separate because they optimize for different tradeoffs. The notification center is loosely coupled — the sender doesn't know who's listening — but that generality has overhead: queuing, indexing, pattern matching. View synchronization doesn't need any of that; it needs a specific method on a specific object to run exactly once, which is what the sync scheduler provides directly. And some internal events (like storage-layer slot propagation) need synchronous delivery with no deferral at all, which is the broadcaster's role. A single mechanism couldn't serve all three without either over-engineering the simple cases or under-serving the complex ones.
**Processing order within an event loop:** Application code runs first — any slot changes during this phase trigger slot change hooks immediately, and any Broadcaster dispatches also execute synchronously inline. Meanwhile, notifications and sync requests are queued, not executed. At the end of the event loop, the SyncScheduler processes its queue in priority order: view-to-model syncs (priority 0) run first, then notification dispatch (which delivers queued NotificationCenter events to observers), then model-to-view syncs (priority 2). Finally, the persistence layer auto-commits all dirty objects to IndexedDB. This ordering guarantees that user edits land before reactive updates, and that storage always sees the final settled state.
- Notification Center
- Sync Scheduler
- Broadcaster
- Slot Change Hooks
---
Source: /docs/Notifications/Broadcaster/
# Broadcaster
Lightweight synchronous dispatch for high-frequency internal events.
## Overview
Some internal framework events — like storage-layer slot propagation — need to arrive immediately, not at the end of the event loop. Deferral would mean downstream code sees stale state between the change and the next microtask. The notification center's queuing and deduplication are liabilities here, not features.
`SvBroadcaster` is a minimal synchronous alternative. Broadcasts execute immediately when posted — no queue, no deduplication, no event-loop delay. The tradeoff is less sophistication (no sender filtering, no pattern matching), which is fine for high-frequency internal events where the simplicity is the point.
## Usage
```javascript
// Register a listener
SvBroadcaster.shared().addListenerForName(this, "didChangeStoredSlot");
// Broadcast (immediate, synchronous)
SvBroadcaster.shared().broadcastNameAndArgument("didChangeStoredSlot", this);
```
When the broadcast fires, the system calls the listener's method matching the broadcast name — in this case, `this.didChangeStoredSlot(argument)`.
## When to Use Broadcaster vs. Notification Center
| | SvNotificationCenter | SvBroadcaster |
|---|---|---|
| **Timing** | Deferred to end of event loop | Immediate, synchronous |
| **Deduplication** | Same name+sender dispatched once per loop | Every call dispatches |
| **Registration** | SvObservation with name, sender, observer | Listener + name |
| **Sender filtering** | Can observe a specific sender | Receives from all senders |
| **Overhead** | Higher (queuing, indexing, dedup) | Lower |
Use the notification center for most inter-layer communication — the deferred deduplication is almost always what you want. Use the broadcaster for internal framework events that need synchronous delivery and where the slight overhead of the notification center matters, such as storage-layer slot change propagation.
---
Source: /docs/Notifications/Notification%20Center/
# Notification Center
Deferred, deduplicated event dispatch with weak-reference cleanup.
## Overview
In a framework where model, view, and storage layers must stay independent, objects need a way to announce state changes without knowing who cares. Direct method calls create tight coupling — the sender has to hold a reference to every interested party, and adding a new observer means modifying the sender. The notification center solves this: senders post named notifications into a shared singleton, observers register interest by name, and the two sides never reference each other.
Notifications are queued and dispatched at the end of the event loop, so multiple changes within a single operation result in a single dispatch. This deferred deduplication is critical for performance — a bulk model update that touches 50 slots produces one notification pass, not 50.
## Posting Notifications
Nodes post notifications when their state changes. The most common pattern uses the convenience method on `SvNode`:
```javascript
this.postNoteNamed("myNotification");
```
For notifications with additional data:
```javascript
SvNotificationCenter.shared().newNote()
.setSender(this)
.setName("myNotification")
.setInfo({ key: "value" })
.post();
```
Notifications are not dispatched immediately. They are queued and processed at the end of the current event loop via `SvSyncScheduler`. If the same notification (same name and sender) is posted multiple times within one event loop, it is dispatched only once.
## Observing Notifications
To observe notifications from a specific sender:
```javascript
const obs = SvNotificationCenter.shared().newObservation()
.setName("didUpdateNode")
.setSender(targetNode)
.setObserver(this)
.startWatching();
```
When `targetNode` posts a `"didUpdateNode"` notification, the system calls `this.didUpdateNode(note)` — by default, the method name matches the notification name. To use a different method:
```javascript
obs.setSendName("handleNodeUpdate");
```
For one-time observations that automatically stop after the first match:
```javascript
this.watchOnceForNote("appDidInit").then(() => {
// App is ready
});
```
Observations can also match broadly:
- `setName(null)` — match notifications with any name from the specified sender
- `setSender(null)` — match notifications with the specified name from any sender
- Both null — match all notifications (useful for debugging)
## SvNotification
Each notification is an `SvNotification` instance with three properties:
- `name` — a string identifying the event (e.g. `"appDidInit"`, `"didUpdateNode"`)
- `sender` — the object that posted it
- `info` — optional additional data
Notifications are deduplicated by a hash computed from `name` and `sender`. Posting the same event from the same object multiple times per event loop has no additional cost.
## SvObservation
An observation connects a notification pattern to an observer:
- `name` — notification name to match (or null for any)
- `sender` — sender to match (or null for any), stored as a **weak reference**
- `observer` — the object to notify, stored as a **weak reference**
- `sendName` — optional custom method name to call on the observer
- `isOneShot` — if true, automatically stops watching after the first match
The notification center maintains indexes by sender and by name for fast matching. When a notification is dispatched, matching observations are found by intersecting the relevant index sets.
## Weak References and Automatic Cleanup
Both `sender` and `observer` on `SvObservation` are stored as weak references. This means:
1. Observations do not prevent garbage collection of either party.
2. When a sender or observer is collected, a weak reference finalizer fires.
3. The finalizer schedules `stopWatching()` via `SvSyncScheduler`.
4. The observation is removed from the notification center automatically.
This eliminates a common source of memory leaks in observer patterns. There is no need to manually remove observations when objects are destroyed. Descriptions of the sender and observer are captured at registration time so that debugging information remains available even after the objects have been collected.
## Common Notification Names
**Application lifecycle:**
- `"appDidInit"` — application fully initialized and ready
**Node changes:**
- `"didUpdateNode"` — node data changed
- `"shouldFocusSubnode"` — request UI focus on a subnode
- `"didReorderParentSubnodes"` — subnode order changed
**Browser events:**
- `"onBrowserOnline"` / `"onBrowserOffline"` — connectivity changes
- `"onDocumentBeforeUnload"` — page unloading
**Configuration:**
- `"onAppDeveloperModeChangedNote"` — developer mode toggled
Applications define additional notification names for their domain-specific events.
---
Source: /docs/Notifications/Slot%20Change%20Hooks/
# Slot Change Hooks
Automatic per-slot callbacks that connect property changes to notifications and persistence.
## Overview
Without slot change hooks, every piece of code that modifies a property would also have to remember to post a notification, mark the object dirty for persistence, and trigger a view sync. That's three separate concerns that would have to be repeated at every call site — and forgetting any one of them causes silent bugs (stale views, lost data, missed observers).
Slot change hooks centralize this. When a slot value changes, the framework automatically calls a hook method on the owning object. This single integration point connects the slot system to notifications, persistence, and view synchronization — the developer changes a value, and everything downstream happens automatically.
## The Hook Convention
Define a method named `didUpdateSlot` + the capitalized slot name:
```javascript
initPrototypeSlots () {
{
const slot = this.newSlot("health", 100);
}
}
// Called automatically when health changes
didUpdateSlotHealth (oldValue, newValue) {
this.postNoteNamed("healthChanged");
}
```
The hook receives the previous and new values. It fires after the slot has been set, so `this.health()` already returns `newValue` inside the hook.
## What Triggers a Hook
Hooks only fire when the value actually changes. Setting a slot to its current value is a no-op — no hook, no notification, no mutation tracking. This is what prevents infinite sync loops in bidirectional model-view synchronization.
## The General Hook
In addition to per-slot hooks, every slot change calls the general `didUpdateSlot(slot, oldValue, newValue)` method. This is useful for cross-cutting concerns like logging or validation:
```javascript
didUpdateSlot (slot, oldValue, newValue) {
super.didUpdateSlot(slot, oldValue, newValue);
console.log(slot.name() + " changed:", oldValue, "→", newValue);
}
```
## Connection to Persistence
For storable nodes, `didUpdateSlot` also calls `didMutate()`, which marks the object as dirty in the persistent store. The store auto-commits dirty objects at the end of the event loop. This is how slot changes automatically propagate to IndexedDB — no manual save calls needed.
## Connection to Views
Slots configured with `setSyncsToView(true)` trigger view synchronization when they change. The hook posts an `onUpdatedNode` notification, observing views schedule a `syncFromNode()` call, and the sync scheduler batches it to the end of the event loop. The full chain:
```
slot value changes
→ didUpdateSlot fires
→ didMutate() marks object dirty (persistence)
→ onUpdatedNode notification posted (views)
→ observing views schedule syncFromNode()
→ SvSyncScheduler batches and executes
```
---
Source: /docs/Notifications/Sync%20Scheduler/
# Sync Scheduler
Deferred, deduplicated method calls with priority ordering and loop detection.
## Overview
View synchronization and storage writes don't need the notification center's broadcast generality — there's no unknown set of observers, just a specific method on a specific object that needs to run. But without coalescing, the same sync could be requested dozens of times per event loop as multiple slots change. Calling it each time wastes work; calling it zero times loses data.
`SvSyncScheduler` solves this by ensuring a given target/method pair runs exactly once per event loop, no matter how many code paths request it. It also provides priority ordering so that view-to-model syncs (user edits) complete before model-to-view syncs (reactive updates), preventing stale data from overwriting user input.
The notification center uses `SvSyncScheduler` internally for its own dispatch, so notification delivery and view synchronization are handled in the same deferred processing pass.
## Scheduling Actions
```javascript
SvSyncScheduler.shared().scheduleTargetAndMethod(this, "syncToView");
```
This schedules `this.syncToView()` to run at the end of the current event loop. If the same target/method pair is scheduled again before it executes, the duplicate is ignored — the method runs exactly once.
## Priority
Actions can be prioritized with an optional order parameter:
```javascript
SvSyncScheduler.shared().scheduleTargetAndMethod(this, "syncToView", 100);
```
Higher values execute later. This is how the framework ensures view-to-model syncs (priority 0) complete before model-to-view syncs (priority 2) — user edits are applied before reactive updates.
## Immediate Processing
For cases where deferred execution isn't appropriate:
```javascript
SvSyncScheduler.shared().fullSyncNow();
```
This synchronously processes all pending actions until the queue is empty.
## Loop Detection
The scheduler detects infinite loops. If an action attempts to schedule itself while it is currently executing, an error is thrown:
```
SvSyncScheduler LOOP DETECTED:
scheduleTargetAndMethod: (MyView.syncToNode)
while processing: (MyView.syncToNode)
```
Bidirectional model-view synchronization avoids loops naturally because slot setters only trigger `didUpdateSlot` when the value actually changes. Setting a slot to its current value is a no-op.
`fullSyncNow()` also includes a safety limit — it halts after 10 iterations if the queue hasn't drained, indicating a cycle that the single-action detector didn't catch.
## Pausing and Resuming
Schedulers can be paused during bulk operations:
```javascript
SvSyncScheduler.shared().pause();
// ... bulk model changes ...
SvSyncScheduler.shared().resume();
// All pending syncs execute now
```
The app startup sequence uses this to prevent premature sync cycles during model and UI initialization.
---
Source: /docs/Persistence/
# Persistence
Local storage, cloud sync, and blob management for object graphs.
- Local Object Pools
- Cloud Object Pools
- Local and Cloud Blob Storage
---
Source: /docs/Persistence/Cloud%20Object%20Pools/
# Cloud Object Pools
Cloud sync for object pools and collections using Firebase Storage.
## Overview
Strvct's local persistence stores serialized object graphs in IndexedDB via `SvPersistentObjectPool`. Cloud sync extends this with two complementary strategies because different data has fundamentally different sync characteristics. A collection of independent items (e.g. characters or campaigns) benefits from per-item files — you can lazy-load, show thumbnails before downloading, and a change to one item doesn't require re-uploading everything. But an interconnected object graph (e.g. a game session with dozens of cross-referencing objects) can't be split into individual files because objects reference each other by ID — they must move as a unit. The two strategies reflect this distinction:
- **Collection sync** — Individual items are synced as separate JSON files with a manifest. Items can be lazily loaded from stubs.
- **Pool sync** — Entire object graphs are synced as a single pool. A write-ahead log of small delta files makes updates fast and efficient — only changed records are uploaded, with periodic compaction back to a full snapshot.
Both strategies require the synced object graph to be **self-contained** — the rest of the system holds only a reference to the graph's root, and objects within the graph hold no persistent references to objects outside it. This isolation is what makes it possible to serialize, upload, and reconstruct the graph independently.
Both strategies use Firebase Storage as the backend and are coordinated by `SvCloudSyncSource`.
## Collection Sync
### How It Works
Each syncable collection maintains a folder in cloud storage at `/users/{userId}/{collectionName}/`. The folder contains one JSON file per item plus a manifest file that tracks ordering and metadata.
**Manifest structure:**
```json
{
"subnodeIds": ["id1", "id2"],
"items": {
"id1": {
"type": "MyItemClass",
"title": "Item Title",
"subtitle": "Item subtitle",
"thumbnailUrl": "https://...",
"lastModified": 1707123456789
}
}
}
```
The manifest enables lazy loading — the client can display item titles and thumbnails without downloading the full item data. Full item JSON is fetched on demand when the user navigates to an item.
Collections can be nested. `SvCloudSyncSource` supports a `subPath` slot, allowing hierarchical storage structures like `/users/{userId}/{collectionName}/{itemId}/{subCollectionName}/`.
### Sync Flow
**Push to cloud:**
1. Item serialized via `asCloudJson()` which calls `serializeToJson("Cloud", [])`
2. JSON uploaded to `/users/{userId}/{collectionName}/{itemId}.json`
3. Manifest updated with item metadata and re-uploaded
**Pull from cloud:**
1. Manifest fetched to discover available items
2. Stubs created locally for each item (title, subtitle, thumbnail from manifest)
3. Full item data fetched lazily when accessed
4. Local item populated via `deserializeFromJson()`
### Conflict Resolution
Collection sync uses a timestamp-based strategy:
- Each item tracks `cloudLastModified` and `localLastModified`
- If cloud is newer and local has no unsaved changes — update from cloud
- If cloud is newer but local has unsaved changes — keep local (re-upload on next sync)
- If local is newer — upload on next sync
This is a "local wins" strategy — local changes always take priority.
## Pool Sync
### How It Works
For complex object graphs where many interrelated objects need to be synced together, `SvSubObjectPool` serializes the entire pool as a single JSON document. The pool maps persistent unique IDs (puuids) to serialized object records:
```json
{
"{puuid1}": "{serialized_object_json}",
"{puuid2}": "{serialized_object_json}"
}
```
This is stored at `/users/{userId}/{collectionName}/{poolId}/pool.json`.
### Write Ahead Log
To avoid uploading the entire pool on every save, `SvSubObjectPool` tracks changes since the last sync and produces incremental deltas:
```json
{
"timestamp": 1707123456789,
"writes": {
"{puuid1}": "{updated_object_json}",
"{puuid3}": "{new_object_json}"
},
"deletes": ["{puuid2}"]
}
```
Deltas are stored as separate timestamped files alongside the main pool. On load, the client fetches `pool.json` and applies all deltas in order to reconstruct the current state.
**Upload strategy:**
- If changes affect less than 50% of records — upload a delta file
- If changes exceed 50% — upload the full pool (more efficient than a large delta)
- When delta count exceeds 20 — compact by uploading a full pool and deleting all deltas
### Concurrency Control
Pool sync uses lock-based concurrency to prevent simultaneous edits:
- `asyncAcquireOrRefreshLock()` acquires an exclusive lock before writing
- Locks are refreshed periodically (every 60 seconds) during active sessions
- `asyncReleaseLock()` releases the lock when the session ends
- Lock acquisition and release are handled via cloud function endpoints
## Key Classes
### SvCloudSyncSource
The primary cloud-aware sync class. Configured with a user ID, folder name, and Firebase Storage reference. Handles:
- Item upload and download
- Manifest management
- Thumbnail uploads to content-addressed storage
- Retry logic with exponential backoff
- Orphaned file cleanup
### SvSubObjectPool
An in-memory `SvObjectPool` (not backed by IndexedDB) designed for cloud sync. Provides:
- `asyncSaveToCloud()` — saves with delta or full upload optimization
- `collectDelta()` — produces incremental changes vs. last synced snapshot
- `asyncCompactToCloud()` — consolidates deltas into a single pool file
- `fromCloudJson(json)` — reconstructs the pool from cloud data
- `asJson()` — serializes the complete pool for upload
### SvSyncCollectionSource
Abstract base class for collection syncing. Defines the interface for:
- `asyncSyncFromSource()` — pull from cloud
- `asyncLazySyncFromSource()` — create stubs for lazy loading
- `asyncSyncToSource()` — push to cloud
## Relationship to Local Persistence
| Component | Backing Store | Cloud Sync | Purpose |
|-----------|--------------|------------|---------|
| `SvPersistentObjectPool` | IndexedDB | No | Local app state (singleton, never synced directly) |
| `SvSubObjectPool` | In-memory | Yes | Session-level cloud sync with delta support |
| `SvCloudSyncSource` | Firebase Storage | Yes | Collection-level cloud sync with manifests |
The local `SvPersistentObjectPool` is the ground truth for the running application. Cloud sync operates alongside it — collections push individual items, while sessions create a `SvSubObjectPool` snapshot for upload.
## Auto-Sync Triggers
Cloud sync is triggered automatically on:
- Tab visibility change (switching back to the app)
- Browser `beforeunload` event
- Network online/offline transitions
- Manual save actions
---
Source: /docs/Persistence/Local%20and%20Cloud%20Blob%20Storage/
# Local and Cloud Blob Storage
Content-addressable storage for binary data like images, audio, and video.
## Motivation
The system addresses a fundamental challenge in web applications: **efficiently managing large binary data (images, audio, video) separately from structured object data**.
**Key problems solved:**
1. **Synchronous vs Async APIs**: The main `SvObjectPool` persistence system uses synchronous operations for fast object loading. Binary blobs are large and require async I/O. Separating them prevents blocking.
2. **Deduplication**: Images or media might be referenced by multiple objects. Content-addressable storage (keyed by SHA-256 hash) means identical blobs are stored once.
3. **Lazy Loading**: Objects can be loaded quickly with just a hash reference. The actual blob data is fetched on-demand when needed.
4. **Cloud Sync**: `SvCloudBlobNode` extends local storage to support pushing/pulling blobs to Google Cloud Storage.
### Why Not Store Everything in Firebase Firestore?
Firebase Firestore has constraints that make it unsuitable for storing the complete object graph directly:
1. **Document Size Limit**: Firestore enforces a **1MB maximum document size**. Objects that serialize themselves along with their contained children can easily exceed this limit (e.g., a campaign with locations, NPCs, treasures, and session history).
2. **No Graph Traversal**: If we fully decomposed storage to one document per object, retrieving an object graph would require **many sequential round trips**. Firestore has no support for traversing a directed graph of references in a single request - each document fetch is independent.
3. **Batching Limits**: Storing each object as its own document hits Firestore's batching limits (500 operations per batch). This makes bulk operations slow and would require additional synchronization mechanisms to ensure consistency across related documents.
**The solution**: Store structured object data as larger, more self-contained documents locally (IndexedDB), and sync to cloud storage at a higher granularity. Binary blobs are separated out because they're the primary driver of document size, and content-addressable storage means they can be efficiently synced and deduplicated independently.
---
## Solution Summary
The solution uses a **dual-database architecture** with hash-based references between them:
| Component | Purpose | Storage |
|-----------|---------|---------|
| **SvObjectPool** | Stores structured objects (characters, sessions, etc.) | IndexedDB (sync API) |
| **SvBlobPool** | Stores binary blobs (images, audio, video) | Separate IndexedDB (async API) |
**The key insight**: Objects don't store blobs directly. Instead, they store a SHA-256 hash that acts as a pointer to the blob in `SvBlobPool`. This provides:
- **Fast object loading** - Objects load synchronously with just a small hash string
- **Lazy blob fetching** - Actual binary data loads asynchronously when needed
- **Automatic deduplication** - Same content = same hash = stored once
- **Simple GC** - Collect all referenced hashes from objects, delete everything else from blob storage
**Three-layer class hierarchy**:
1. **SvBlobPool** - Low-level blob storage engine (store/retrieve by hash)
2. **SvBlobNode** - Node wrapper that manages a blob reference with lazy loading
3. **SvCloudBlobNode** - Adds cloud push/pull for cross-device sync
Media-specific classes like **SvImageNode** and **SvVideoNode** extend `SvCloudBlobNode` to add format-specific behavior (MIME type handling, thumbnails, etc.) while inheriting all the storage and sync capabilities.
---
## SvBlobPool - The Blob Storage Engine
**Location**: `strvct/source/library/node/storage/base/SvBlobPool.js`
**Core concept**: A singleton that provides content-addressable blob storage using IndexedDB.
### Key Implementation Details
1. **Storage Format**:
- `{sha256-hash}` → ArrayBuffer (the actual blob data)
- `{sha256-hash}/meta` → JSON metadata (contentType, size, timeCreated, customMetadata)
2. **Deduplication**: When storing a blob, it computes the SHA-256 hash. If that hash already exists, the store is skipped.
3. **Weak Reference Cache**: Uses `SvEnumerableWeakMap` for `activeBlobs` - blobs in memory are cached by hash, but can be garbage collected when not in use.
4. **Concurrency Control**: Tracks active read/write operations via `activeReadsMap` and `activeWritesMap` to prevent duplicate concurrent operations on the same hash.
5. **Garbage Collection**: The `asyncCollectUnreferencedKeySet()` method removes blobs not in a provided set of referenced hashes.
### API
```javascript
// Store - returns the SHA-256 hash
const hash = await SvBlobPool.shared().asyncStoreBlob(blob, {customMeta: "value"});
// Retrieve
const blob = await SvBlobPool.shared().asyncGetBlob(hash);
// Check existence
const exists = await SvBlobPool.shared().asyncHasBlob(hash);
// Metadata only (without loading blob data)
const meta = await SvBlobPool.shared().asyncGetMetadata(hash);
```
---
## SvBlobNode - The Node Wrapper
**Location**: `strvct/source/library/node/blobs/SvBlobNode.js`
**Core concept**: A storable node that holds a reference to a blob via its hash, with lazy loading.
### Key Slots
- `valueHash` (stored): The SHA-256 hash - persisted with the object
- `blobValue` (transient): The actual Blob object - not persisted, loaded on demand
### Key Behaviors
1. **Lazy Loading**: `asyncBlobValue()` checks if the blob is loaded; if not, fetches it from `SvBlobPool` using the stored hash.
2. **Auto-hashing**: When `blobValue` is set, `didUpdateSlotBlobValue()` automatically computes the hash and writes to local storage.
3. **GC Integration**: `referencedBlobHashesSet()` returns the hash for garbage collection coordination with `SvObjectPool`.
---
## SvCloudBlobNode - Cloud Sync Extension
**Location**: `strvct/source/library/node/blobs/SvCloudBlobNode.js`
**Core concept**: Extends `SvBlobNode` with cloud storage push/pull capabilities.
### Additional Slots
- `hasInCloud`: Boolean flag indicating cloud presence
- `downloadUrl`: Public/private URL for cloud retrieval
- `doesAutoSyncToCloud`: When true, automatically pushes to cloud after local storage
### Key Methods
1. **Push to Cloud** (`asyncPushToCloud`):
- Takes local blob, uploads to cloud storage via `SvApp.shared().asyncPublicUrlForBlob()`
- Sets `downloadUrl` and `hasInCloud` flag
2. **Pull from Cloud** (`asyncPullFromCloudByHash`):
- Uses stored hash to fetch blob from cloud: `SvApp.shared().asyncBlobForHash(hash)`
- Caches the retrieved blob locally
3. **Smart Resolution** (`asyncBlobValue`):
- First checks in-memory blob
- Then tries local storage
- Finally falls back to cloud
---
## Data Flow Examples
### Storing an Image
```
User uploads image
↓
SvImageNode.asyncSetBlobValue(blob)
↓
SvBlobNode computes SHA-256 hash
↓
SvBlobPool.asyncStoreBlob() stores ArrayBuffer + metadata
↓
SvBlobNode stores only the hash in SvObjectPool
```
### Loading an Image
```
Object loads from SvObjectPool (has valueHash: "abc123...")
↓
asyncBlobValue() called
↓
Check in-memory cache → miss
↓
SvBlobPool.asyncGetBlob("abc123...") → returns Blob
↓
Blob cached in activeBlobs for future access
```
---
## Garbage Collection Coordination
Since blobs and objects are stored in separate databases, garbage collection requires coordination between `SvObjectPool` and `SvBlobPool` to prevent orphaned blobs from accumulating.
### How It Works
1. **Objects report their blob references**: Any object that holds blob references implements `referencedBlobHashesSet()`, which returns a `Set` of SHA-256 hashes it depends on.
2. **SvObjectPool aggregates all references**: When GC runs, `SvObjectPool.allBlobHashesSet()` iterates through all stored objects, calling `referencedBlobHashesSet()` on each, and combines them into a master set of referenced hashes.
3. **BlobPool removes orphans**: `SvObjectPool.asyncCollectBlobs()` passes this master set to `SvBlobPool.asyncCollectUnreferencedKeySet()`, which:
- Gets all keys currently in blob storage
- Computes the difference (keys in storage but not in the reference set)
- Deletes those orphaned blobs and their metadata
### Code Flow
```
SvObjectPool.asyncCollectBlobs()
↓
SvObjectPool.allBlobHashesSet()
↓
┌───────────────────────────────────────┐
│ for each object in allObjects(): │
│ if object.referencedBlobHashesSet: │
│ hashesSet.addAll(object.referencedBlobHashesSet()) │
└───────────────────────────────────────┘
↓
SvBlobPool.asyncCollectUnreferencedKeySet(hashesSet)
↓
┌───────────────────────────────────────┐
│ allKeys = await idb.promiseAllKeys() │
│ orphans = allKeys.difference(hashesSet) │
│ await idb.promiseRemoveKeySet(orphans) │
└───────────────────────────────────────┘
```
### Implementation Details
**In SvObjectPool** (`SvObjectPool.js`):
```javascript
allBlobHashesSet () {
const hashesSet = new Set();
this.allObjects().forEach(obj => {
if (obj.referencedBlobHashesSet) {
const objBlobHashes = obj.referencedBlobHashesSet();
hashesSet.addAll(objBlobHashes);
}
});
return hashesSet;
}
async asyncCollectBlobs () {
const keySet = this.allBlobHashesSet();
const removedCount = await this.blobPool().asyncCollectUnreferencedKeySet(keySet);
return removedCount;
}
```
**In SvBlobNode** (`SvBlobNode.js`):
```javascript
referencedBlobHashesSet () {
const hashesSet = new Set();
const hash = this.valueHash();
if (hash) {
hashesSet.add(hash);
}
return hashesSet;
}
```
### Key Points
- **Mark-and-sweep style**: The approach mirrors classic GC - mark what's referenced, sweep the rest
- **Async-safe**: Blob GC is fully async and doesn't block the synchronous SvObjectPool operations
- **Metadata cleanup**: When a blob is removed, its `/meta` key is also deleted
- **Deduplication preserved**: If multiple objects reference the same hash, the blob stays until all references are gone
---
## Design Strengths
1. **Separation of concerns**: Objects remain lightweight; blobs handled separately
2. **Efficient caching**: Content-addressable means natural deduplication
3. **Progressive loading**: UI can show objects immediately, load media lazily
4. **Cloud-ready**: Clean extension point for cloud sync without changing base storage
5. **GC-aware**: Hash-based references allow proper garbage collection across dual storage systems
---
Source: /docs/Persistence/Local%20Object%20Pools/
# Local Object Pools
IndexedDB-backed persistence for object graphs using dirty tracking and automatic serialization.
## Overview
Strvct's persistence system stores object graphs in the browser's IndexedDB. Rather than requiring explicit save/load calls, it monitors slot changes and automatically commits dirty objects at the end of the event loop. The system is built from three layers:
- **`SvObjectPool`** — Manages an in-memory cache of objects indexed by persistent unique IDs (puuids). Tracks dirty objects and handles serialization, deserialization, and garbage collection.
- **`SvPersistentAtomicMap`** — An IndexedDB wrapper that loads the entire database into memory on open, provides synchronous read/write to the cache, and batches writes into atomic IndexedDB transactions on commit.
- **`SvStorableNode`** — A node base class that hooks slot changes into the dirty tracking system.
## Opting Into Persistence
### Marking a Node as Storable
A node class opts into persistence by calling `setShouldStore(true)` in its `initPrototype()` method:
```javascript
(class MyNode extends SvStorableNode {
initPrototypeSlots () {
{
const slot = this.newSlot("name", "");
slot.setSlotType("String");
slot.setShouldStoreSlot(true);
}
{
const slot = this.newSlot("score", 0);
slot.setSlotType("Number");
slot.setShouldStoreSlot(true);
}
{
const slot = this.newSlot("cachedResult", null);
// Not stored — transient, recomputed at runtime
}
}
initPrototype () {
this.setShouldStore(true);
this.setShouldStoreSubnodes(true);
}
}.initThisClass());
```
### What Gets Stored
Two flags control what is persisted:
- **`setShouldStore(true)`** on the node — enables persistence for the node itself. Without this, the node and all its slots are ignored by the storage system.
- **`setShouldStoreSlot(true)`** on individual slots — marks that slot's value for inclusion in the serialized record. Slots without this flag are transient and will be lost on reload.
A third flag controls whether child nodes are stored:
- **`setShouldStoreSubnodes(true)`** — persists the node's `subnodes` array. Used for collection nodes where children are the primary data. When false, subnodes are transient and must be recreated on load (typically via `setFinalInitProto()` on slots with `setIsSubnodeField(true)`).
### Inheritance
Storage capability begins at `SvStorableNode` in the class hierarchy:
```
ProtoClass → SvNode → SvTitledNode → SvInspectableNode → SvViewableNode → SvStyledNode → SvStorableNode
```
Classes above `SvStorableNode` cannot be stored. Application model classes typically extend `SvStorableNode` or one of its subclasses like `SvSummaryNode`.
## Persistent Unique IDs
Every stored object has a **puuid** — a 10-character random string (A-Za-z0-9) that serves as its key in the object pool. Puuids are generated on first access via `crypto.getRandomValues()` and stored as a non-enumerable `_puuid` property on the object.
Puuids serve two purposes:
1. **Storage key** — the puuid is the key under which the object's serialized record is stored in IndexedDB.
2. **Object references** — when one stored object references another, the reference is serialized as `{ "*": "puuid" }` rather than inlining the referenced object. This allows the storage system to trace the object graph for garbage collection.
## Serialization Format
Each stored object is serialized as a JSON record with a type field and an entries array:
```json
{
"type": "MyNode",
"entries": [
["name", "Alice"],
["score", 42],
["inventory", { "*": "aB3xK9mQ2p" }]
]
}
```
Primitive values (strings, numbers, booleans, null) are stored inline. Object references are stored as `{ "*": "puuid" }` pointers. The `type` field identifies the class so the correct constructor can be used on deserialization.
### Serialization Methods
- **`recordForStore(aStore)`** — iterates all slots with `shouldStoreSlot() == true`, calls `aStore.refValue()` on each value to handle object references, and returns the record.
- **`loadFromRecord(aRecord, aStore)`** — iterates the record's entries, calls `aStore.unrefValue()` to resolve references back to live objects, and sets each slot value.
## Dirty Tracking and Automatic Commits
The persistence system uses automatic dirty tracking so application code never needs to call save explicitly.
### The Mutation Flow
1. A slot value changes (via its setter method).
2. `SvStorableNode.didUpdateSlot()` checks whether the node and slot are both marked for storage.
3. If so, it calls `didMutate()`, which notifies the `SvObjectPool` via a mutation observer.
4. The pool calls `addDirtyObject(obj)` to add the object to its dirty set.
5. `addDirtyObject()` calls `scheduleStore()`, which uses `SvSyncScheduler` to defer the commit.
6. At the end of the event loop, `commitStoreDirtyObjects()` runs, serializing all dirty objects and writing them to IndexedDB in a single atomic transaction.
Because the commit is deferred, multiple slot changes within the same event loop — even across different objects — are batched into a single IndexedDB transaction. This keeps persistence efficient even when many properties change in rapid succession.
### Commit Details
`commitStoreDirtyObjects()` begins an IndexedDB transaction via `SvPersistentAtomicMap`, then iterates the dirty set. For each dirty object, it calls `recordForStore()` to serialize it and writes the JSON string to the map keyed by puuid. After all objects are stored, the transaction is committed atomically. If any object becomes dirty again during the commit (because serialization triggers side effects), the cycle repeats until the dirty set is empty.
## SvPersistentAtomicMap
`SvPersistentAtomicMap` wraps `SvIndexedDbFolder` with a synchronous in-memory cache. On open, it loads the entire database into a JavaScript Map. All reads are served from memory. Writes go to an in-memory write cache and are flushed to the underlying store in batched transactions on commit. `SvIndexedDbFolder` is the environment abstraction point — it uses native IndexedDB in the browser and LevelDB (via `classic-level`) in Node.js, with the same async API in both cases. See [Headless Execution](../../Lifecycle/Headless%20Execution/index.html) for details on the storage abstraction.
This design means:
- **Reads are synchronous and fast** — no async IndexedDB calls during normal operation.
- **Writes are batched** — many changes are committed in a single IndexedDB transaction.
- **The full dataset is in memory** — suitable for object graphs that fit in browser memory (typically tens of megabytes).
### Transaction Model
1. `promiseBegin()` — snapshots the current state into a write cache.
2. Synchronous operations (`atPut`, `removeKey`) modify the write cache.
3. `promiseCommit()` — applies all changes to IndexedDB in a single transaction.
## Opening the Pool
The application opens the pool once at startup:
```javascript
const pool = SvPersistentObjectPool.sharedPool();
await pool.promiseOpen();
const root = await pool.rootOrIfAbsentFromClosure(() => {
return MyRootNode.clone();
});
```
`promiseOpen()` opens the IndexedDB database, loads all records into memory, and runs garbage collection. `rootOrIfAbsentFromClosure()` loads the existing root object from storage, or creates a new one using the provided closure if no root exists yet.
### Loading Cascade
Loading the root object triggers a cascade: as each object is deserialized, its slot values that contain `{ "*": "puuid" }` references cause those referenced objects to be loaded in turn. After all objects in the reachable graph have been loaded, `finalInit()` is called on each to re-establish object relationships, followed by `afterInit()`.
## Class Name Migrations
Renaming a stored class would normally break deserialization: existing IndexedDB records still reference the old class name in their `type` field, and `classForName()` would fail to find the renamed class. To avoid a forced data migration, the pool supports a **conversion map** that routes old class names to their new names at load time.
### Registering Conversions
Before opening the pool, register the old→new mappings:
```javascript
const store = this.defaultStore();
store.addClassNameConversion("OldName", "NewName");
// or for many at once:
store.addClassNameConversionTuples([
["OldName", "NewName"],
["AnotherOldName", "AnotherNewName"]
]);
await store.promiseOpen();
```
`classForName()` checks the map first — if an entry exists, it looks up the new name instead. Stored records are left unchanged on disk; next time each object is saved, it's written with the new class name, so the database gradually migrates itself.
### When to Use It
- **Any rename of a stored class** — classes that `extend SvStorableNode` (directly or indirectly) have their names embedded in records, so a rename without a conversion mapping will strand that data.
- **Permanent retention** — keep every mapping forever unless you're certain no user has stale data. Removing an entry later breaks any client whose IndexedDB predates the rename.
### Scope
The conversion map only affects record deserialization. It does **not** rewrite code, JSDoc, or string literals elsewhere in the codebase — those must be updated directly (see the codemod pattern in `ClassRenames.json`).
## Garbage Collection
The pool uses mark-and-sweep garbage collection to remove unreachable objects:
1. **Mark** — starting from the root object's puuid, recursively walk all `{ "*": "puuid" }` references in stored records, marking each visited puuid.
2. **Sweep** — delete any stored records whose puuids were not marked.
Garbage collection runs automatically when the pool opens. It ensures that objects which are no longer reachable from the root — for example, nodes removed from a collection — are cleaned up from IndexedDB.
Blob garbage collection runs separately via `SvBlobPool` (see [Local and Cloud Blob Storage](../Local%20and%20Cloud%20Blob%20Storage/index.html)).
## SvSubObjectPool
`SvSubObjectPool` is an in-memory variant of `SvObjectPool` used for cloud sync rather than local persistence. It uses a plain `SvAtomicMap` instead of `SvPersistentAtomicMap` (no IndexedDB) and does not auto-schedule commits. Instead, it provides explicit methods for cloud upload with delta optimization. See [Cloud Object Pools](../Cloud%20Object%20Pools/index.html) for details.
## Key Classes Summary
| Class | Purpose |
|-------|---------|
| `SvObjectPool` | Base pool: object cache, dirty tracking, serialization, GC |
| `SvPersistentObjectPool` | Singleton `SvObjectPool` backed by IndexedDB |
| `SvPersistentAtomicMap` | IndexedDB wrapper with synchronous in-memory cache |
| `SvStorableNode` | Node base class that hooks slot changes to dirty tracking |
| `SvSubObjectPool` | In-memory pool for cloud sync (no IndexedDB) |
---
Source: /docs/Programming%20Idioms/
# Programming Idioms
Recurring patterns and conventions for writing STRVCT code.
- Style Guide
- Async Patterns
- Categories
- Protocols
---
Source: /docs/Programming%20Idioms/Async%20Patterns/
# Async Patterns
Extended promises, serial and parallel iteration, and concurrency control.
## Promise.clone()
STRVCT extends the native `Promise` class (via `Promise_ideal.js`) with a factory method that exposes the resolve and reject functions as callable methods on the promise itself. This is the foundation for most async coordination in the framework.
```javascript
const promise = Promise.clone();
promise.setLabel("loadUserData");
// Later, from any code that holds a reference:
promise.callResolveFunc(result);
// or:
promise.callRejectFunc(error);
```
### Why not `new Promise()`?
The native constructor captures resolve/reject inside the executor callback, making them inaccessible outside it. `Promise.clone()` stores them as properties so the promise can be resolved externally — by a different method, a timer, or a network callback — without nesting all the logic inside the constructor.
### Status tracking
Cloned promises track their state explicitly:
```javascript
promise.isPending() // true until resolved or rejected
promise.isResolved() // true after callResolveFunc()
promise.isRejected() // true after callRejectFunc()
promise.isCompleted() // true if resolved or rejected
```
Calling `callResolveFunc()` or `callRejectFunc()` on an already-completed promise throws an assertion error, catching double-resolution bugs immediately.
### Timeouts
```javascript
const promise = Promise.clone();
promise.setLabel("apiCall");
promise.beginTimeout(5000); // reject after 5 seconds if still pending
```
The timeout auto-cancels on resolution or rejection. The rejection message includes the label and duration for debugging.
### Await hooks
```javascript
const promise = Promise.clone();
promise.setOnAwaitFunc((p) => {
// Called the first time someone awaits this promise.
// Useful for lazy initialization — don't start the work
// until someone actually needs the result.
startExpensiveOperation(p);
});
```
The framework also tracks `hasAwaiters()` — whether anyone is currently waiting on the promise.
### Common pattern: deferred resolution
The most frequent use of `Promise.clone()` is to bridge callback-style or event-driven code into async/await:
```javascript
async fetchData () {
const promise = Promise.clone();
promise.setLabel("fetchData");
promise.beginTimeout(10000);
this.setOnResponseCallback((data) => {
promise.callResolveFunc(data);
});
this.setOnErrorCallback((error) => {
promise.callRejectFunc(error);
});
this.sendRequest();
return promise;
}
```
## Array async iteration
`Array_promises.js` adds methods for controlled async iteration. These are categories on `Array`, so they're available on any array.
### Serial iteration
```javascript
await items.promiseSerialForEach(async (item, index) => {
await processItem(item);
});
```
Processes one item at a time, in order. Throws immediately if any iteration fails.
### Serial with yielding
```javascript
await items.promiseSerialTimeoutsForEach(async (item, index, total) => {
await processItem(item);
}, 0); // delay in ms between iterations
```
Like serial, but inserts a `setTimeout` between iterations. This yields control back to the event loop between items, preventing UI freezes during long-running sequences. A delay of `0` still yields; higher values add intentional pacing.
### Parallel
```javascript
const results = await items.promiseParallelMap(async (item) => {
return await transform(item);
});
// or when you don't need results:
await items.promiseParallelForEach(async (item) => {
await processItem(item);
});
```
All items processed concurrently via `Promise.all()`. Fast, but can overwhelm APIs or exhaust resources if the array is large.
### Concurrency-limited batching
```javascript
await items.promiseConcurrentSerialTimeoutsForEach(
async (item, index, total) => {
await callApi(item);
},
3, // maxConcurrent — at most 3 in flight at once
100, // delay in ms between batches
async (error, item, index) => {
// optional error handler — log and continue
console.error("Failed:", item, error);
}
);
```
The workhorse for API-heavy operations. Runs up to `maxConcurrent` items simultaneously, yields between batches, and supports per-item error handling without aborting the whole sequence. Uses `Promise.clone()` internally for coordination.
## Choosing the right iteration method
| Method | Concurrency | Yielding | Error handling | Use when |
|--------|------------|----------|----------------|----------|
| `promiseSerialForEach` | 1 | No | Fail-fast | Order matters, small arrays |
| `promiseSerialTimeoutsForEach` | 1 | Yes | Fail-fast | Order matters, UI must stay responsive |
| `promiseParallelMap` | All | No | Fail-fast | Independent items, bounded array size |
| `promiseConcurrentSerialTimeoutsForEach` | N | Yes | Configurable | API calls, large arrays, rate limiting |
---
Source: /docs/Programming%20Idioms/Categories/
# Categories
Extending existing classes by adding methods from separate files.
## Overview
Categories allow you to add methods to an existing class without modifying its original file. This is borrowed from Objective-C/Smalltalk traditions and is used throughout STRVCT to separate concerns — keeping core class files focused on essential functionality while adding specialized behavior in dedicated files.
A category is a class that extends the target class but calls `initThisCategory()` instead of `initThisClass()`. The framework copies the category's methods onto the target class's prototype rather than creating a new class in the hierarchy.
## Defining a category
```javascript
// SvJsonGroup_patches.js — adds JSON Patch support to SvJsonGroup
(class SvJsonGroup_patches extends SvJsonGroup {
applyJsonPatches (patches) {
// patch implementation
}
applyPatch (operation) {
// single patch operation
}
}.initThisCategory());
```
The key difference from a normal class: `.initThisCategory()` instead of `.initThisClass()`. This tells the framework to merge the methods into the parent class rather than registering a new class.
## Naming convention
Category files use an underscore to separate the base class name from the category purpose:
```
SvJsonGroup.js // base class
SvJsonGroup_patches.js // JSON Patch operations
SvJsonGroup_clientState.js // client state tool methods
```
The category class name follows the same pattern: `SvJsonGroup_patches`, `Array_promises`, `Promise_ideal`.
## Loading order
Base classes must be loaded before their categories. In `_imports.json` files, list the base class first:
```json
[
"SvJsonGroup.js",
"SvJsonGroup_patches.js",
"SvJsonGroup_clientState.js"
]
```
If a category loads before its base class, the `extends` clause will fail because the base class doesn't exist yet.
## Extending JavaScript builtins
Categories are commonly used to extend native JavaScript classes. The boot system includes several:
```javascript
// Promise_ideal.js — adds clone(), status tracking, timeouts
(class Promise_ideal extends Promise {
static clone () { /* ... */ }
callResolveFunc (...args) { /* ... */ }
isPending () { /* ... */ }
}.initThisCategory());
// Array_promises.js — adds async iteration methods
(class Array_promises extends Array {
async promiseSerialForEach (aBlock) { /* ... */ }
async promiseParallelMap (aBlock) { /* ... */ }
}.initThisCategory());
```
After these categories load, every `Promise` and `Array` instance has the new methods — no imports needed.
## When to use categories
**Good uses:**
- Separating a large class into thematic files (e.g., persistence, UI, serialization)
- Adding framework methods to JavaScript builtins
- Adding app-specific behavior to framework classes without forking them
- Keeping a base class stable while iterating on extensions
**Avoid when:**
- The methods need their own slots or state — categories can't add slots, only methods
- You need polymorphism (override behavior in subclasses) — a subclass is the right tool
- The base class is in an external library that doesn't use the STRVCT class system
## How it works internally
`initThisCategory()` iterates over the category class's own methods (both prototype and static) and copies them onto the target class. It does not create a new entry in the class registry — `SvJsonGroup_patches` is not a class you can instantiate or look up by name. It's purely a delivery mechanism for methods.
This means:
- `instanceof` checks are unaffected — an `SvJsonGroup` instance won't show as `instanceof SvJsonGroup_patches`
- Category methods have full access to `this` and the base class's slots and methods
- If two categories define the same method name on the same base class, the last one loaded wins (with a warning)
## Related patterns
- [Slot Patterns](../Slot%20Patterns/index.html) — how to declare properties on classes
- [Lifecycle](../../Lifecycle/index.html) — `initPrototypeSlots` / `initPrototype` and the initialization chain, which categories cannot participate in (only methods are merged)
---
Source: /docs/Programming%20Idioms/Protocols/
# Protocols
Declaring interfaces and verifying conformance at runtime.
## Overview
Protocols are STRVCT's interface system. A protocol defines a set of methods that a class promises to implement. Unlike duck-typing (where you check for individual methods at call sites), protocols give the contract a name, make it inheritable, and verify it at registration time rather than at the point of use.
The most important property of the protocol system is **fail-fast verification**: when a class declares that it conforms to a protocol, the framework immediately checks that all required methods are present. **If any are missing, an error is thrown at startup** -- not later when a rarely-exercised code path happens to call the missing method. This moves an entire category of bugs from runtime surprises to immediate, deterministic failures.
The conformance check is also designed to be very fast. It uses a single set-subset operation -- each required method name is looked up in the class's `Set` of slot names in O(1). Since this runs once at startup during class registration, there is zero per-call overhead. The cost is paid once, upfront, and the guarantee holds for the lifetime of the application.
The system is inspired by Objective-C's `@protocol` and Smalltalk's message categories.
## Defining a protocol
A protocol is a subclass of `Protocol` that lists the required methods as empty instance methods:
```javascript
(class SvAudioClipProtocol extends Protocol {
play () {
}
addDelegate (audioClipDelegate) {
}
removeDelegate (audioClipDelegate) {
}
stop () {
}
}.initThisProtocol());
```
Key points:
- Call `.initThisProtocol()` instead of `.initThisClass()`. This registers the protocol and asserts the naming convention.
- The class name **must** end with `Protocol` (enforced at runtime).
- Method bodies are empty -- they exist to declare the interface, not to provide default implementations.
- Use the `@interface` JSDoc tag (not `@class`) in the file's module comment.
## Implementing a protocol
A class declares conformance by calling `addProtocol()` in its `initPrototype()` method:
```javascript
(class SvWaSound extends SvSummaryNode {
initPrototype () {
this.addProtocol(SvAudioClipProtocol);
}
play () {
// actual implementation
}
addDelegate (audioClipDelegate) {
// actual implementation
}
removeDelegate (audioClipDelegate) {
// actual implementation
}
stop () {
// actual implementation
}
}.initThisClass());
```
When `addProtocol()` is called, the framework immediately checks that the class's methods satisfy the protocol. If any required method is missing, an error is thrown at class-registration time -- not later when the method would have been called.
## Verification API
The protocol system provides several methods on `ProtoClass` (available to all STRVCT classes):
| Method | Purpose |
|---|---|
| `addProtocol(protocol)` | Declare conformance; throws if methods are missing |
| `conformsToProtocol(protocol)` | Returns `true` if the class has registered the protocol |
| `assertConformsToProtocol(protocol)` | Throws if the class doesn't conform |
| `methodsConformToProtocol(protocol)` | Returns which methods satisfy the protocol |
| `implementsMethodNamesSet(set)` | Checks if the class implements a given set of method names |
On the `Protocol` class itself:
| Method | Purpose |
|---|---|
| `Protocol.allProtocols()` | Returns all registered protocol subclasses |
| `protocol.addImplementer(class)` | Records a class as an implementer (called automatically by `addProtocol`) |
| `protocol.implementers()` | Returns the set of all classes that conform to this protocol |
## Protocol inheritance
Protocols are classes, so they support inheritance. A protocol can extend another protocol to build larger interfaces from smaller ones:
```javascript
(class SvExtendedAudioProtocol extends SvAudioClipProtocol {
seek (position) {
}
duration () {
}
}.initThisProtocol());
```
A class that conforms to `SvExtendedAudioProtocol` must implement both its own methods and those inherited from `SvAudioClipProtocol`.
## Existing protocols
The framework currently declares four formal protocols:
- **`SvAudioClipProtocol`** -- playback interface: `play()`, `stop()`, `addDelegate()`, `removeDelegate()`
- **`SvAudioClipDelegateProtocol`** -- callback interface: `onSoundEnded(audioClip)`
- **`SvDragSourceProtocol`** -- drag source callbacks: `onDragSourceBegin()`, `onDragSourceDropped()`, `onDragSourceEnd()`, `acceptsDropHover()`, and others
- **`SvDragDestinationProtocol`** -- drop target callbacks: `onDragDestinationEnter()`, `onDragDestinationHover()`, `onDragDestinationExit()`, `acceptsDropHoverComplete()`, `acceptsDrop()`, and others
## Protocols vs. duck-typing
Many parts of the codebase use informal duck-typing -- checking for a method's existence before calling it:
```javascript
if (node && node.nodeAcceptsDrop) {
node.nodeAcceptsDrop(droppedNode);
}
```
This works, but it has drawbacks:
- The interface contract is implicit -- you have to read call sites to discover what methods are expected.
- There's no early verification -- a missing method surfaces only when the code path is hit at runtime.
- There's no way to query which classes implement the interface.
Formal protocols address all three. The trade-off is a small amount of ceremony (defining the protocol class and calling `addProtocol`). For optional interfaces where not every class is expected to conform, duck-typing remains appropriate. For interfaces that represent a real contract between components, a protocol is the better choice.
## Naming conventions
- Protocol class names always end with `Protocol`: `SvAudioClipProtocol`, `SvDragSourceProtocol`
- Protocol files live alongside the classes they relate to (e.g., the audio protocols are in `library/node/audio/`)
- Delegate protocols follow the pattern `SvThingDelegateProtocol` for callback interfaces
## Related patterns
- [Categories](../Categories/index.html) -- extending classes with methods from separate files (protocols define *what* methods to implement; categories *add* methods)
- [Complete Protocols](../../Future%20Work/Complete%20Protocols/index.html) -- future work on formalizing the codebase's many undeclared protocols
---
Source: /docs/Programming%20Idioms/Style%20Guide/
# Style Guide
Naming conventions, formatting rules, and code structure patterns.
## Classes
Class names use UpperCamelCase with a two-letter prefix indicating their origin:
- **`Sv`** -- framework classes: `SvNode`, `SvStorableNode`, `SvJsonGroup`, `SvNotificationCenter`
- **Application prefix** -- applications built on STRVCT should choose their own short prefix and use it consistently for all custom classes. The prefix doesn't need to be two characters -- any short, distinctive prefix works (`Uo`, `App`, `Xyz`). This prevents name collisions between framework, application, and third-party code.
The prefix is not applied to external libraries or JavaScript builtins extended via categories.
Acronyms are treated as a single capitalized unit: `SvJsonGroup` (not `SvJSONGroup`), `SvAiService`, `SvHttpResponseCodes`, `SvDbTable`.
**View classes** append `View` to the model class name. The framework uses this convention to automatically discover the view for a given node:
| Model class | View class |
|---|---|
| `SvNode` | `SvNodeView` |
| `SvField` | `SvFieldView` |
Classes use the self-initializing pattern -- the class expression is wrapped in parentheses and `.initThisClass()` is called inline:
```javascript
(class SvTimeFormatter extends SvNode {
// ...
}.initThisClass());
```
This registers the class with the framework immediately upon evaluation.
## Slots
Slot names use lowerCamelCase. The slot system automatically generates a getter and setter from the name:
| Slot declaration | Getter | Setter |
|---|---|---|
| `newSlot("userName", "")` | `userName()` | `setUserName(value)` |
| `newSlot("is24Hour", false)` | `is24Hour()` | `setIs24Hour(value)` |
| `newSlot("subnodes", null)` | `subnodes()` | `setSubnodes(value)` |
Each slot declaration is wrapped in a block scope so `const slot` can be reused without naming collisions:
```javascript
initPrototypeSlots () {
{
const slot = this.newSlot("userName", "");
slot.setSlotType("String");
}
{
const slot = this.newSlot("isActive", false);
slot.setSlotType("Boolean");
}
}
```
### Boolean slots
Boolean slot names use a query-style prefix that reads naturally as a question:
| Prefix | Usage | Examples |
|---|---|---|
| `is` | Identity or state | `isComplete`, `isEditable`, `isLoggedIn` |
| `has` | Possession or presence | `hasShared`, `hasSelection` |
| `can` | Ability or permission | `canDelete`, `canReorderSubnodes`, `canInspect` |
| `should` | Configuration flags | `shouldStore`, `shouldStoreSlot`, `shouldStoreSubnodes` |
| `does` | Behavioral switches | `doesPadHours`, `doesHookSetter` |
| `shows` | Visibility toggles | `showsMeridiem`, `showsHours` |
## Instance Variables
Instance variables use an underscore prefix (`_userName`, `_isActive`) and are subject to three rules:
### 1. Always declare via `newSlot()`
Never assign an instance variable directly. All instance variables are created by the slot system in `initPrototypeSlots()`:
```javascript
// Correct
{
const slot = this.newSlot("userName", "");
slot.setSlotType("String");
}
// Wrong -- bypasses the slot system entirely
this._userName = "";
```
Declaring variables through `newSlot()` ensures they participate in the framework's infrastructure: getter/setter generation, dirty tracking, persistence, view synchronization, JSON Schema, and ARIA metadata. A manually assigned `_` variable gets none of this.
### 2. Internal access: use the getter
Within the same object, access instance variables through the generated getter (`this.userName()`), not directly (`this._userName`). The getter is the standard access path; direct access is reserved for rare, performance-critical cases where you intentionally need to skip hooks.
```javascript
// Standard -- uses the getter
formattedName () {
return this.userName().toUpperCase();
}
// Avoid -- skips hooks, breaks the uniform access pattern
formattedName () {
return this._userName.toUpperCase();
}
```
Bypassing the getter may seem harmless for reads, but it creates a maintenance hazard: if a subclass or category overrides the getter (to add lazy initialization, computed values, or delegation), direct `_` access silently bypasses that override.
### 3. External access: always use the getter
Accessing another object's instance variables directly (`other._userName`) is never acceptable. External code must always go through the public getter (`other.userName()`). This isn't just convention -- the setter performs dirty tracking for persistence, posts `didUpdateSlot` notifications, and schedules view sync. A direct `other._name = x` silently breaks storage, UI updates, and any observers watching that slot.
```javascript
// Correct
player.setUserName("Alice");
const name = player.userName();
// Wrong -- breaks persistence, notifications, and view sync
player._userName = "Alice";
const name = player._userName;
```
## Methods
Methods use lowerCamelCase. There is no `get` prefix -- a bare noun is the getter. This follows the Uniform Access Principle: `node.name()` and `node.formattedName()` look identical at call sites, so callers don't know or care whether a value is stored or computed. The naming doesn't leak implementation details into the API.
### Short methods
Methods should do one thing. If a method is growing long, extract named helper methods -- even if each helper is only called once. Small methods with descriptive names are easier to read, override, and debug than large methods with inline comments explaining each section.
### Method chaining
Setters and configuration methods return `this` to support chaining:
```javascript
slot.setSlotType("String").setShouldStoreSlot(true).setSyncsToView(true);
```
All `init` methods (`init()`, `finalInit()`, `afterInit()`) should also return `this`.
### Getters and setters
- **Getter**: `propertyName()` -- bare name, no prefix
- **Setter**: `setPropertyName(value)` -- `set` prefix, UpperCamelCase property name
- **Computed getters**: descriptive name for the derived value: `formattedValue()`, `visibleClassName()`, `hoursString()`
Do **not** use ES6 `get`/`set` property definitions. Beyond conflicting with the slot system, ES6 getters make property access and method calls syntactically indistinguishable -- `obj.name` could be a simple read or an expensive computation. With `obj.name()`, the parentheses consistently signal "this is a method call", which matters in a framework where slot access triggers hooks.
### Lifecycle methods
The initialization chain uses reserved names in a fixed order:
1. `initPrototypeSlots()` -- declare slots
2. `initPrototype()` -- configure class-wide behavior
3. `init()` -- basic instance setup
4. `finalInit()` -- complex initialization, object relationships
5. `afterInit()` -- post-initialization tasks
`initPrototypeSlots()` and `initPrototype()` should **never** call `super` -- the framework walks the class hierarchy automatically, calling each level in base-to-derived order. Adding `super` would cause each level to execute multiple times. The other init methods (`init()`, `finalInit()`, `afterInit()`) **should** call `super`.
### Event methods
Three prefix conventions distinguish when and how events are handled:
| Prefix | Timing | Examples |
|---|---|---|
| `will` | Before something happens | `willRemoveSubnode()` |
| `did` | After something happened | `didUpdateSlot()`, `didChangeSubnodeList()`, `didInit()` |
| `on` | In response to an external event | `onDragSourceBegin()`, `onSoundEnded()`, `onBrowserDropChunk()` |
`did` and `will` are typically used for internal lifecycle notifications. `on` is used for callbacks from other objects (delegates, gesture recognizers, external events).
### Async methods
Async methods use the `async` keyword and an `async` prefix in the method name:
```javascript
async asyncStoreBlob (blob) { ... }
async asyncGetBlob (hash) { ... }
async asyncCollectUnreferencedKeySet () { ... }
```
The prefix makes async operations searchable (`grep "asyncLoad"` finds all of them) and self-documenting at call sites -- `await node.asyncLoadChildren()` is immediately clear without checking the declaration.
### Factory methods
- `clone()` -- standard instantiation (called on the class: `SvNode.clone()`)
- `shared()` -- singleton access (called on the class: `SvNotificationCenter.shared()`)
- `newSlot()`, `newSubnode()`, `newObservation()` -- create and return a child object owned by the receiver
## Categories
Category files use an underscore to separate the base class name from the category purpose:
```
SvJsonGroup.js // base class
SvJsonGroup_patches.js // JSON Patch operations
SvJsonGroup_clientState.js // client state tool methods
SvTile_dragging.js // drag behavior
SvTile_keyboard.js // keyboard handling
```
The category class name matches the filename: `SvJsonGroup_patches`, `SvTile_dragging`. The underscore convention makes it easy to see at a glance which class is being extended and what the extension adds.
See [Categories](../Categories/index.html) for details on how categories work.
## Protocols
Protocol class names **must** end with `Protocol` (enforced at runtime by `initThisProtocol()`):
```
SvAudioClipProtocol
SvAudioClipDelegateProtocol
SvDragSourceProtocol
SvDragDestinationProtocol
```
Delegate protocols follow the pattern `SvThingDelegateProtocol` -- naming the object that receives the callbacks, not the object that sends them.
Protocol files follow the standard one-class-per-file rule and live alongside the classes they relate to, not in a central directory:
```
library/node/audio/SvAudioClipProtocol.js
library/node/audio/SvAudioClipDelegateProtocol.js
library/node/node_views/.../SvTilesView/SvDragSourceProtocol.js
library/node/node_views/.../SvTilesView/SvDragDestinationProtocol.js
```
See [Protocols](../Protocols/index.html) for details on defining and implementing protocols.
## Files and directories
**One class per file.** The filename matches the class name: `SvNode.js`, `SvTimeFormatter.js`. Category files follow the `ClassName_category.js` pattern. This makes finding a class's source trivial -- the filename is the class name -- and matches the `_imports.json` resource loading system's assumption of one declaration per file.
**No import/require.** STRVCT uses its own resource loading system based on `_imports.json` files, not standard JavaScript modules. The CAM (Content-Addressable Memory) loader provides content-based caching, deduplication, and atomic updates that standard ES modules can't. Do not add `import` or `require` statements to framework code.
**Directory names** are lowercase or lowerCamelCase, organized by function:
| Directory | Purpose |
|---|---|
| `library/ideal/` | Base classes, formatters, utilities |
| `library/node/` | Node hierarchy, storage, views |
| `library/view/` | View layer, DOM abstractions |
| `library/services/` | AI, cloud storage, media services |
| `browser-only/` | Excluded in Node.js environments |
| `server-only/` | Excluded in browser environments |
## Notifications
Notification names follow the `did`/`will` pattern used by event methods. When stored as a slot for reuse, they use a `Note` suffix:
```javascript
// Declaring a notification slot
this.newSlot("didUpdateNodeNote", null);
// Posting
this.postNoteNamed("onRequestNavigateToNode", this);
```
## Slot types
The `setSlotType()` method takes a string matching either a JavaScript built-in or a STRVCT class name:
- **Primitives**: `"String"`, `"Number"`, `"Boolean"`, `"Array"`, `"Date"`
- **Framework types**: `"SvNode"`, `"SvNotification"`, `"SvSubnodesArray"`
- **Semantic types**: `"Action"`, `"UUID"`, `"Integer"`, `"Float"`
These are used for type checking, JSON Schema generation, and documentation -- not for runtime enforcement in most cases.
## Things to avoid
- **ES6 `get`/`set` property definitions** -- use `foo()` / `setFoo()` instead. ES6 getters hide method calls behind property-access syntax, making it impossible to distinguish a simple read from a computation with side effects.
- **`import` / `require`** -- use the `_imports.json` resource loading system. The CAM loader provides content-based caching and atomic updates that standard ES modules can't.
- **`super` in `initPrototypeSlots` / `initPrototype`** -- the framework walks the hierarchy automatically. Adding `super` causes each level to execute multiple times.
- **`instance.hasOwnProperty()`** -- use `Object.hasOwn(instance, key)` instead. `hasOwnProperty` is a prototype method that can be shadowed by an object's own property; `Object.hasOwn()` is a static method that can't be overridden.
- **Plain objects as dictionaries** -- use `Map` for key-value collections. Plain objects risk prototype pollution (`toString`, `constructor` as key names), only support string keys, and lack `.size`.
- **Direct instance variable access** -- see [Instance Variables](#instance-variables) for the full rules. In short: always use the getter.
## Formatting
Style rules enforced by ESLint:
- **Space before parentheses** in all function and method declarations: `initPrototype () {`, not `initPrototype() {`. This isn't just cosmetic -- it makes text search unambiguous: `methodName (` finds definitions, `methodName(` finds call sites.
- **Four-space indentation**, no tabs.
- **Semicolons required** at the end of statements. Avoids Automatic Semicolon Insertion edge cases, which matters more than usual in a codebase that loads code via `eval`.
These apply to function declarations, expressions, async functions, and method definitions uniformly.
---
Source: /docs/Reference/
# Reference
Class hierarchy, module hierarchy, and protocol definitions.
- Classes
- Modules
- Protocols
---
Source: /docs/Reference/Classes/
# Classes
Complete class inheritance hierarchy.
- Object
- [AjvValidator](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2FAjvValidator.js)
- Array
- [Array_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FArray_ideal.js)
- [Array_promises](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fcategories%2FArray_promises.js)
- [Array_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FArray_store.js)
- [SvHookedArray](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcollections%2FSvHookedArray.js)
- [SvIndexedArray](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcollections%2FSvIndexedArray.js)
- [SvSortedArray](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcollections%2FSvSortedArray.js)
- [SvSubnodesArray](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2FSvSubnodesArray.js)
- ArrayBuffer
- [ArrayBuffer_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FArrayBuffer_ideal.js)
- [ArrayBuffer_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FArrayBuffer_store.js)
- [Base](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FBase.js)
- [BaseHttpsServer](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FBaseHttpsServer.js)
- [BaseHttpsServerRequest](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FBaseHttpsServerRequest.js)
- [AcmeChallengeRequest](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2Frequests%2FAcmeChallengeRequest.js)
- [FileRequest](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2Frequests%2FFileRequest.js)
- [CliWebServer](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FCliWebServer.js)
- [SvMimeExtensions](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FSvMimeExtensions.js)
- [SvBasicJsonRepairShop](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fjson%2FSvBasicJsonRepairShop.js)
- [BigInt_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FBigInt_store.js)
- Blob
- [Blob_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FBlob_ideal.js)
- Boolean
- [Boolean_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FBoolean_ideal.js)
- [Boolean_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2Fliterals%2FBoolean_store.js)
- [ContentBase](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentBase.js)
- [ContentCards](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentCards.js)
- [ContentImage](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentImage.js)
- [ContentKeyValue](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentKeyValue.js)
- [ContentOrderedList](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentOrderedList.js)
- [ContentTable](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentTable.js)
- [ContentText](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentText.js)
- [ContentTimeline](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentTimeline.js)
- [ContentToc](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentToc.js)
- [ContentUnorderedList](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentUnorderedList.js)
- Date
- [Date_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FDate_ideal.js)
- [Date_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FDate_store.js)
- [SvEnumerableWeakMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fweak%2FSvEnumerableWeakMap.js)
- [SvEnumerableWeakSet](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fweak%2FSvEnumerableWeakSet.js)
- Error
- [SvAiRequestOverloadedError](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FRequests%2Ferrors%2FSvAiRequestOverloadedError.js)
- [Error_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FError_ideal.js)
- [Error_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FError_store.js)
- [SvMissingSlotError](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_copying.js)
- [o](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [a](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [s](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [SvJsonPatchError](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2Fpatches%2FSvJsonPatchError.js)
- [FileReader](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FFileReaderShim.js)
- [FontFace](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FFontFaceShim.js)
- [HTMLCanvasElement](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FImageShim.js)
- [HTMLElement_textField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2Fbrowser-only%2FHtmlElement_textField.js)
- [i](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [c](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [f](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [h](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [S](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [v](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [y](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [_](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [b](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [E](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [$](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [g](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [k](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [N](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [P](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [m](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [p](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [u](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [Image](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FImageShim.js)
- [Image_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FImage_ideal.js)
- [Image_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FImage_store.js)
- [ImportsIndexer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Findex-builder%2FImportsIndexer.js)
- [j](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [JsClassParser](../../resources/class-doc/class_doc.html?path=%2Fdocs%2Fresources%2Fclass-doc%2Fclass_doc_parser.js)
- [JsonRepairShop](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fjsonrepair%2FJsonRepairShop.js)
- [l](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [d](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- Map
- [SvFifoMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FSvFifoMap.js)
- [SvHookedMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcollections%2FSvHookedMap.js)
- [Map_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FMap_ideal.js)
- [Map_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FMap_store.js)
- [SvMarkdownRelative](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmarkdown%2FSvMarkdownRelative.js)
- [SvMarkdownToc](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmarkdown%2FSvMarkdownToc.js)
- [MinimalIndexedDbFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fserver-only%2Ftests%2FMinimalLevelDbWrapper.js)
- [Mirror](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FMirror.js)
- [n](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- Number
- [Number_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FNumber_ideal.js)
- [Number_random](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FNumber_random.js)
- [Number_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2Fliterals%2FNumber_store.js)
- [Object_boot](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fcategories%2FObject_boot.js)
- [Object_categorySupport](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fcategories%2FObject_categorySupport.js)
- [Object_class](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_class.js)
- [Object_copying](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_copying.js)
- [Object_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_ideal.js)
- [Object_init](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_init.js)
- [Object_mutation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_mutation.js)
- [Object_notification](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_notification.js)
- [Object_puuid](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_puuid.js)
- [Object_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FObject_store.js)
- [Object_timeouts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_timeouts.js)
- [PageIndex](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FPageIndex.js)
- [SvPersistentAtomicMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fstorage%2FSvPersistentAtomicMap.js)
- [Promise_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fcategories%2FPromise_ideal.js)
- [ProtoClass](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2FProtoClass.js)
- [SvAtomicMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmap%2FSvAtomicMap.js)
- [SvByteFormatter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fformatters%2FSvByteFormatter.js)
- [SvCanvasTextTapeMeasure](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FHelpers%2FTapeMeasures%2FSvCanvasTextTapeMeasure.js)
- [SvCssAnimation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FAttributes%2FSvCssAnimation.js)
- [SvCssColor](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FHelpers%2FSvCssColor.js)
- [SvDevice](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvDevice.js)
- [SvGamePad](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvGamePad.js)
- [SvKeyboardKey](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvKeyboardKey.js)
- [SvMouse](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvMouse.js)
- [SvKeyboard](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvKeyboard.js)
- [SvTouchScreen](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvTouchScreen.js)
- [SvDevices](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvDevices.js)
- [SvDocumentation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmisc%2FSvDocumentation.js)
- [SvDomBorderRadius](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FAttributes%2FSvDomBorderRadius.js)
- [SvDomCssInspector](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FHelpers%2FSvDomCssInspector.js)
- [SvDomTextTapeMeasure](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FHelpers%2FTapeMeasures%2FSvDomTextTapeMeasure.js)
- [SvDomTransition](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FAttributes%2FSvDomTransition.js)
- [SvDomTransitions](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FAttributes%2FSvDomTransitions.js)
- [SvElementDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvElementDomView.js)
- [SvCssDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvCssDomView.js)
- [SvSubviewsDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvSubviewsDomView.js)
- [SvListenerDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvListenerDomView.js)
- [SvVisibleDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvVisibleDomView.js)
- [SvGesturableDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvGesturableDomView.js)
- [SvResponderDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvResponderDomView.js)
- [SvControlDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvControlDomView.js)
- [SvSelectableDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvSelectableDomView.js)
- [SvEditableDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvEditableDomView.js)
- [SvDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvDomView.js)
- [SvDocumentBody](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvDocumentBody.js)
- [SvDomView_animations](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvDomView_animations.js)
- [SvDomView_browserDragAndDrop](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvDomView_browserDragAndDrop.js)
- [SvDragBarView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvDragBarView.js)
- [SvFlexDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvFlexDomView.js)
- [SvButtonView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvButtonView.js)
- [SvTileNoteButtonView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Fsubviews%2FSvTileNoteButtonView.js)
- [SvCloseButton](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvCloseButton.js)
- [SvStyledDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvStyledDomView.js)
- [SvBooleanView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvBooleanView.js)
- [SvDragView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvDragView.js)
- [SvNodeView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvNodeView.js)
- [SvNavView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvNavView.js)
- [SvSceneView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpatial%2FSvSceneView.js)
- [SvScrollContentView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvScrollContentView.js)
- [SvTilesView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView.js)
- [SvTilesView_dragViewProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_dragViewProtocol.js)
- [SvTilesView_gestures](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_gestures.js)
- [SvTilesView_helpers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_helpers.js)
- [SvTilesView_keyboard](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_keyboard.js)
- [SvTilesView_orientation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_orientation.js)
- [SvTilesView_selection](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_selection.js)
- [SvTilesView_styling](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_styling.js)
- [SvStackView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvStackView.js)
- [SvBrowserView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2FSvBrowserView.js)
- [SvCoachableView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvCoachableView.js)
- [SvImageView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvImageView.js)
- [SvImageWellView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvImageWellView.js)
- [SvVideoView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvVideoView.js)
- [SvVideoWellView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvVideoWellView.js)
- [SvTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile.js)
- [SvBreadCrumbsTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvBreadCrumbsTile.js)
- [SvActionFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvActionFieldTile.js)
- [SvFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvFieldTile.js)
- [SvSceneViewWellFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpatial%2FSvSceneViewWellFieldTile.js)
- [SvBooleanFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvBooleanFieldTile.js)
- [SvImageWellFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvImageWellFieldTile.js)
- [SvStringFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvStringFieldTile.js)
- [SvPasswordFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvPasswordFieldTile.js)
- [SvTextAreaFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvTextAreaFieldTile.js)
- [SvChatMessageTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvChatMessageTile.js)
- [SvChatInputTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvChatInputTile.js)
- [SvVideoWellFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvVideoWellFieldTile.js)
- [SvTextNodeTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTextNodeTile.js)
- [SvTile_dragging](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile_dragging.js)
- [SvTile_gestures](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile_gestures.js)
- [SvTile_keyboard](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile_keyboard.js)
- [SvTile_slideGesture](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile_slideGesture.js)
- [SvTile_styling](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile_styling.js)
- [SvTitledTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTitledTile.js)
- [SvHeaderTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvHeaderTile.js)
- [SvFontTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffonts%2FSvFontTile.js)
- [SvImageTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fimages%2FSvImageTile.js)
- [SvOptionNodeTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2Foptions%2FSvOptionNodeTile.js)
- [SvOptionsNodeTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2Foptions%2FSvOptionsNodeTile.js)
- [SvPointerFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvPointerFieldTile.js)
- [SvTileContainer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvTileContainer.js)
- [SvTextView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvTextView.js)
- [SvPasswordView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvPasswordView.js)
- [SvTileNoteView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Fsubviews%2FSvTileNoteView.js)
- [SvTileSubtitleView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Fsubviews%2FSvTileSubtitleView.js)
- [SvTileTitleView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Fsubviews%2FSvTileTitleView.js)
- [SvgIconView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvgIconView.js)
- [SvScrollToBottomButton](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvScrollToBottomButton.js)
- [SvScrollView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvScrollView.js)
- [SvStackScrollView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvStackScrollView.js)
- [SvCoachMarkView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2Fcoachmarks%2FSvCoachMarkView.js)
- [SvOverlayBannerView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvOverlayBannerView.js)
- [SvPanelView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvPanelView.js)
- [SvScrimView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvScrimView.js)
- [SvEventListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2FSvEventListener.js)
- [SvEventManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2FSvEventManager.js)
- [SvEventSetListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2FSvEventSetListener.js)
- [SvAnimationListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvAnimationListener.js)
- [SvBatteryListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvBatteryListener.js)
- [SvClipboardListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvClipboardListener.js)
- [SvDocumentListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvDocumentListener.js)
- [SvDragListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvDragListener.js)
- [SvDropListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvDropListener.js)
- [SvFocusListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvFocusListener.js)
- [SvGamePadListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvGamePadListener.js)
- [SvKeyboardListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvKeyboardListener.js)
- [SvMouseListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvMouseListener.js)
- [SvMouseMoveListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvMouseMoveListener.js)
- [SvScrollListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvScrollListener.js)
- [SvSelectListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvSelectListener.js)
- [SvSpeechListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvSpeechListener.js)
- [SvTouchListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvTouchListener.js)
- [SvTouchMoveListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvTouchMoveListener.js)
- [SvTransitionListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvTransitionListener.js)
- [SvWebSocketListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvWebSocketListener.js)
- [SvWheelListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvWheelListener.js)
- [SvWindowListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvWindowListener.js)
- [SvFirebaseStoragePermissions](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FSvFirebaseStoragePermissions.js)
- [SvGamePadManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvGamePadManager.js)
- [SvGestureManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2FSvGestureManager.js)
- [SvGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2FSvGestureRecognizer.js)
- [SvLongPressGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvLongPressGestureRecognizer.js)
- [SvOrientGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvOrientGestureRecognizer.js)
- [SvPanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvPanGestureRecognizer.js)
- [SvEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2FSvEdgePanGestureRecognizer.js)
- [SvBottomEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fview%2FSvBottomEdgePanGestureRecognizer.js)
- [SvLeftEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fview%2FSvLeftEdgePanGestureRecognizer.js)
- [SvRightEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fview%2FSvRightEdgePanGestureRecognizer.js)
- [SvTopEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fview%2FSvTopEdgePanGestureRecognizer.js)
- [SvScreenEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fscreen%2FSvScreenEdgePanGestureRecognizer.js)
- [SvScreenBottomEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fscreen%2Fsides%2FSvScreenBottomEdgePanGestureRecognizer.js)
- [SvScreenLeftEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fscreen%2Fsides%2FSvScreenLeftEdgePanGestureRecognizer.js)
- [SvScreenRightEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fscreen%2Fsides%2FSvScreenRightEdgePanGestureRecognizer.js)
- [SvScreenTopEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fscreen%2Fsides%2FSvScreenTopEdgePanGestureRecognizer.js)
- [SvPinchGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvPinchGestureRecognizer.js)
- [SvRotationGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvRotationGestureRecognizer.js)
- [SvSlideGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvSlideGestureRecognizer.js)
- [SvTapGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvTapGestureRecognizer.js)
- [SvHtmlStreamReader](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fhtml%2FHtmlStreamReader%2FSvHtmlStreamReader.js)
- [SvHttpResponseCodes](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fnetworking%2FSvHttpResponseCodes.js)
- [SvJsonObject](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FSvJsonObject.js)
- [SvJsonStreamReader](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fjson%2FJsonStreamReader%2FSvJsonStreamReader.js)
- [SvNamespaceSearch](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmisc%2FSvNamespaceSearch.js)
- [SvNumberFormatter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fformatters%2FSvNumberFormatter.js)
- [SvObjectPool](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2FSvObjectPool.js)
- [SvPersistentObjectPool](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2FSvPersistentObjectPool.js)
- [SvSubObjectPool](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2FSvSubObjectPool.js)
- [SvObservableProxy](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproxies%2FSvObservableProxy.js)
- [SvFirewallProxy](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproxies%2FSvFirewallProxy.js)
- [SvPersistentAsyncMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fstorage%2FSvPersistentAsyncMap.js)
- [SvPoint](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fgeometry%2FSvPoint.js)
- [SvEventPoint](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvEventPoint.js)
- [ProtoClass_protocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fprotocol%2FProtoClass_protocol.js)
- [ProtoClass_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2FProtoClass_store.js)
- [ProtoClass_tasks](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2Ftasks%2FProtoClass_tasks.js)
- [Protocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fprotocol%2FProtocol.js)
- [SvAudioClipDelegateProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Faudio%2FSvAudioClipDelegateProtocol.js)
- [SvAudioClipProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Faudio%2FSvAudioClipProtocol.js)
- [SvDragDestinationProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvDragDestinationProtocol.js)
- [SvDragSourceProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvDragSourceProtocol.js)
- [SvRectangle](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fgeometry%2FSvRectangle.js)
- [SvSimpleSynth](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Faudio%2FSvSimpleSynth.js)
- [SvStackFrame](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmisc%2FSvStackTrace.js)
- [SvStackTrace](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmisc%2FSvStackTrace.js)
- [SvStreamNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fhtml%2FHtmlStreamReader%2FSvStreamNode.js)
- [SvStreamElementNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fhtml%2FHtmlStreamReader%2FSvStreamElementNode.js)
- [SvStreamTextNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fhtml%2FHtmlStreamReader%2FSvStreamTextNode.js)
- [SvAsyncTimer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2FSvAsyncTimer.js)
- [SvBlobPool](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2FSvBlobPool.js)
- [SvBroadcaster](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2FSvBroadcaster.js)
- [SvDataUrl](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FBrowserDragAndDrop%2FSvDataUrl.js)
- [SvErrorCatalog](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Ferrors%2FSvErrorCatalog.js)
- [SvErrorCatalog_auth](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Ferrors%2FSvErrorCatalog_auth.js)
- [SvErrorCatalog_configuration](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Ferrors%2FSvErrorCatalog_configuration.js)
- [SvErrorDefinition](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Ferrors%2FSvErrorDefinition.js)
- [SvErrorImageResolver](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Ferrors%2FSvErrorImageResolver.js)
- [SvgIconCache](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvgIconCache.js)
- [SvI18nCache](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvI18nCache.js)
- [SvI18nStore](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvI18nStore.js)
- [SvNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvNode.js)
- [SvNode_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2FSvNode_store.js)
- [SvTitledNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvTitledNode.js)
- [SvApp](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2FSvApp.js)
- [SvErrorReport](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2FSvErrorReport.js)
- [SvTranslatableNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvTranslatableNode.js)
- [SvInspectableNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvInspectableNode.js)
- [SvViewableNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvViewableNode.js)
- [SvStyledNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvStyledNode.js)
- [SvBaseNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvBaseNode.js)
- [SvActorMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Factor%2FSvActorMessage.js)
- [SvActorMessages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Factor%2FSvActorMessages.js)
- [SvActorNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Factor%2FSvActorNode.js)
- [SvDataStore](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fnodes%2Finspectors%2FSvDataStore.js)
- [SvDayNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Fdate%2FSvDayNode.js)
- [SvFontFamily](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffonts%2FSvFontFamily.js)
- [SvHourNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Ftime%2FSvHourNode.js)
- [SvI18n](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvI18n.js)
- [SvI18nService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvI18nService.js)
- [SvMeridiemNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Ftime%2FSvMeridiemNode.js)
- [SvMinuteNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Ftime%2FSvMinuteNode.js)
- [SvMonthNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Fdate%2FSvMonthNode.js)
- [SvResource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2FSvResource.js)
- [SvFont](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffonts%2FSvFont.js)
- [SvgIconNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ficons%2FSvgIconNode.js)
- [SvImage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fimages%2FSvImage.js)
- [SvImage_evaluator](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FSvImage_evaluator.js)
- [SvJsonResource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fjson%2FSvJsonResource.js)
- [SvURLImage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fimages%2FSvURLImage.js)
- [SvWaSound](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fsounds%2FSvWaSound.js)
- [SvResourceFile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffiles%2FSvResourceFile.js)
- [SvResourceFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffiles%2FSvResourceFolder.js)
- [SvResourceGroup](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2FSvResourceGroup.js)
- [SvFileResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffiles%2FSvFileResources.js)
- [SvFontResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffonts%2FSvFontResources.js)
- [SvIconResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ficons%2FSvIconResources.js)
- [SvImageResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fimages%2FSvImageResources.js)
- [SvJsonResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fjson%2FSvJsonResources.js)
- [SvSoundResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fsounds%2FSvSoundResources.js)
- [SvWaContext](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fsounds%2FSvWaContext.js)
- [SvYearNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Fdate%2FSvYearNode.js)
- [SvStorableNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fnodes%2FSvStorableNode.js)
- [SvAiRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FRequests%2FSvAiRequest.js)
- [SvAnthropicRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAnthropic%2FSvAnthropicRequest.js)
- [SvGeminiRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FSvGeminiRequest.js)
- [SvOpenAiRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FSvOpenAiRequest.js)
- [SvDeepSeekRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FDeepSeek%2FSvDeepSeekRequest.js)
- [SvGroqRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGroq%2FSvGroqRequest.js)
- [SvXaiRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FXai%2FSvXaiRequest.js)
- [SvAzureService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2FSvAzureService.js)
- [SvAzureTtsRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fspeakers%2Frequests%2FSvAzureTtsRequest.js)
- [SvRzPeer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FSvRzPeer.js)
- [SvRzSigServer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FSvRzSigServer.js)
- [SvRzSigServerConn](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FSvRzSigServerConn.js)
- [SvSpatialModelNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpatial%2FSpatialModelsNode.js)
- [SvBlobsNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fblobs%2FSvBlobsNode.js)
- [SvCreatorNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2FSvCreatorNode.js)
- [SvFieldSetNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2FSvFieldSetNode.js)
- [SvDataStoreRecord](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fnodes%2Finspectors%2FSvDataStoreRecord.js)
- [SvI18nEntry](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvI18nEntry.js)
- [SvModel](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2FSvModel.js)
- [SvOptionNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Foptions%2FSvOptionNode.js)
- [SvPrototypesNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvPrototypesNode.js)
- [SvResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2FSvResources.js)
- [SvSummaryNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvSummaryNode.js)
- [SvAiChatModel](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiChatModel.js)
- [SvAiChatModels](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiChatModels.js)
- [SvAiConversations](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiConversations.js)
- [SvAiPromptComposer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FComposer%2FSvAiPromptComposer.js)
- [SvAiService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiService.js)
- [SvAnthropicService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAnthropic%2FSvAnthropicService.js)
- [SvDeepSeekService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FDeepSeek%2FSvDeepSeekService.js)
- [SvGeminiService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FSvGeminiService.js)
- [SvGroqService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGroq%2FSvGroqService.js)
- [SvImagineProService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FSvImagineProService.js)
- [SvLeonardoService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FSvLeonardoService.js)
- [SvOpenAiService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FSvOpenAiService.js)
- [SvXaiService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FXai%2FSvXaiService.js)
- [SvAssistantToolKit](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FSvAssistantToolKit.js)
- [SvAudioQueue](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Faudio%2FSvAudioQueue.js)
- [SvAzureLocale](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Flocales%2FSvAzureLocale.js)
- [SvAzureLocales](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Flocales%2FSvAzureLocales.js)
- [SvAzureSpeaker](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fspeakers%2FSvAzureSpeaker.js)
- [SvAzureSpeakers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fspeakers%2FSvAzureSpeakers.js)
- [SvAzureTtsRequests](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fspeakers%2Frequests%2FSvAzureTtsRequests.js)
- [SvAzureVoice](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fvoices%2FSvAzureVoice.js)
- [SvAzureVoices](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fvoices%2FSvAzureVoices.js)
- [SvEvalChecklistItem](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FChecklist%2FSvEvalChecklistItem.js)
- [SvEvalChecklistItems](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FChecklist%2FSvEvalChecklistItems.js)
- [SvFilesToDownload](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2Ffiles%2FSvFilesToDownload.js)
- [SvFileToDownload](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2Ffiles%2FSvFileToDownload.js)
- [SvFirebaseNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FSvFirebaseNode.js)
- [SvFirebaseFile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FFiles%2FSvFirebaseFile.js)
- [SvFirebaseFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FFolders%2FSvFirebaseFolder.js)
- [SvFirebaseRootFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FFolders%2FSvFirebaseRootFolder.js)
- [SvFirebaseService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FSvFirebaseService.js)
- [SvFirebaseStorageService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FSvFirebaseStorageService.js)
- [SvFirestoreCollections](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FCollections%2FSvFirestoreCollections.js)
- [SvFirestoreDatabaseService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FSvFirestoreDatabaseService.js)
- [SvFirestoreDocuments](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FDocuments%2FSvFirestoreDocuments.js)
- [SvFirestoreNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FSvFirestoreNode.js)
- [SvFirestoreCollection](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FCollections%2FSvFirestoreCollection.js)
- [SvFirestoreDocument](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FDocuments%2FSvFirestoreDocument.js)
- [SvFirestoreQuery](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FSvFirestoreQuery.js)
- [SvFirestoreRoot](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FSvFirestoreRoot.js)
- [SvGeminiImageUpscalings](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FImage%2520Upscaling%2FSvGeminiImageUpscalings.js)
- [SvGeminiVideoPrompt](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FText%2520to%2520Video%2FSvGeminiVideoPrompt.js)
- [SvGeminiVideoPrompts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FText%2520to%2520Video%2FSvGeminiVideoPrompts.js)
- [SvHomeAssistant](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FAssistants%2FSvHomeAssistant.js)
- [SvHomeAssistantFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FSvHomeAssistantFolder.js)
- [SvHomeAssistantGroup](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FSvHomeAssistantGroup.js)
- [SvHomeAssistantAreas](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FAreas%2FSvHomeAssistantAreas.js)
- [SvHomeAssistantDevices](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FDevices%2FSvHomeAssistantDevices.js)
- [SvHomeAssistantEntities](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FEntities%2FSvHomeAssistantEntities.js)
- [SvHomeAssistantStates](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FStates%2FSvHomeAssistantStates.js)
- [SvHomeAssistantObject](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FSvHomeAssistantObject.js)
- [SvHomeAssistantArea](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FAreas%2FSvHomeAssistantArea.js)
- [SvHomeAssistantDevice](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FDevices%2FSvHomeAssistantDevice.js)
- [SvHomeAssistantEntity](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FEntities%2FSvHomeAssistantEntity.js)
- [SvHomeAssistantState](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FStates%2FSvHomeAssistantState.js)
- [SvHomeAssistants](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FAssistants%2FSvHomeAssistants.js)
- [SvImageEvalChecklistMaker](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FSvImageEvalChecklistMaker.js)
- [SvImageEvaluator](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FSvImageEvaluator.js)
- [SvImageEvaluators](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FSvImageEvaluators.js)
- [SvImagineProImageGeneration](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2FSvImagineProImageGeneration.js)
- [SvImagineProImageGenerations](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2FSvImagineProImageGenerations.js)
- [SvImagineProImagePrompt](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2FSvImagineProImagePrompt.js)
- [SvImagineProImageEvalPrompt](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FSvImagineProImageEvalPrompt.js)
- [SvLeonardoImage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FText%2520to%2520Image%2Fimages%2FSvLeonardoImage.js)
- [SvLeonardoImageGeneration](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FText%2520to%2520Image%2FSvLeonardoImageGeneration.js)
- [SvLeonardoImagePrompt](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FText%2520to%2520Image%2FSvLeonardoImagePrompt.js)
- [SvLeonardoImagePrompts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FText%2520to%2520Image%2FSvLeonardoImagePrompts.js)
- [SvLeonardoImages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FText%2520to%2520Image%2Fimages%2FSvLeonardoImages.js)
- [SvLeonardoRefImage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FRefImages%2FSvLeonardoRefImage.js)
- [SvLeonardoRefImages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FRefImages%2FSvLeonardoRefImages.js)
- [SvLeoStyleTransfer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FStyle%2520Transfers%2FSvLeoStyleTransfer.js)
- [SvLeoStyleTransfers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FStyle%2520Transfers%2FSvLeoStyleTransfers.js)
- [SvMusicFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FMusicPlayer%2FSvMusicFolder.js)
- [SvMusicLibrary](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FMusicPlayer%2FSvMusicLibrary.js)
- [SvMusicTrack](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FMusicPlayer%2FSvMusicTrack.js)
- [SvOpenAiImage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Image%2Fimages%2FSvOpenAiImage.js)
- [SvOpenAiImagePrompt](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Image%2FSvOpenAiImagePrompt.js)
- [SvOpenAiImagePrompts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Image%2FSvOpenAiImagePrompts.js)
- [SvOpenAiImages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Image%2Fimages%2FSvOpenAiImages.js)
- [SvOpenAiStyleTransfer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FStyle%2520Transfers%2FSvOpenAiStyleTransfer.js)
- [SvOpenAiStyleTransfers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FStyle%2520Transfers%2FSvOpenAiStyleTransfers.js)
- [SvOpenAiTtsRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Speech%2FSvOpenAiTtsRequest.js)
- [SvOpenAiTtsSession](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Speech%2FSvOpenAiTtsSession.js)
- [SvOpenAiTtsSessions](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Speech%2FSvOpenAiTtsSessions.js)
- [SvPeerService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FSvPeerService.js)
- [SvProxyServer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FProxyServers%2FSvProxyServer.js)
- [SvDefaultProxyServer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FProxyServers%2FSvDefaultProxyServer.js)
- [SvProxyServers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FProxyServers%2FSvProxyServers.js)
- [SvRzMsg](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FRzPeerConns%2FRzMsgs%2FSvRzMsg.js)
- [SvRzMsgs](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FRzPeerConns%2FRzMsgs%2FSvRzMsgs.js)
- [SvRzPeerConn](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FRzPeerConns%2FSvRzPeerConn.js)
- [SvRzPeerConns](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FRzPeerConns%2FSvRzPeerConns.js)
- [SvRzSigServerConns](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FSvRzSigServerConns.js)
- [SvRzSigServerPeers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FSvRzSigServerPeers.js)
- [SvRzSigServers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FSvRzSigServers.js)
- [SvSpeechToTextSession](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpeechToText%2FSvSpeechToTextSession.js)
- [SvSpeechToTextSessions](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpeechToText%2FSvSpeechToTextSessions.js)
- [SvSttMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpeechToText%2FSttMessages%2FSvSttMessage.js)
- [SvSttMessages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpeechToText%2FSttMessages%2FSvSttMessages.js)
- [SvAiImageEditor](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FImageEditor%2FSvAiImageEditor.js)
- [SvGeminiImageEditor](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FImage%2520Editing%2FSvGeminiImageEditor.js)
- [SvGeminiImageScaler](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FImage%2520Upscaling%2FSvGeminiImageScaler.js)
- [SvCoachMarkManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvCoachMarkManager.js)
- [SvCredential](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fcredentials%2FSvCredential.js)
- [SvCredentialManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fcredentials%2FSvCredentialManager.js)
- [SvCredentials](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fcredentials%2FSvCredentials.js)
- [SvDateNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Fdate%2FSvDateNode.js)
- [SvFolderNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvFolderNode.js)
- [SvBreadCrumbsNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fapp%2FSvBreadCrumbsNode.js)
- [SvGeminiImageEditors](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FImage%2520Editing%2FSvGeminiImageEditors.js)
- [SvImageMosaic](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fimage%2FSvImageMosaic.js)
- [SvImageMosaics](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fimage%2FSvImageMosaics.js)
- [SvJsonArchiver](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonArchiver.js)
- [SvJsonIdNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonIdNode.js)
- [SvJsonGroup](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonGroup.js)
- [SvBlobNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fblobs%2FSvBlobNode.js)
- [SvCloudBlobNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fblobs%2FSvCloudBlobNode.js)
- [SvImageNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fimage%2FSvImageNode.js)
- [SvVideoNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fvideo%2FSvVideoNode.js)
- [SvField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2FSvField.js)
- [SvActionField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvActionField.js)
- [SvBooleanField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvBooleanField.js)
- [SvColorField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvColorField.js)
- [SvDateField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvDateField.js)
- [SvIdentityField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvIdentityField.js)
- [SvImageWellField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvImageWellField.js)
- [SvImageField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvImageField.js)
- [SvJsonField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvJsonField.js)
- [SvArrayField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvArrayField.js)
- [SvJsonNullField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2FSvJsonNullField.js)
- [SvNumberField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvNumberField.js)
- [SvOptionsNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Foptions%2FSvOptionsNode.js)
- [SvPointerField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvPointerField.js)
- [SvStampField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvStampField.js)
- [SvStringField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvStringField.js)
- [SvPasswordField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvPasswordField.js)
- [SvTextAreaField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvTextAreaField.js)
- [SvChatInputNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvChatInputNode.js)
- [SvConversationMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvConversationMessage.js)
- [SvAiMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiMessage.js)
- [SvAiResponseMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiResponseMessage.js)
- [SvAiParsedResponseMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FParsing%2FSvAiParsedResponseMessage.js)
- [SvAiParsedResponseMessage_parsing](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FParsing%2FSvAiParsedResponseMessage_parsing.js)
- [SvAiParsedResponseMessage_streaming](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FParsing%2FSvAiParsedResponseMessage_streaming.js)
- [SvAiParsedResponseMessage_tagEvents](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FParsing%2F-unused%2FSvAiParsedResponseMessage_tagEvents.js)
- [SvAiParsedResponseMessage_voiceNarration](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FParsing%2FSvAiParsedResponseMessage_voiceNarration.js)
- [SvUrlField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvUrlField.js)
- [SvVideoWellField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvVideoWellField.js)
- [SvJsonGroup_patches](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2Fpatches%2FSvJsonGroup_patches.js)
- [SvModelReference](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fjson%2FSvModelReference.js)
- [SvSyncableJsonGroup](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvSyncableJsonGroup.js)
- [SvJsonNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonNode.js)
- [SvJsonArrayNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonArrayNode.js)
- [SvConversation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvConversation.js)
- [SvAiConversation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiConversation.js)
- [SvFirebaseFiles](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FFiles%2FSvFirebaseFiles.js)
- [SvFirebaseFolders](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FFolders%2FSvFirebaseFolders.js)
- [SvImagineProImagePrompts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2FSvImagineProImagePrompts.js)
- [SvImagineProImageEvalPrompts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FSvImagineProImageEvalPrompts.js)
- [SvImages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fimages%2FSvImages.js)
- [SvImagesNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fimage%2FSvImagesNode.js)
- [SvJsonArrayNode_patches](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2Fpatches%2FSvJsonArrayNode_patches.js)
- [SvSyncableArrayNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fsyncing%2FSvSyncableArrayNode.js)
- [SvJsonDictionaryNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonDictionaryNode.js)
- [UoJsonDictionaryNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FJson%2FUoJsonDictionaryNode.js)
- [SvJsonPatchRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FJson%2FSvJsonPatchRequest.js)
- [SvToolCall](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FCalls%2FSvToolCall.js)
- [SvToolDefinition](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FDefinitions%2FSvToolDefinition.js)
- [SvToolDefinition_anthropic](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAnthropic%2FSvToolDefinition_anthropic.js)
- [SvLinkNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvLinkNode.js)
- [SvServices](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSvServices.js)
- [SvSyncCollectionSource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fsyncing%2FSvSyncCollectionSource.js)
- [SvCloudSyncSource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fsyncing%2FSvCloudSyncSource.js)
- [SvPublicCloudSource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fsyncing%2FSvPublicCloudSource.js)
- [SvLocalResourceSource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fsyncing%2FSvLocalResourceSource.js)
- [SvTimeNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Ftime%2FSvTimeNode.js)
- [SvWaQueue](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fsounds%2FSvWaQueue.js)
- [SvToolCalls](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FCalls%2FSvToolCalls.js)
- [SvToolDefinitions](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FDefinitions%2FSvToolDefinitions.js)
- [SvToolResult](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FCalls%2FSvToolResult.js)
- [SvTextNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvTextNode.js)
- [SvThemeFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeFolder.js)
- [SvTheme](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvTheme.js)
- [SvDefaultTheme](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvDefaultTheme.js)
- [SvThemeClass](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeClass.js)
- [SvThemeClassChildren](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeClassChildren.js)
- [SvThemeState](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeState.js)
- [SvThemeStates](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeStates.js)
- [SvThemeResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeResources.js)
- [SvUserInterface](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2Fui%2FSvUserInterface.js)
- [SvCliUserInterface](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2Fui%2FSvCliUserInterface.js)
- [SvHeadlessUserInterface](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2Fui%2FSvHeadlessUserInterface.js)
- [SvWebUserInterface](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2Fui%2FSvWebUserInterface.js)
- [SvXhrRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FRequests%2FSvXhrRequest.js)
- [SvYouTubeAudioPlayer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FSvYouTubeAudioPlayer.js)
- [SvYouTubeService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FSvYouTubeService.js)
- [SvNotification](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2Fnotifications%2FSvNotification.js)
- [SvNotificationCenter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2Fnotifications%2FSvNotificationCenter.js)
- [SvObservation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2Fnotifications%2FSvObservation.js)
- [SvStyleSheet](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvStyleSheet.js)
- [SvSyncAction](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2FSvSyncAction.js)
- [SvSyncScheduler](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2FSvSyncScheduler.js)
- [SvTask](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2Ftasks%2FSvTask.js)
- [SvTasks](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2Ftasks%2FSvTasks.js)
- [SvTranslationFilter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvTranslationFilter.js)
- [SvWebBrowserBattery](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebBrowserBattery.js)
- [SvWebBrowserTab](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebBrowserTab.js)
- [SvThrashDetector](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvThrashDetector.js)
- [SvTimeFormatter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fformatters%2FSvTimeFormatter.js)
- [SvTimePeriodFormatter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fformatters%2FSvTimePeriodFormatter.js)
- [SvTransform](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fgeometry%2FSvTransform.js)
- [SvViewAnimator](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FAttributes%2FSvViewAnimator.js)
- [WbCookie](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2Fcookies%2FWbCookie.js)
- [WbCookieManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2Fcookies%2FWbCookieManager.js)
- [SvWebBrowserCookie](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebBrowserCookie.js)
- [SvWebBrowserNotification](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2Fnotifications%2FSvWebBrowserNotification.js)
- [SvWebBrowserNotifications](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2Fnotifications%2FSvWebBrowserNotifications.js)
- [SvWebBrowserScreen](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebBrowserScreen.js)
- [SvWebBrowserWindow](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebBrowserWindow.js)
- [SvWebDocument](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebDocument.js)
- [SvYouTubePlayerFrame](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FSvYouTubePlayerFrame.js)
- [ProtocolAnalyzer](../../resources/class-doc/class_doc.html?path=%2Fdocs%2Fresources%2Fprotocols.js)
- [Range](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FRangeShim.js)
- [Range_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FRange_ideal.js)
- [RegExp_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FRegex_store.js)
- [SvResourceIndexer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Findex-builder%2FSvResourceIndexer.js)
- [SvResourcesFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Findex-builder%2FSvResourcesFolder.js)
- Set
- [SvHookedSet](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcollections%2FSvHookedSet.js)
- [SvImmutableSet](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FSvImmutableSet.js)
- [Set_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FSet_ideal.js)
- [Set_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FSet_store.js)
- [Slot](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2FSlot.js)
- [Slot_promiseWrapper](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2FSlot_promiseWrapper.js)
- [SourceInspector](../../resources/class-doc/class_doc.html?path=%2Fdocs%2Fresources%2FSourceInspector%2FSourceInspector.js)
- [SvStoreRef](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2FSvStoreRef.js)
- String
- [String_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FString_ideal.js)
- [String_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2Fliterals%2FString_store.js)
- [StrvctFile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FStrvctFile.js)
- [StrvctFramework](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fmodule%2FStrvctFramework.js)
- [SvBase](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvBase.js)
- [SvDatabase](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDatabase.js)
- [SvDbCache](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbCache.js)
- [SvDbColumn](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbColumn.js)
- [SvDbDataType](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbDataType.js)
- [SvDbRow](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbRow.js)
- [SvDbCustomRow](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbCustomRow.js)
- [SvDbSchema](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbSchema.js)
- [SvDbTable](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbTable.js)
- [SvDbCustomTable](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbCustomTable.js)
- [SvDbTx](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbTx.js)
- [SvHashCache](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvHashCache.js)
- [SvIndexedDbFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fserver-only%2FSvIndexedDbFolder.js)
- [SvIndexedDbTx](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fserver-only%2FSvIndexedDbTx.js)
- [SvBootLoader](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvBootLoader.js)
- [SvBootLoadingView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvBootLoadingView.js)
- [SvCliBrowser](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fcli%2Fserver-only%2FSvCliBrowser.js)
- [SvGlobals](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FSvGlobals.js)
- [SvMimeTypeDetector](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fmedia%2Fmime%2FSvMimeTypeDetector.js)
- [SvPlatform](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvPlatform.js)
- [SvResourceManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvResourceManager.js)
- [SvServiceWorker](../../resources/class-doc/class_doc.html?path=%2Fsource%2FServiceWorker%2FSvServiceWorker.js)
- [SvUrlResource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvUrlResource.js)
- [SvWindowErrorPanel](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvWindowErrorPanel.js)
- [Symbol_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FSymbol_store.js)
- [TestClass](../../resources/class-doc/class_doc.html?path=%2Fdocs%2Fresources%2FSourceInspector%2Ftest%2FTestClass.js)
- [TestRunner](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fserver-only%2Ftests%2FSvIndexedDbTests.js)
- [Type](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FType.js)
- [URL_promises](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fcategories%2FURL_promises.js)
- [w](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fajv%2Fajv7.js)
- [XMLHttpRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FXMLHttpRequestShim.js)
- [ZJsonValidator](../../resources/class-doc/class_doc.html?path=%2Fexternal-libs%2Fjson%2Fz-schema%2FZJsonValidator.js)
---
Source: /docs/Reference/Modules/
# Modules
Module hierarchy and file organization.
- boot
- [Array_promises](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fcategories%2FArray_promises.js)
- [Object_categorySupport](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fcategories%2FObject_categorySupport.js)
- [Promise_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fcategories%2FPromise_ideal.js)
- [StrvctFile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FStrvctFile.js)
- [SvBootLoadingView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvBootLoadingView.js)
- [SvGlobals](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FSvGlobals.js)
- [SvHashCache](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvHashCache.js)
- [SvIndexedDbFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fserver-only%2FSvIndexedDbFolder.js)
- [SvIndexedDbTx](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fserver-only%2FSvIndexedDbTx.js)
- [SvResourceManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvResourceManager.js)
- [SvUrlResource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvUrlResource.js)
- [URL_promises](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fcategories%2FURL_promises.js)
- boot/server-only
- [SvIndexedDbFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fserver-only%2FSvIndexedDbFolder.js)
- [SvIndexedDbTx](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fserver-only%2FSvIndexedDbTx.js)
- browser
- stack
- Tile
- [SvBreadCrumbsTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvBreadCrumbsTile.js)
- [SvTile_slideGesture](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile_slideGesture.js)
- globals
- [SvAiParsedResponseMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FParsing%2FSvAiParsedResponseMessage.js)
- [SvAiParsedResponseMessage_parsing](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FParsing%2FSvAiParsedResponseMessage_parsing.js)
- [SvAiParsedResponseMessage_streaming](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FParsing%2FSvAiParsedResponseMessage_streaming.js)
- [SvAiParsedResponseMessage_tagEvents](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FParsing%2F-unused%2FSvAiParsedResponseMessage_tagEvents.js)
- [SvAiParsedResponseMessage_voiceNarration](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FParsing%2FSvAiParsedResponseMessage_voiceNarration.js)
- [SvAiPromptComposer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FComposer%2FSvAiPromptComposer.js)
- [SvAnthropicRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAnthropic%2FSvAnthropicRequest.js)
- [ArrayBuffer_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FArrayBuffer_ideal.js)
- [ArrayBuffer_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FArrayBuffer_store.js)
- [Array_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FArray_ideal.js)
- [Array_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FArray_store.js)
- [SvAssistantToolKit](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FSvAssistantToolKit.js)
- [SvAtomicMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmap%2FSvAtomicMap.js)
- [SvAudioQueue](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Faudio%2FSvAudioQueue.js)
- [SvBaseNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvBaseNode.js)
- [SvBasicJsonRepairShop](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fjson%2FSvBasicJsonRepairShop.js)
- [BigInt_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FBigInt_store.js)
- [Boolean_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FBoolean_ideal.js)
- [Boolean_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2Fliterals%2FBoolean_store.js)
- [SvBreadCrumbsNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fapp%2FSvBreadCrumbsNode.js)
- [SvByteFormatter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fformatters%2FSvByteFormatter.js)
- [CliWebServer](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FCliWebServer.js)
- [ContentBase](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentBase.js)
- [ContentCards](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentCards.js)
- [ContentImage](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentImage.js)
- [ContentKeyValue](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentKeyValue.js)
- [ContentOrderedList](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentOrderedList.js)
- [ContentTable](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentTable.js)
- [ContentText](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentText.js)
- [ContentTimeline](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentTimeline.js)
- [ContentToc](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentToc.js)
- [ContentUnorderedList](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FContentUnorderedList.js)
- [Date_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FDate_ideal.js)
- [Date_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FDate_store.js)
- [SvDocumentation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmisc%2FSvDocumentation.js)
- [SvDragSourceProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvDragSourceProtocol.js)
- [SvEnumerableWeakMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fweak%2FSvEnumerableWeakMap.js)
- [SvEnumerableWeakSet](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fweak%2FSvEnumerableWeakSet.js)
- [Error_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FError_ideal.js)
- [Error_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FError_store.js)
- [SvEvalChecklistItems](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FChecklist%2FSvEvalChecklistItems.js)
- [SvFifoMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FSvFifoMap.js)
- [FileReader](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FFileReaderShim.js)
- [SvFileToDownload](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2Ffiles%2FSvFileToDownload.js)
- [SvFilesToDownload](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2Ffiles%2FSvFilesToDownload.js)
- [SvFirewallProxy](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproxies%2FSvFirewallProxy.js)
- [FontFace](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FFontFaceShim.js)
- [SvGeminiVideoPrompt](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FText%2520to%2520Video%2FSvGeminiVideoPrompt.js)
- [HTMLCanvasElement](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FImageShim.js)
- [HTMLElement_textField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2Fbrowser-only%2FHtmlElement_textField.js)
- [SvHeaderTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvHeaderTile.js)
- [SvHookedArray](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcollections%2FSvHookedArray.js)
- [SvHookedMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcollections%2FSvHookedMap.js)
- [SvHookedSet](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcollections%2FSvHookedSet.js)
- [SvHtmlStreamReader](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fhtml%2FHtmlStreamReader%2FSvHtmlStreamReader.js)
- [SvHttpResponseCodes](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fnetworking%2FSvHttpResponseCodes.js)
- [Image](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FImageShim.js)
- [SvImageEvaluators](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FSvImageEvaluators.js)
- [Image_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FImage_ideal.js)
- [Image_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FImage_store.js)
- [ImportsIndexer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Findex-builder%2FImportsIndexer.js)
- [SvIndexedArray](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcollections%2FSvIndexedArray.js)
- [SvInspectableNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvInspectableNode.js)
- [SvJsonObject](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FSvJsonObject.js)
- [SvJsonPatchRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FJson%2FSvJsonPatchRequest.js)
- [SvJsonStreamReader](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fjson%2FJsonStreamReader%2FSvJsonStreamReader.js)
- [Map_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FMap_ideal.js)
- [Map_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FMap_store.js)
- [SvMarkdownRelative](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmarkdown%2FSvMarkdownRelative.js)
- [SvMarkdownToc](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmarkdown%2FSvMarkdownToc.js)
- [MinimalIndexedDbFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fserver-only%2Ftests%2FMinimalLevelDbWrapper.js)
- [SvMissingSlotError](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_copying.js)
- [SvMusicLibrary](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FMusicPlayer%2FSvMusicLibrary.js)
- [SvNamespaceSearch](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmisc%2FSvNamespaceSearch.js)
- [SvNavView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvNavView.js)
- [SvNodeView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvNodeView.js)
- [SvNumberFormatter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fformatters%2FSvNumberFormatter.js)
- [Number_random](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FNumber_random.js)
- [Number_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2Fliterals%2FNumber_store.js)
- [Object_boot](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fcategories%2FObject_boot.js)
- [Object_class](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_class.js)
- [Object_copying](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_copying.js)
- [Object_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_ideal.js)
- [Object_init](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_init.js)
- [Object_mutation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_mutation.js)
- [Object_notification](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_notification.js)
- [Object_puuid](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_puuid.js)
- [Object_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FObject_store.js)
- [Object_timeouts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fobject%2FObject_timeouts.js)
- [SvObservableProxy](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproxies%2FSvObservableProxy.js)
- [PageIndex](../../resources/class-doc/class_doc.html?path=%2Fstyle%2Flayout%2FPageIndex.js)
- [ProtoClass](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2FProtoClass.js)
- [ProtoClass_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2FProtoClass_store.js)
- [ProtoClass_tasks](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2Ftasks%2FProtoClass_tasks.js)
- [Protocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fprotocol%2FProtocol.js)
- [SvProxyServers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FProxyServers%2FSvProxyServers.js)
- [Range](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FRangeShim.js)
- [Range_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FRange_ideal.js)
- [RegExp_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FRegex_store.js)
- [SvResourceIndexer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Findex-builder%2FSvResourceIndexer.js)
- [SvResourcesFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Findex-builder%2FSvResourcesFolder.js)
- [Set_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FSet_ideal.js)
- [Set_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FSet_store.js)
- [SvSimpleSynth](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Faudio%2FSvSimpleSynth.js)
- [Slot_promiseWrapper](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2FSlot_promiseWrapper.js)
- [SvSortedArray](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcollections%2FSvSortedArray.js)
- [SvStackScrollView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvStackScrollView.js)
- [SvStackView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvStackView.js)
- [SvStoreRef](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2FSvStoreRef.js)
- [SvStreamElementNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fhtml%2FHtmlStreamReader%2FSvStreamElementNode.js)
- [SvStreamNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fhtml%2FHtmlStreamReader%2FSvStreamNode.js)
- [SvStreamTextNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fhtml%2FHtmlStreamReader%2FSvStreamTextNode.js)
- [String_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FString_ideal.js)
- [String_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2Fliterals%2FString_store.js)
- [StrvctFramework](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fmodule%2FStrvctFramework.js)
- [SvStyledNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvStyledNode.js)
- [SvSubviewsDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvSubviewsDomView.js)
- [SvActionField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvActionField.js)
- [SvActionFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvActionFieldTile.js)
- [SvActorMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Factor%2FSvActorMessage.js)
- [SvActorMessages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Factor%2FSvActorMessages.js)
- [SvActorNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Factor%2FSvActorNode.js)
- [SvArrayField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvArrayField.js)
- [SvBase](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvBase.js)
- [SvBlobNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fblobs%2FSvBlobNode.js)
- [SvBlobsNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fblobs%2FSvBlobsNode.js)
- [SvBooleanField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvBooleanField.js)
- [SvBooleanFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvBooleanFieldTile.js)
- [SvBootLoader](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvBootLoader.js)
- [SvChatInputTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvChatInputTile.js)
- [SvChatMessageTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvChatMessageTile.js)
- [SvCliBrowser](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fcli%2Fserver-only%2FSvCliBrowser.js)
- [SvCliUserInterface](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2Fui%2FSvCliUserInterface.js)
- [SvCloudBlobNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fblobs%2FSvCloudBlobNode.js)
- [SvColorField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvColorField.js)
- [SvCreatorNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2FSvCreatorNode.js)
- [SvCredential](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fcredentials%2FSvCredential.js)
- [SvCredentialManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fcredentials%2FSvCredentialManager.js)
- [SvCredentials](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fcredentials%2FSvCredentials.js)
- [SvDataStore](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fnodes%2Finspectors%2FSvDataStore.js)
- [SvDataStoreRecord](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fnodes%2Finspectors%2FSvDataStoreRecord.js)
- [SvDateNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Fdate%2FSvDateNode.js)
- [SvDayNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Fdate%2FSvDayNode.js)
- [SvErrorCatalog](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Ferrors%2FSvErrorCatalog.js)
- [SvErrorCatalog_auth](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Ferrors%2FSvErrorCatalog_auth.js)
- [SvErrorCatalog_configuration](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Ferrors%2FSvErrorCatalog_configuration.js)
- [SvErrorDefinition](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Ferrors%2FSvErrorDefinition.js)
- [SvErrorImageResolver](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Ferrors%2FSvErrorImageResolver.js)
- [SvErrorReport](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2FSvErrorReport.js)
- [SvFieldSetNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2FSvFieldSetNode.js)
- [SvFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvFieldTile.js)
- [SvHeadlessUserInterface](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2Fui%2FSvHeadlessUserInterface.js)
- [SvHourNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Ftime%2FSvHourNode.js)
- [SvIdentityField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvIdentityField.js)
- [SvImageField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvImageField.js)
- [SvImageView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvImageView.js)
- [SvImageWellField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvImageWellField.js)
- [SvImageWellFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvImageWellFieldTile.js)
- [SvImage_evaluator](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FSvImage_evaluator.js)
- [SvImages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fimages%2FSvImages.js)
- [SvImagesNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fimage%2FSvImagesNode.js)
- [SvJsonArchiver](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonArchiver.js)
- [SvJsonArrayNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonArrayNode.js)
- [SvJsonArrayNode_patches](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2Fpatches%2FSvJsonArrayNode_patches.js)
- [SvJsonField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvJsonField.js)
- [SvJsonGroup](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonGroup.js)
- [SvJsonNullField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2FSvJsonNullField.js)
- [SvJsonPatchError](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2Fpatches%2FSvJsonPatchError.js)
- [SvLinkNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvLinkNode.js)
- [SvMeridiemNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Ftime%2FSvMeridiemNode.js)
- [SvMinuteNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Ftime%2FSvMinuteNode.js)
- [SvModel](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2FSvModel.js)
- [SvModelReference](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fjson%2FSvModelReference.js)
- [SvNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvNode.js)
- [SvNode_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2FSvNode_store.js)
- [SvOptionNodeTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2Foptions%2FSvOptionNodeTile.js)
- [SvOptionsNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Foptions%2FSvOptionsNode.js)
- [SvOptionsNodeTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2Foptions%2FSvOptionsNodeTile.js)
- [SvPasswordFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvPasswordFieldTile.js)
- [SvPasswordView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvPasswordView.js)
- [SvPlatform](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvPlatform.js)
- [SvPointerField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvPointerField.js)
- [SvPointerFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvPointerFieldTile.js)
- [SvPrototypesNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvPrototypesNode.js)
- [SvServiceWorker](../../resources/class-doc/class_doc.html?path=%2Fsource%2FServiceWorker%2FSvServiceWorker.js)
- [SvStampField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvStampField.js)
- [SvStorableNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fnodes%2FSvStorableNode.js)
- [SvStringFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvStringFieldTile.js)
- [SvSummaryNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvSummaryNode.js)
- [SvTask](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2Ftasks%2FSvTask.js)
- [SvTasks](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2Ftasks%2FSvTasks.js)
- [SvTextAreaField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvTextAreaField.js)
- [SvTextAreaFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvTextAreaFieldTile.js)
- [SvTextNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvTextNode.js)
- [SvTextNodeTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTextNodeTile.js)
- [SvTextView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvTextView.js)
- [SvTimeNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Ftime%2FSvTimeNode.js)
- [SvUrlField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvUrlField.js)
- [SvUserInterface](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2Fui%2FSvUserInterface.js)
- [SvVideoNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fvideo%2FSvVideoNode.js)
- [SvVideoView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvVideoView.js)
- [SvVideoWellField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvVideoWellField.js)
- [SvVideoWellFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Ffield_tiles%2FSvVideoWellFieldTile.js)
- [SvVideoWellView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvVideoWellView.js)
- [SvWaSound](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fsounds%2FSvWaSound.js)
- [SvWebBrowserTab](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebBrowserTab.js)
- [SvWebUserInterface](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2Fui%2FSvWebUserInterface.js)
- [Symbol_store](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2Fcategories%2Fprimitives%2FSymbol_store.js)
- [TestRunner](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2Fserver-only%2Ftests%2FSvIndexedDbTests.js)
- [SvTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile.js)
- [SvTileContainer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvTileContainer.js)
- [SvTileNoteButtonView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Fsubviews%2FSvTileNoteButtonView.js)
- [SvTileNoteView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Fsubviews%2FSvTileNoteView.js)
- [SvTileSubtitleView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Fsubviews%2FSvTileSubtitleView.js)
- [SvTileTitleView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2Fsubviews%2FSvTileTitleView.js)
- [SvTile_dragging](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile_dragging.js)
- [SvTile_keyboard](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile_keyboard.js)
- [SvTile_styling](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile_styling.js)
- [SvTilesView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView.js)
- [SvTilesView_dragViewProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_dragViewProtocol.js)
- [SvTilesView_gestures](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_gestures.js)
- [SvTilesView_helpers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_helpers.js)
- [SvTilesView_keyboard](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_keyboard.js)
- [SvTilesView_orientation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_orientation.js)
- [SvTilesView_selection](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_selection.js)
- [SvTilesView_styling](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvTilesView_styling.js)
- [SvTimeFormatter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fformatters%2FSvTimeFormatter.js)
- [SvTimePeriodFormatter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fformatters%2FSvTimePeriodFormatter.js)
- [SvTitledNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvTitledNode.js)
- [SvTitledTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTitledTile.js)
- [SvToolCall](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FCalls%2FSvToolCall.js)
- [SvToolCalls](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FCalls%2FSvToolCalls.js)
- [SvToolDefinition](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FDefinitions%2FSvToolDefinition.js)
- [SvToolDefinition_anthropic](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAnthropic%2FSvToolDefinition_anthropic.js)
- [SvToolDefinitions](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FDefinitions%2FSvToolDefinitions.js)
- [SvToolResult](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FCalls%2FSvToolResult.js)
- [UoJsonDictionaryNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FTools%2FJson%2FUoJsonDictionaryNode.js)
- [XMLHttpRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2Fserver-only%2FXMLHttpRequestShim.js)
- library
- i18n
- [SvI18n](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvI18n.js)
- [SvI18nCache](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvI18nCache.js)
- [SvI18nEntry](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvI18nEntry.js)
- [SvI18nService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvI18nService.js)
- [SvI18nStore](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvI18nStore.js)
- [SvTranslationFilter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fi18n%2FSvTranslationFilter.js)
- ideal
- [SvImmutableSet](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FSvImmutableSet.js)
- [Number_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FNumber_ideal.js)
- [Type](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FType.js)
- categories
- [Blob_ideal](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FBlob_ideal.js)
- [Mirror](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fcategories%2FMirror.js)
- misc
- [SvStackFrame](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmisc%2FSvStackTrace.js)
- [SvStackTrace](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fmisc%2FSvStackTrace.js)
- proto
- [Slot](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fproto%2FSlot.js)
- protocol
- [ProtoClass_protocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fideal%2Fprotocol%2FProtoClass_protocol.js)
- image
- [SvImageMosaic](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fimage%2FSvImageMosaic.js)
- [SvImageMosaics](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fimage%2FSvImageMosaics.js)
- media
- mime
- [SvMimeTypeDetector](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fmedia%2Fmime%2FSvMimeTypeDetector.js)
- node
- [SvApp](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2FSvApp.js)
- [SvAsyncTimer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fapp%2FSvAsyncTimer.js)
- audio
- [SvAudioClipDelegateProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Faudio%2FSvAudioClipDelegateProtocol.js)
- [SvAudioClipProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Faudio%2FSvAudioClipProtocol.js)
- fields
- [SvField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2FSvField.js)
- json
- [SvJsonDictionaryNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonDictionaryNode.js)
- [SvJsonIdNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonIdNode.js)
- [SvJsonNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvJsonNode.js)
- patches
- [SvJsonGroup_patches](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2Fpatches%2FSvJsonGroup_patches.js)
- subclasses
- [SvDateField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvDateField.js)
- [SvNumberField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvNumberField.js)
- [SvPasswordField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvPasswordField.js)
- [SvStringField](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2FSvStringField.js)
- date
- [SvMonthNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Fdate%2FSvMonthNode.js)
- [SvYearNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Fdate%2FSvYearNode.js)
- options
- [SvOptionNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fsubclasses%2Foptions%2FSvOptionNode.js)
- json
- [SvSyncableJsonGroup](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fjson%2FSvSyncableJsonGroup.js)
- node_views
- [SvCoachableView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvCoachableView.js)
- [SvImageWellView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2FSvImageWellView.js)
- browser
- [SvBrowserView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2FSvBrowserView.js)
- stack
- [SvScrollContentView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvScrollContentView.js)
- [SvScrollView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvScrollView.js)
- [SvScrollToBottomButton](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FSvScrollToBottomButton.js)
- Tile
- [SvTile_gestures](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTile%2FSvTile_gestures.js)
- TilesView
- [SvDragDestinationProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvDragDestinationProtocol.js)
- nodes
- [SvFolderNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvFolderNode.js)
- [SvImageNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Ffields%2Fimage%2FSvImageNode.js)
- base
- [SvTranslatableNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvTranslatableNode.js)
- [SvViewableNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fbase%2FSvViewableNode.js)
- syncing
- [SvCloudSyncSource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fsyncing%2FSvCloudSyncSource.js)
- [SvLocalResourceSource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fsyncing%2FSvLocalResourceSource.js)
- [SvPublicCloudSource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fsyncing%2FSvPublicCloudSource.js)
- [SvSyncCollectionSource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fsyncing%2FSvSyncCollectionSource.js)
- [SvSyncableArrayNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2Fsyncing%2FSvSyncableArrayNode.js)
- storage
- base
- [SvObjectPool](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2FSvObjectPool.js)
- [SvPersistentObjectPool](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2FSvPersistentObjectPool.js)
- [SvSubObjectPool](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2FSvSubObjectPool.js)
- [SvBlobPool](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fstorage%2Fbase%2FSvBlobPool.js)
- SubnodesArray
- [SvSubnodesArray](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2FSvSubnodesArray.js)
- notification
- [SvBroadcaster](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2FSvBroadcaster.js)
- [SvSyncAction](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2FSvSyncAction.js)
- [SvSyncScheduler](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2FSvSyncScheduler.js)
- notifications
- [SvNotification](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2Fnotifications%2FSvNotification.js)
- [SvNotificationCenter](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2Fnotifications%2FSvNotificationCenter.js)
- [SvObservation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnotification%2Fnotifications%2FSvObservation.js)
- resources
- [SvMimeExtensions](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FSvMimeExtensions.js)
- [SvResource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2FSvResource.js)
- [SvResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2FSvResources.js)
- files
- [SvFileResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffiles%2FSvFileResources.js)
- [SvResourceFile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffiles%2FSvResourceFile.js)
- [SvResourceFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffiles%2FSvResourceFolder.js)
- fonts
- [SvFont](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffonts%2FSvFont.js)
- [SvFontFamily](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffonts%2FSvFontFamily.js)
- [SvFontResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffonts%2FSvFontResources.js)
- [SvFontTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ffonts%2FSvFontTile.js)
- icons
- [SvIconResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ficons%2FSvIconResources.js)
- [SvResourceGroup](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2FSvResourceGroup.js)
- [SvgIconNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Ficons%2FSvgIconNode.js)
- images
- [SvImage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fimages%2FSvImage.js)
- [SvImageResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fimages%2FSvImageResources.js)
- [SvImageTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fimages%2FSvImageTile.js)
- [SvURLImage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fimages%2FSvURLImage.js)
- json
- [SvJsonResource](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fjson%2FSvJsonResource.js)
- [SvJsonResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fjson%2FSvJsonResources.js)
- sounds
- [SvSoundResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fsounds%2FSvSoundResources.js)
- [SvWaContext](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fsounds%2FSvWaContext.js)
- [SvWaQueue](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fsounds%2FSvWaQueue.js)
- themes
- [SvDefaultTheme](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvDefaultTheme.js)
- [SvTheme](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvTheme.js)
- [SvThemeClass](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeClass.js)
- [SvThemeClassChildren](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeClassChildren.js)
- [SvThemeFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeFolder.js)
- [SvThemeResources](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeResources.js)
- [SvThemeState](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeState.js)
- [SvThemeStates](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fresources%2Fthemes%2FSvThemeStates.js)
- services
- [SvServices](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSvServices.js)
- AiServiceKit
- [SvAiChatModel](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiChatModel.js)
- [SvAiChatModels](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiChatModels.js)
- [SvAiConversation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiConversation.js)
- [SvAiConversations](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiConversations.js)
- [SvAiMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiMessage.js)
- [SvAiRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FRequests%2FSvAiRequest.js)
- [SvAiResponseMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiResponseMessage.js)
- [SvAiService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvAiService.js)
- [SvChatInputNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvChatInputNode.js)
- [SvConversation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvConversation.js)
- [SvConversationMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FSvConversationMessage.js)
- [SvXhrRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FRequests%2FSvXhrRequest.js)
- ImageEditor
- [SvAiImageEditor](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FImageEditor%2FSvAiImageEditor.js)
- Requests
- errors
- [SvAiRequestOverloadedError](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAiServiceKit%2FRequests%2Ferrors%2FSvAiRequestOverloadedError.js)
- Anthropic
- [SvAnthropicService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAnthropic%2FSvAnthropicService.js)
- Azure
- [SvAzureService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2FSvAzureService.js)
- locales
- [SvAzureLocale](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Flocales%2FSvAzureLocale.js)
- [SvAzureLocales](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Flocales%2FSvAzureLocales.js)
- speakers
- [SvAzureSpeaker](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fspeakers%2FSvAzureSpeaker.js)
- [SvAzureSpeakers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fspeakers%2FSvAzureSpeakers.js)
- requests
- [SvAzureTtsRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fspeakers%2Frequests%2FSvAzureTtsRequest.js)
- [SvAzureTtsRequests](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fspeakers%2Frequests%2FSvAzureTtsRequests.js)
- voices
- [SvAzureVoice](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fvoices%2FSvAzureVoice.js)
- [SvAzureVoices](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FAzure%2Fvoices%2FSvAzureVoices.js)
- DeepSeek
- [SvDeepSeekRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FDeepSeek%2FSvDeepSeekRequest.js)
- [SvDeepSeekService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FDeepSeek%2FSvDeepSeekService.js)
- Firebase
- [SvFirebaseFile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FFiles%2FSvFirebaseFile.js)
- [SvFirebaseFiles](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FFiles%2FSvFirebaseFiles.js)
- [SvFirebaseFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FFolders%2FSvFirebaseFolder.js)
- [SvFirebaseFolders](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FFolders%2FSvFirebaseFolders.js)
- [SvFirebaseNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FSvFirebaseNode.js)
- [SvFirebaseRootFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FFolders%2FSvFirebaseRootFolder.js)
- [SvFirebaseService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FSvFirebaseService.js)
- [SvFirebaseStoragePermissions](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FSvFirebaseStoragePermissions.js)
- [SvFirebaseStorageService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirebaseStorage%2FSvFirebaseStorageService.js)
- [SvFirestoreCollection](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FCollections%2FSvFirestoreCollection.js)
- [SvFirestoreCollections](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FCollections%2FSvFirestoreCollections.js)
- [SvFirestoreDatabaseService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FSvFirestoreDatabaseService.js)
- [SvFirestoreDocument](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FDocuments%2FSvFirestoreDocument.js)
- [SvFirestoreDocuments](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FDocuments%2FSvFirestoreDocuments.js)
- [SvFirestoreNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FSvFirestoreNode.js)
- [SvFirestoreQuery](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FSvFirestoreQuery.js)
- [SvFirestoreRoot](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FFirebase%2FFirestoreDatabase%2FSvFirestoreRoot.js)
- Gemini
- [SvGeminiRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FSvGeminiRequest.js)
- [SvGeminiService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FSvGeminiService.js)
- Image_Editing
- [SvGeminiImageEditor](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FImage%2520Editing%2FSvGeminiImageEditor.js)
- [SvGeminiImageEditors](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FImage%2520Editing%2FSvGeminiImageEditors.js)
- Image_Upscaling
- [SvGeminiImageUpscalings](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FImage%2520Upscaling%2FSvGeminiImageUpscalings.js)
- [SvGeminiImageScaler](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FImage%2520Upscaling%2FSvGeminiImageScaler.js)
- Text_to_Video
- [SvGeminiVideoPrompts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGemini%2FText%2520to%2520Video%2FSvGeminiVideoPrompts.js)
- Groq
- [SvGroqRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGroq%2FSvGroqRequest.js)
- [SvGroqService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FGroq%2FSvGroqService.js)
- HomeAssistant
- [SvHomeAssistantFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FSvHomeAssistantFolder.js)
- [SvHomeAssistantGroup](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FSvHomeAssistantGroup.js)
- [SvHomeAssistantObject](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FSvHomeAssistantObject.js)
- Areas
- [SvHomeAssistantArea](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FAreas%2FSvHomeAssistantArea.js)
- [SvHomeAssistantAreas](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FAreas%2FSvHomeAssistantAreas.js)
- Assistants
- [SvHomeAssistant](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FAssistants%2FSvHomeAssistant.js)
- [SvHomeAssistants](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FAssistants%2FSvHomeAssistants.js)
- Devices
- [SvHomeAssistantDevice](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FDevices%2FSvHomeAssistantDevice.js)
- [SvHomeAssistantDevices](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FDevices%2FSvHomeAssistantDevices.js)
- Entities
- [SvHomeAssistantEntities](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FEntities%2FSvHomeAssistantEntities.js)
- [SvHomeAssistantEntity](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FEntities%2FSvHomeAssistantEntity.js)
- States
- [SvHomeAssistantState](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FStates%2FSvHomeAssistantState.js)
- [SvHomeAssistantStates](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FHomeAssistant%2FStates%2FSvHomeAssistantStates.js)
- ImaginePro
- [SvEvalChecklistItem](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FChecklist%2FSvEvalChecklistItem.js)
- [SvImageEvalChecklistMaker](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FSvImageEvalChecklistMaker.js)
- [SvImageEvaluator](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FImageEvaluator%2FSvImageEvaluator.js)
- [SvImagineProService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FSvImagineProService.js)
- Image_Eval_Prompts
- [SvImagineProImageEvalPrompt](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FSvImagineProImageEvalPrompt.js)
- [SvImagineProImageEvalPrompts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FImage%2520Eval%2520Prompts%2FSvImagineProImageEvalPrompts.js)
- Text_to_Image
- [SvImagineProImageGeneration](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2FSvImagineProImageGeneration.js)
- [SvImagineProImageGenerations](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2FSvImagineProImageGenerations.js)
- [SvImagineProImagePrompt](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2FSvImagineProImagePrompt.js)
- [SvImagineProImagePrompts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FImaginePro%2FText%2520to%2520Image%2FSvImagineProImagePrompts.js)
- Leonardo
- [SvLeonardoService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FSvLeonardoService.js)
- RefImages
- [SvLeoStyleTransfers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FStyle%2520Transfers%2FSvLeoStyleTransfers.js)
- [SvLeonardoRefImage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FRefImages%2FSvLeonardoRefImage.js)
- [SvLeonardoRefImages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FRefImages%2FSvLeonardoRefImages.js)
- StyleTransfers
- [SvLeoStyleTransfer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FStyle%2520Transfers%2FSvLeoStyleTransfer.js)
- Text_to_Image
- [SvLeonardoImageGeneration](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FText%2520to%2520Image%2FSvLeonardoImageGeneration.js)
- [SvLeonardoImagePrompt](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FText%2520to%2520Image%2FSvLeonardoImagePrompt.js)
- [SvLeonardoImagePrompts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FText%2520to%2520Image%2FSvLeonardoImagePrompts.js)
- images
- [SvLeonardoImage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FText%2520to%2520Image%2Fimages%2FSvLeonardoImage.js)
- [SvLeonardoImages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FLeonardo%2FText%2520to%2520Image%2Fimages%2FSvLeonardoImages.js)
- OpenAI
- [SvOpenAiRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FSvOpenAiRequest.js)
- [SvOpenAiService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FSvOpenAiService.js)
- StyleTransfers
- [SvOpenAiStyleTransfer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FStyle%2520Transfers%2FSvOpenAiStyleTransfer.js)
- [SvOpenAiStyleTransfers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FStyle%2520Transfers%2FSvOpenAiStyleTransfers.js)
- Text_to_Image
- [SvOpenAiImagePrompt](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Image%2FSvOpenAiImagePrompt.js)
- [SvOpenAiImagePrompts](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Image%2FSvOpenAiImagePrompts.js)
- images
- [SvOpenAiImage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Image%2Fimages%2FSvOpenAiImage.js)
- [SvOpenAiImages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Image%2Fimages%2FSvOpenAiImages.js)
- Text_to_Speech
- [SvOpenAiTtsRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Speech%2FSvOpenAiTtsRequest.js)
- [SvOpenAiTtsSession](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Speech%2FSvOpenAiTtsSession.js)
- [SvOpenAiTtsSessions](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FOpenAI%2FText%2520to%2520Speech%2FSvOpenAiTtsSessions.js)
- Peer
- [SvPeerService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FSvPeerService.js)
- RzSigServers
- [SvRzPeer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FSvRzPeer.js)
- [SvRzSigServer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FSvRzSigServer.js)
- [SvRzSigServerPeers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FSvRzSigServerPeers.js)
- [SvRzSigServers](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FSvRzSigServers.js)
- RzSigServerConns
- [SvRzSigServerConn](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FSvRzSigServerConn.js)
- [SvRzSigServerConns](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FSvRzSigServerConns.js)
- RzPeerConns
- [SvRzPeerConn](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FRzPeerConns%2FSvRzPeerConn.js)
- [SvRzPeerConns](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FRzPeerConns%2FSvRzPeerConns.js)
- RzMsgs
- [SvRzMsg](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FRzPeerConns%2FRzMsgs%2FSvRzMsg.js)
- [SvRzMsgs](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FPeer%2FRzSigServers%2FRzSigServerConns%2FRzPeerConns%2FRzMsgs%2FSvRzMsgs.js)
- ProxyServers
- [SvDefaultProxyServer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FProxyServers%2FSvDefaultProxyServer.js)
- [SvProxyServer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FProxyServers%2FSvProxyServer.js)
- Spatial
- [SvSceneView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpatial%2FSvSceneView.js)
- [SvSceneViewWellFieldTile](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpatial%2FSvSceneViewWellFieldTile.js)
- [SvSpatialModelNode](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpatial%2FSpatialModelsNode.js)
- SpeechToText
- [SvSpeechToTextSession](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpeechToText%2FSvSpeechToTextSession.js)
- [SvSpeechToTextSessions](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpeechToText%2FSvSpeechToTextSessions.js)
- SttMessages
- [SvSttMessage](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpeechToText%2FSttMessages%2FSvSttMessage.js)
- [SvSttMessages](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FSpeechToText%2FSttMessages%2FSvSttMessages.js)
- Xai
- [SvXaiRequest](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FXai%2FSvXaiRequest.js)
- [SvXaiService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FXai%2FSvXaiService.js)
- YouTube
- [SvYouTubeAudioPlayer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FSvYouTubeAudioPlayer.js)
- [SvYouTubePlayerFrame](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FSvYouTubePlayerFrame.js)
- [SvYouTubeService](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FSvYouTubeService.js)
- MusicPlayer
- [SvMusicFolder](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FMusicPlayer%2FSvMusicFolder.js)
- [SvMusicTrack](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fservices%2FYouTube%2FMusicPlayer%2FSvMusicTrack.js)
- storage
- [SvPersistentAsyncMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fstorage%2FSvPersistentAsyncMap.js)
- [SvPersistentAtomicMap](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fstorage%2FSvPersistentAtomicMap.js)
- view
- dom
- Attributes
- [SvCssAnimation](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FAttributes%2FSvCssAnimation.js)
- [SvDomBorderRadius](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FAttributes%2FSvDomBorderRadius.js)
- [SvDomTransition](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FAttributes%2FSvDomTransition.js)
- [SvDomTransitions](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FAttributes%2FSvDomTransitions.js)
- [SvViewAnimator](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FAttributes%2FSvViewAnimator.js)
- BrowserDragAndDrop
- [SvDataUrl](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FBrowserDragAndDrop%2FSvDataUrl.js)
- DomView
- [SvControlDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvControlDomView.js)
- [SvCssDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvCssDomView.js)
- [SvDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvDomView.js)
- [SvDomView_animations](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvDomView_animations.js)
- [SvDomView_browserDragAndDrop](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvDomView_browserDragAndDrop.js)
- [SvEditableDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvEditableDomView.js)
- [SvElementDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvElementDomView.js)
- [SvFlexDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvFlexDomView.js)
- [SvGesturableDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvGesturableDomView.js)
- [SvListenerDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvListenerDomView.js)
- [SvResponderDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvResponderDomView.js)
- [SvSelectableDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvSelectableDomView.js)
- [SvStyledDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvStyledDomView.js)
- [SvVisibleDomView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2FSvVisibleDomView.js)
- subclasses
- [SvBooleanView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvBooleanView.js)
- [SvButtonView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvButtonView.js)
- [SvCloseButton](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvCloseButton.js)
- [SvDocumentBody](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvDocumentBody.js)
- [SvDragBarView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvDragBarView.js)
- [SvDragView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvDragView.js)
- [SvCoachMarkView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2Fcoachmarks%2FSvCoachMarkView.js)
- [SvOverlayBannerView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvOverlayBannerView.js)
- [SvPanelView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvPanelView.js)
- [SvScrimView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvScrimView.js)
- [SvWindowErrorPanel](../../resources/class-doc/class_doc.html?path=%2Fsource%2Fboot%2FSvWindowErrorPanel.js)
- [SvgIconCache](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvgIconCache.js)
- [SvgIconView](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FDomView%2Fsubclasses%2FSvgIconView.js)
- coachmarks
- [SvCoachMarkManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnodes%2FSvCoachMarkManager.js)
- Helpers
- [SvCssColor](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FHelpers%2FSvCssColor.js)
- [SvDomCssInspector](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FHelpers%2FSvDomCssInspector.js)
- TapeMeasures
- [SvCanvasTextTapeMeasure](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FHelpers%2FTapeMeasures%2FSvCanvasTextTapeMeasure.js)
- [SvDomTextTapeMeasure](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fdom%2FHelpers%2FTapeMeasures%2FSvDomTextTapeMeasure.js)
- events
- devices
- [SvDevice](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvDevice.js)
- [SvDevices](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvDevices.js)
- [SvEventPoint](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvEventPoint.js)
- [SvGamePad](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvGamePad.js)
- [SvGamePadManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvGamePadManager.js)
- [SvKeyboardKey](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvKeyboardKey.js)
- [SvMouse](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvMouse.js)
- [SvKeyboard](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvKeyboard.js)
- [SvTouchScreen](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fdevices%2FSvTouchScreen.js)
- gesturing
- [SvGestureManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2FSvGestureManager.js)
- [SvGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2FSvGestureRecognizer.js)
- gestures
- [SvLongPressGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvLongPressGestureRecognizer.js)
- [SvOrientGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvOrientGestureRecognizer.js)
- [SvPanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvPanGestureRecognizer.js)
- [SvPinchGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvPinchGestureRecognizer.js)
- [SvRotationGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvRotationGestureRecognizer.js)
- [SvSlideGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvSlideGestureRecognizer.js)
- [SvTapGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2FSvTapGestureRecognizer.js)
- edges
- [SvEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2FSvEdgePanGestureRecognizer.js)
- screen
- [SvScreenEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fscreen%2FSvScreenEdgePanGestureRecognizer.js)
- sides
- [SvScreenBottomEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fscreen%2Fsides%2FSvScreenBottomEdgePanGestureRecognizer.js)
- [SvScreenLeftEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fscreen%2Fsides%2FSvScreenLeftEdgePanGestureRecognizer.js)
- [SvScreenRightEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fscreen%2Fsides%2FSvScreenRightEdgePanGestureRecognizer.js)
- [SvScreenTopEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fscreen%2Fsides%2FSvScreenTopEdgePanGestureRecognizer.js)
- view
- [SvBottomEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fview%2FSvBottomEdgePanGestureRecognizer.js)
- [SvLeftEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fview%2FSvLeftEdgePanGestureRecognizer.js)
- [SvRightEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fview%2FSvRightEdgePanGestureRecognizer.js)
- [SvTopEdgePanGestureRecognizer](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Fgesturing%2Fgestures%2Fedges%2Fview%2FSvTopEdgePanGestureRecognizer.js)
- listening
- [SvEventListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2FSvEventListener.js)
- [SvEventManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2FSvEventManager.js)
- [SvEventSetListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2FSvEventSetListener.js)
- listeners
- [SvAnimationListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvAnimationListener.js)
- [SvBatteryListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvBatteryListener.js)
- [SvClipboardListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvClipboardListener.js)
- [SvDocumentListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvDocumentListener.js)
- [SvDragListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvDragListener.js)
- [SvDropListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvDropListener.js)
- [SvFocusListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvFocusListener.js)
- [SvGamePadListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvGamePadListener.js)
- [SvKeyboardListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvKeyboardListener.js)
- [SvMouseListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvMouseListener.js)
- [SvMouseMoveListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvMouseMoveListener.js)
- [SvScrollListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvScrollListener.js)
- [SvSelectListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvSelectListener.js)
- [SvSpeechListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvSpeechListener.js)
- [SvTouchListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvTouchListener.js)
- [SvTouchMoveListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvTouchMoveListener.js)
- [SvTransitionListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvTransitionListener.js)
- [SvWebSocketListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvWebSocketListener.js)
- [SvWheelListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvWheelListener.js)
- [SvWindowListener](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fevents%2Flistening%2Flisteners%2FSvWindowListener.js)
- geometry
- [SvPoint](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fgeometry%2FSvPoint.js)
- [SvRectangle](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fgeometry%2FSvRectangle.js)
- [SvTransform](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fgeometry%2FSvTransform.js)
- webbrowser
- [SvStyleSheet](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvStyleSheet.js)
- [SvWebBrowserBattery](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebBrowserBattery.js)
- [SvThrashDetector](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvThrashDetector.js)
- [WbCookie](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2Fcookies%2FWbCookie.js)
- [WbCookieManager](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2Fcookies%2FWbCookieManager.js)
- [SvWebBrowserCookie](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebBrowserCookie.js)
- [SvWebBrowserNotification](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2Fnotifications%2FSvWebBrowserNotification.js)
- [SvWebBrowserNotifications](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2Fnotifications%2FSvWebBrowserNotifications.js)
- [SvWebBrowserScreen](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebBrowserScreen.js)
- [SvWebBrowserWindow](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebBrowserWindow.js)
- [SvWebDocument](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fview%2Fwebbrowser%2FSvWebDocument.js)
- local-web-server
- [Base](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FBase.js)
- [SvMimeExtensions](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FSvMimeExtensions.js)
- WebServer
- [AcmeChallengeRequest](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2Frequests%2FAcmeChallengeRequest.js)
- [BaseHttpsServer](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FBaseHttpsServer.js)
- [BaseHttpsServerRequest](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2FBaseHttpsServerRequest.js)
- [FileRequest](../../resources/class-doc/class_doc.html?path=%2Fwebserver%2Frequests%2FFileRequest.js)
- webserver/orm
- [SvDatabase](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDatabase.js)
- [SvDbCache](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbCache.js)
- [SvDbColumn](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbColumn.js)
- [SvDbCustomRow](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbCustomRow.js)
- [SvDbCustomTable](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbCustomTable.js)
- [SvDbDataType](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbDataType.js)
- [SvDbRow](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbRow.js)
- [SvDbSchema](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbSchema.js)
- [SvDbTable](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbTable.js)
- [SvDbTx](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Form%2FSvDbTx.js)
---
Source: /docs/Reference/Protocols/
# Protocols
Protocol definitions and implementations.
- library
- node
- audio
- [SvAudioClipDelegateProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Faudio%2FSvAudioClipDelegateProtocol.js)
- [SvAudioClipProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Faudio%2FSvAudioClipProtocol.js)
- node_views
- browser
- stack
- TilesView
- [SvDragDestinationProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvDragDestinationProtocol.js)
- [SvDragSourceProtocol](../../resources/class-doc/class_doc.html?path=%2Fsource%2Flibrary%2Fnode%2Fnode_views%2Fbrowser%2Fstack%2FTilesView%2FSvDragSourceProtocol.js)
---
Source: /docs/Services/
# Services
AI, cloud, media, and IoT service integrations.
## Overview
Services are not part of the Strvct core — they are optional integrations provided as a convenient way to quickly connect with important external services. The `Services` singleton is the root container for all of them. Each service is a standard Strvct node with slots, persistence, and automatic UI — the same patterns used for domain objects apply to service configuration. Users can inspect and configure services (API keys, model selection, proxy settings) through the generated interface without any custom settings UI.
- AI Services
- Cloud Storage
- Media
- Proxies
- Home Assistant
---
Source: /docs/Services/AI%20Services/
# AI Services
Base classes, requests, conversations, tool calling, response parsing, and prompt composition.
## SvAiService
The base class for AI service providers. Each subclass is a singleton representing one provider (Anthropic, OpenAI, Gemini, etc.). Key responsibilities:
- **Authentication** — `apiKeyOrUserAuthToken()` prefers a Firebase bearer token from `SvCredentialManager`, falling back to a stored API key. This allows both direct API access during development and proxied access through Firebase Functions in production.
- **Model registry** — Each service defines a `modelsJson()` method returning its available models with context limits and capability flags (temperature, top-p, image generation, etc.).
- **Request class resolution** — `chatRequestClass()` uses naming convention (`SvGeminiService` resolves to `SvGeminiRequest`) so no explicit registration is needed when adding providers.
## SvAiChatModel
Represents one model offered by a service. Slots include `modelName`, `inputTokenLimit`, `outputTokenLimit`, and capability flags like `supportsTemperature`, `supportsTopP`, and `supportsImageGeneration`. The `Services` node exposes helper methods to query models across all providers: `chatModels()`, `chatModelNames()`, `chatModelWithName()`.
## SvAiRequest
The base HTTP request wrapper for API calls. Manages streaming responses via a delegate protocol:
- `onRequestBegin` / `onRequestComplete` / `onRequestError`
- `onStreamStart` / `onStreamData` / `onStreamEnd`
Each AI service has a paired request subclass (e.g. `SvAnthropicRequest`, `SvGeminiRequest`) that handles provider-specific message formatting, headers, and response parsing. This is the only class that needs to know about the provider's wire format.
## Conversations and Messages
`SvAiConversation` extends a generic `SvConversation` base class, adding AI-specific state: the selected chat model, token tracking, response message class, and tool call management. `SvAiMessage` extends `SvConversationMessage` with role support (system, user, assistant), where role names are mapped to each provider's conventions by the service.
## Tool Calling
The `SvAssistantToolKit` coordinates structured function calling between AI models and application code:
- **`SvToolDefinitions`** — A registry of available tools, each defined with a name, description, typed parameters, and return types.
- **`SvToolCalls`** — A queue of pending and completed invocations from the AI.
- **Execution timing** — Tools can run during streaming (real-time effects like sound), after response completion (state changes), or during narration playback (synchronized audio effects).
Tools are defined on model objects using the slot/method system:
```javascript
const tool = this.methodNamed("rollDice");
tool.setDescription("Roll dice for a check");
tool.addParameter("notation", "String", "Dice notation like 2d6+3");
tool.setIsToolable(true);
```
The AI invokes tools via structured tags in its response. Results are collected and — for non-silent tools — sent back to the AI in a follow-up message.
## Response Parsing
`SvAiParsedResponseMessage` handles structured tag extraction from AI responses. Tags like ``, and `` are parsed incrementally during streaming, enabling real-time processing before the full response arrives. A voice narration category routes speakable content to the TTS pipeline as it's parsed. ## Prompt Composition `SvAiPromptComposer` assembles prompts from modular template files using three substitution patterns: - `{{file$FileName.txt}}` — Include the contents of another file (recursive) - `{{$methodName}}` — Call a method on the target object and insert the result - `{{$tableOfContents}}` — Auto-generate a table of contents from headings This allows complex system prompts to be built from reusable, domain-specific components without string concatenation in code. ## Providers Each AI provider is implemented as a service/request pair. The service defines available models and authentication; the request handles the provider's specific API format. | Service | Provider | Key Capabilities | |---|---|---| | `SvAnthropicService` | Anthropic | Claude models, tool calling with Anthropic-specific schema | | `SvGeminiService` | Google | Gemini models, text-to-video generation | | `SvOpenAiService` | OpenAI | GPT models, DALL-E image generation, text-to-speech, style transfer | | `SvImagineProService` | ImaginePro | Midjourney image generation via API | | `SvGroqService` | Groq | Fast inference with OpenAI-compatible API | | `SvDeepSeekService` | DeepSeek | Code-focused models | | `SvXaiService` | xAI | Grok models with OpenAI-compatible API | ## Adding a New AI Provider Adding a provider requires two classes and one registration: 1. **`NewProviderService`** extending `SvAiService` — define `modelsJson()` with available models, set the endpoint URL, and configure role name mappings if they differ from the defaults. 2. **`NewProviderRequest`** extending `SvAiRequest` — implement `buildBody()` for the provider's message format and `readDataChunk()` for streaming response parsing. 3. **Register** the service as a slot in `Services.initPrototypeSlots()`. The naming convention (`NewProviderService` resolves to `NewProviderRequest`) handles the wiring automatically. If the provider uses an OpenAI-compatible API, the request class can be minimal. --- Source: /docs/Services/Cloud%20Storage/ # Cloud Storage Firebase integration for cloud persistence and file storage. ## SvFirebaseService Integrates with Firebase for cloud persistence and file storage. Unlike AI services, `SvFirebaseService` extends `SvSummaryNode` directly and contains two sub-services: - **`SvFirestoreDatabaseService`** — Document and collection access via Firestore. Provides query building, real-time listeners, and CRUD operations through Strvct node wrappers (`SvFirestoreNode`, `SvFirestoreQuery`). - **`SvFirebaseStorageService`** — File upload and download via Firebase Storage, with permission management. --- Source: /docs/Services/Home%20Assistant/ # Home Assistant IoT device control via Home Assistant's WebSocket API. ## Overview The Home Assistant integration maps an entire Home Assistant instance — areas, devices, entities, and states — into the Strvct node graph. The result is a navigable, inspectable tree of your smart home that uses the same UI patterns as the rest of the framework. No custom views are involved; the generated interface lets you browse areas, drill into devices, see entity states, and inspect raw JSON from HA — all from slot annotations. Multiple Home Assistant instances are supported. Each connection is configured with a host, port, and long-lived access token, all editable through the generated inspector. ## Connection Communication uses the Home Assistant WebSocket API. Because browsers disallow plain `ws://` connections from HTTPS pages, a small WSS-to-WS proxy relays traffic between the browser and HA's local WebSocket endpoint. ### Authentication Flow 1. Browser opens a secure WebSocket connection to the proxy 2. HA sends `auth_required` 3. Client responds with the stored long-lived access token 4. HA replies `auth_ok` or `auth_invalid` 5. On success, a full data refresh begins All subsequent requests use a sequential integer ID with a promise-based response pattern — each outgoing message gets a unique ID, and incoming results are matched to their pending promise by that ID. ## Data Model After authentication, the integration fetches four registries in parallel: | Group | HA WebSocket Command | Node Class | |---|---|---| | Areas | `config/area_registry/list` | `SvHomeAssistantArea` | | SvDevices | `config/device_registry/list` | `SvHomeAssistantDevice` | | Entities | `config/entity_registry/list` | `SvHomeAssistantEntity` | | States | `get_states` | `SvHomeAssistantState` | Each registry response is an array of JSON objects. For each entry, a corresponding Strvct node is created and registered in an ID map for O(1) lookup. ### Object Wiring After all four registries are loaded, a wiring pass connects objects into a hierarchy based on their foreign keys: - **SvDevices** attach to **Areas** via `area_id` - **Entities** attach to **SvDevices** via `device_id` - **States** attach to **Entities** via `entity_id` The result is a tree rooted at a `SvHomeAssistantFolder` node (titled "regions") that mirrors the physical layout of the home: ``` Home Assistant └── regions ├── Living Room (area) │ └── HomePod (device) │ └── volume (entity) │ └── standby (state) ├── Kitchen (area) │ └── ... └── ... ``` ### Display Names Each object computes a short display name by stripping its parent's name as a prefix. For example, a device named "Living Room Speaker" under the "Living Room" area displays as "Speaker". This keeps the tree compact without losing context. ## Class Hierarchy ``` SvHomeAssistants — Collection of HA connections └── SvHomeAssistant — One connection instance ├── rootFolder — Navigable UI tree (regions) ├── SvHomeAssistantAreas ─┐ ├── SvHomeAssistantDevices │ Data groups (hidden, ├── SvHomeAssistantEntities │ used for ID lookup) └── SvHomeAssistantStates ─┘ SvHomeAssistantGroup — Base for the four registry groups ├── SvHomeAssistantAreas ├── SvHomeAssistantDevices ├── SvHomeAssistantEntities └── SvHomeAssistantStates SvHomeAssistantObject — Base for individual HA items ├── SvHomeAssistantArea ├── SvHomeAssistantDevice ├── SvHomeAssistantEntity └── SvHomeAssistantState ``` The four data group nodes (`areasNode`, `devicesNode`, `entitiesNode`, `statesNode`) are hidden from the UI — they exist for ID-based lookup during the wiring pass. The visible navigation tree is the `rootFolder`, which is populated with area nodes after all data is loaded and wired. --- Source: /docs/Services/Media/ # Media YouTube audio playback and browser speech recognition. ## SvYouTubeService Manages YouTube-based audio playback via the IFrame Player API. The service contains a `SvYouTubeAudioPlayer` subnode that wraps a hidden YouTube player element. ### SvYouTubeAudioPlayer The core playback class. Handles player lifecycle, volume, looping, and state tracking. The YouTube IFrame API script is loaded lazily on first use, and playback waits for a user gesture (browser autoplay policy). ```javascript // Create a player and loop background music const player = SvYouTubeAudioPlayer.clone(); player.setTrackName("Ambient Forest"); player.setVideoId("abc123xyz"); player.setShouldRepeat(true); player.setVolume(0.1); player.play(); // Control player.stop(); player.togglePlay(); player.isPlaying(); // => boolean player.stateName(); // => "playing" | "paused" | "buffering" | "ended" // One-shot playback (resolves when video ends) player.setShouldRepeat(false); await player.play(); // Cleanup await player.shutdown(); // destroys the YT.Player and removes the DOM element ``` ### SvMusicLibrary A higher-level layer that manages playlists of `SvMusicTrack` nodes loaded from a JSON resource file. Owns two `SvYouTubeAudioPlayer` instances — one for background music (low volume), one for sound effects (higher volume). ```javascript // Play looping background music by track name library.playTrackWithName("Mystical Forest"); // Play a one-shot sound effect await library.playSoundEffectWithName("Sword Clash"); // Stop background music library.musicPlayer().stop(); // Lookup library.trackWithName("Battle Theme"); // => SvMusicTrack library.playlists(); // => SvMusicFolder[] library.trackNames(); // => String[] ``` Playlist data is a JSON object mapping folder names to track dictionaries: ```json { "Fantasy": { "Mystical Forest": "YouTubeVideoId1", "Battle Theme": "YouTubeVideoId2" }, "Sound FX": { "Sword Clash": "YouTubeVideoId3" } } ``` ### SvMusicTrack Represents a single track with a YouTube video ID. Supports a delegate set for playback notifications: ```javascript track.addDelegate(myObserver); await track.play(); track.stop(); ``` Delegates receive `onSoundStarted(track)` and `onSoundEnded(track)`. ## SvSpeechToTextSessions Wraps the browser's native `SpeechRecognition` API for voice input. Each `SvSpeechToTextSession` tracks recognition state, language settings, and transcription results. Not a cloud service — all processing happens in the browser. ### SvSpeechToTextSession ```javascript const session = SvSpeechToTextSession.clone(); session.setDelegate(myObject); session.setLanguage("en-US"); session.setIsContinuous(true); session.setGetInterimResults(true); session.setInputTimeoutMs(1500); // Start — returns a promise that resolves with the transcript // when the input timeout fires (silence detected after speech) const text = await session.start(); // Manual stop session.stop(); // State session.isRecording(); session.fullTranscript(); // accumulated text session.interimTranscript(); // current partial text ``` ### Delegate Protocol All methods are optional. The session is passed as the first argument. | Method | When | |---|---| | `onSpeechInterimResult(session)` | Partial result received | | `onSpeechFinal(session)` | Finalized segment received, appended to `fullTranscript` | | `onSpeechEnd(session)` | Browser speech recognition ended | | `onSpeechInput(session)` | Input timeout elapsed — transcript is final | | `onSessionEnd(session)` | Recognition service disconnected | | `onSpeechError(session, error)` | Recognition error | ### Usage in SvTextView Any text field supports voice input via Alt+L. Holding the key starts a session; releasing it stops recognition and inserts the transcript at the cursor: ```javascript startSpeechToText () { this._speechSession = SvSpeechToTextSession.clone().setDelegate(this); this._speechSession.start(); } onSpeechEnd (speechSession) { const s = speechSession.fullTranscript(); this.insertTextAtCursorSimple(s); this._speechSession = null; } ``` --- Source: /docs/Services/Proxies/ # Proxies Client-side proxy configuration for routing API calls through intermediary servers. ## Overview These classes do not run proxy servers — they are client-side configuration nodes that store proxy server connection details and rewrite API URLs to route through a proxy. The actual proxy server (e.g. a Firebase Function or local HTTPS reverse proxy) runs separately. The primary use case is routing AI service API calls through a proxy that holds the real API keys, so that browser clients never see provider credentials directly. The client sends a Firebase user auth token to the proxy, and the proxy adds the appropriate API key before forwarding the request. ## SvProxyServers `SvProxyServers` is a singleton collection of `SvProxyServer` entries, accessible via `SvProxyServers.shared()`. In practice, a single `SvDefaultProxyServer` entry handles all routing, accessible via `SvProxyServers.shared().defaultServer()`. Users can add, remove, and reorder proxy entries through the generated inspector UI. All entries are persisted to IndexedDB. ## SvProxyServer Each `SvProxyServer` node stores the connection details for one proxy endpoint: | Slot | Type | Default | Purpose | |---|---|---|---| | `isSecure` | Boolean | `true` | Use `https` or `http` | | `subdomain` | String | `""` | Optional subdomain prefix | | `domain` | String | `""` | Base domain (e.g. `localhost`, `example.com`) | | `port` | Number | `0` | Port number (0 or null omits port from URL) | | `path` | String | `""` | URL path (e.g. `/proxy`) | | `parameterName` | String | `null` | Query parameter name for the target URL | | `isDisabled` | Boolean | `false` | When true, returns target URLs unchanged | All configuration slots are persisted and editable through the generated inspector. ### URL Rewriting The core method is `proxyUrlForUrl(targetUrl)`, which rewrites a direct API URL into a proxied one: ``` Target: https://api.openai.com/v1/chat/completions Proxied: https://localhost:8443/proxy?proxyUrl=https%3A%2F%2Fapi.openai.com%2Fv1%2Fchat%2Fcompletions ``` The target URL is passed as a query parameter (named by `parameterName`), so the proxy server can decode it, forward the request to the real provider, and stream the response back. If `isDisabled` is true, the target URL is returned unchanged — useful for direct API access during development. ## SvDefaultProxyServer `SvDefaultProxyServer` extends `SvProxyServer` and auto-configures itself from the browser's current page URL on startup. For a page served at `https://localhost:8443`, it defaults to: - `isSecure`: `true` - `hostname`: `localhost` - `port`: `8443` - `path`: `/proxy` - `parameterName`: `"proxyUrl"` This means the proxy is assumed to run on the same origin as the application by default. Applications can override these settings programmatically via `setupForConfigDict()` using build-time environment configuration. ## Integration with AI Services `SvAiRequest` has a `needsProxy` slot (default `true`). When making an API call, the request checks this flag and rewrites the URL if needed: ```javascript async activeApiUrl () { let url = this.apiUrl(); // e.g. "https://api.openai.com/v1/chat/completions" if (this.needsProxy()) { url = SvProxyServers.shared().defaultServer().proxyUrlForUrl(url); } return url; } ``` This applies to all AI service requests (chat, image generation, text-to-speech, video generation) and also to image/media downloads that would otherwise be blocked by CORS in production. --- Source: /docs/Slots/ # Slots The property system: declaration, annotations, and the most common slot settings. ## Overview Slots are STRVCT's property system. A property declared as a slot is more than a value holder — it carries metadata that each framework layer (UI, storage, validation, JSON schema) reads independently. That metadata is what lets the framework auto-generate forms, persist state, sync views, and produce JSON schemas without per-property glue code. Two things often surprise newcomers: the auto-generated setter **type-checks values at runtime** against the declared slot type (warning and attempting recovery on mismatch), and slots can hold **weak references** via `newWeakSlot`, which is the standard way to express back-references and non-owning pointers without creating retain cycles. Both are covered in detail below. ## Declaration Slots are declared in a class's `initPrototypeSlots()` method. Each declaration creates a private instance variable (`_slotName`), an auto-generated getter (`slotName()`), and an auto-generated setter (`setSlotName(value)`). ```javascript initPrototypeSlots () { { const slot = this.newSlot("userName", ""); slot.setSlotType("String"); slot.setShouldStoreSlot(true); slot.setSyncsToView(true); slot.setCanEditInspection(true); } } ``` The block-scope pattern (`{ const slot = ... }`) is a convention that keeps each slot's configuration visually grouped and avoids name collisions across slots in the same method. ### Constructors - `newSlot(name, initialValue)` — the standard constructor. - `newWeakSlot(name, initialValue)` — creates a slot that holds a `WeakRef` to its value. The auto-generated getter unwraps the ref; the auto-generated setter wraps it. Useful for back-references (child → parent) and caches where you don't want to prevent garbage collection. - `newSubnodeFieldSlot(name, ProtoClass)` — convenience for subnode-field slots (see below). Available on `SvJsonGroup` and descendants. - `overrideSlot(name, initialValue)` — overrides a slot inherited from a parent class, preserving its configuration while changing the default value. ### Auto-generated getters A plain getter returns the private ivar directly, but the framework first calls an optional `willGetSlotSlotName()` hook on the owning object if one is defined. This is the mechanism behind on-demand initialization for specific slots without having to subclass the setter. For **weak slots**, the getter dereferences the underlying `WeakRef` transparently. If the target has been garbage-collected, the getter returns `undefined`. ### Auto-generated setters The setter generated for a typed slot validates the incoming value against `slotType()`. If the value doesn't match, the setter logs a warning and attempts to recover — converting `Number` → `String` or `String` → `Number` where possible, falling back to the slot's initial value otherwise. Validation is on by default (`validatesOnSet` defaults to `true`); disable it with `slot.setValidatesOnSet(false)` when you need to store runtime values that intentionally don't match the declared type. Setters also post a `didUpdateSlot` notification when the value changes, which is what drives view synchronization, persistence, and observers. ## Core annotations ### Type ```javascript slot.setSlotType("String"); ``` The type name is a string — either a primitive name (`"String"`, `"Number"`, `"Boolean"`, `"Map"`, `"Set"`, `"Array"`) or a class name (`"UoCharacter"`, `"SvNode"`). The framework uses this for: - **Runtime validation** — the auto-generated setter rejects values of the wrong type. - **UI generation** — the inspector picks an appropriate field widget (text input, number stepper, toggle, etc.). - **JSON schema export** — translated to the corresponding JSON Schema type. - **Persistence** — native collections (`Array`, `Map`, `Set`, `Object`, `ArrayBuffer`, `TypedArray`) are serialized automatically based on their declared type. Type annotation is recommended for every slot. Debug builds assert that every prototype slot has a declared type. ### Persistence ```javascript slot.setShouldStoreSlot(true); ``` Marks the slot as part of the object's persistence record. The object's class must also opt in via `setShouldStore(true)` in `initPrototype()`. When a stored slot changes, its owning object is added to the dirty set and committed at the end of the event loop. - `setShouldJsonArchive(true)` — include the slot when the object is exported to JSON (separate from internal persistence format). - `setIsInJsonSchema(true)` — include the slot in generated JSON schemas. Use for slots that should appear to AI assistants and external schema consumers. - `setIsInCloudJson(true)` — include the slot when the object is serialized for cloud sync. ### View synchronization ```javascript slot.setSyncsToView(true); ``` When the slot's value changes, schedule the owning node's view to re-sync. The sync scheduler batches and deduplicates updates, so multiple slot changes in the same event loop produce a single view refresh. ### Inspector and editing ```javascript slot.setCanEditInspection(true); ``` Exposes the slot as an editable field in the auto-generated inspector. Related annotations: - `setLabel("Display Name")` — override the auto-humanized label. - `setLabelToCapitalizedSlotName()` — use the capitalized slot name as the label. - `setDescription("Explanatory text")` — inspector hint text and JSON schema description. - `setValuePlaceholder("Type your name")` — placeholder text for empty string fields. - `setIsReadOnly(true)` — show the value but disable editing. - `setIsRequired(true)` — mark as required for validation and schema export. ### Auto-initialization ```javascript slot.setFinalInitProto(SettingsNode); ``` During `finalInit()`, if the slot's value is still its initial value (usually `null`), the framework creates a new instance of the given class and assigns it. This runs after storage-loaded values are populated, so `setFinalInitProto` doesn't overwrite loaded objects — it only fills in missing children. Use for nested sub-structures that should always exist. ### Validation ```javascript slot.setValidValues(["small", "medium", "large"]); ``` - `setValidValues(array)` — restrict the value to one of the listed options. Produces a popup/dropdown in the inspector and a JSON Schema `enum`. - `setValidItems(itemsArray)` — like `validValues` but for dictionary items (each item has a label and a value). - `setJsonSchemaPattern(regex)` — string pattern constraint for schema validation. ## Subnode-related annotations STRVCT has two distinct ways of exposing child objects in the UI. Choosing between them is one of the most important slot-design decisions. ### Stored subnodes ```javascript slot.setIsSubnode(true); ``` The slot's value is treated as a persistent child node in the parent's `subnodes` array. The framework manages the parent/child relationship automatically — setting `ownerNode`, inserting into `subnodes`, and handling removal on clear. This is the right choice when the child has independent identity and lifecycle (a user-authored item in a list). Most commonly used implicitly, through `SvJsonArrayNode`-style collections where each element is a subnode. ### Subnode fields ```javascript slot.setIsSubnodeField(true); ``` The slot's value is still stored in the slot itself (not in the subnodes array), but the inspector presents it as a navigable tile. Clicking drills into the child object. The field is ephemeral UI structure; the data lives in the slot. Use this for structured but always-present children (a `SettingsObject` that's part of every instance of the parent, or a `Stats` sub-record). The parent typically sets `shouldStoreSubnodes(false)` because the real data is in the slots, not the subnodes array. `newSubnodeFieldSlot(name, ProtoClass)` is a convenience that applies the common settings together: ```javascript const slot = this.newSubnodeFieldSlot("settings", SettingsObject); // equivalent to: newSlot + setFinalInitProto + setIsSubnodeField // + setShouldStoreSlot(true) + setShouldJsonArchive(true) ``` ### Quick comparison | | Subnode (`setIsSubnode`) | Subnode field (`setIsSubnodeField`) | |-------------------------|--------------------------------------|-------------------------------------| | Data location | Owner's `subnodes` array | The slot itself | | Typical use | Collections of user-authored items | Structured sub-records | | Parent config | `shouldStoreSubnodes(true)` | `shouldStoreSubnodes(false)` | | Identity | Independent lifecycle | Always present as part of parent | ## Weak slots ```javascript const slot = this.newWeakSlot("parentRef", null); // or: slot.setIsWeak(true); ``` A weak slot holds a `WeakRef` instead of a direct reference. The getter transparently dereferences; if the target has been collected, the getter returns `null` (or `undefined`). Use cases: - **Back-references** (`childNode.parentRef()` → parent) where a strong ref would create a cycle that keeps nodes alive after their containing tree is released. - **Caches and observation targets** where you want the reference to disappear automatically when the target is no longer used elsewhere. Weak slots participate in the framework's `FinalizationRegistry`-based cleanup: when the referenced object is collected, `onFinalizedSlot()` is called on the owning object. ## Common recipes Quick-reference for the most frequent slot configurations. These compose freely — a slot can be stored, view-synced, JSON-visible, and cloud-synced all at once. ### Stored property with view sync ```javascript { const slot = this.newSlot("hitPoints", 0); slot.setSlotType("Number"); slot.setShouldStoreSlot(true); slot.setSyncsToView(true); slot.setCanEditInspection(true); } ``` ### Transient (non-stored) property Runtime-only state that resets on reload. Not persisted, not shown in the inspector. ```javascript { const slot = this.newSlot("isLoading", false); slot.setSlotType("Boolean"); } ``` ### Read-only display A computed or system-managed value shown in the inspector but not editable. ```javascript { const slot = this.newSlot("createdAt", null); slot.setSlotType("String"); slot.setShouldStoreSlot(true); slot.setCanEditInspection(true); slot.setIsReadOnly(true); } ``` ### JSON-visible property A slot included in JSON serialization for AI consumption or data exchange, with a schema description. ```javascript { const slot = this.newSlot("characterClass", "Fighter"); slot.setSlotType("String"); slot.setShouldStoreSlot(true); slot.setIsInJsonSchema(true); slot.setShouldJsonArchive(true); slot.setDescription("The character's class (e.g., Fighter, Wizard, Rogue)"); } ``` ### Cloud-synced property A slot included when the object is serialized for cloud storage. ```javascript { const slot = this.newSlot("lastModified", null); slot.setSlotType("Number"); slot.setShouldStoreSlot(true); slot.setIsInCloudJson(true); } ``` ### Collection (stored subnodes) A variable-length list of child objects. Each child is a subnode with independent identity. ```javascript // In initPrototypeSlots(): { const slot = this.newSlot("subnodes", null); slot.setShouldStoreSlot(true); } // In initPrototype(): this.setShouldStoreSubnodes(true); this.setSubnodeClasses([ItemNode]); // accepted child types ``` Classes extending `SvJsonArrayNode` get this behavior by default. ## Full reference The `Slot` class lives in `source/library/ideal/proto/Slot.js` and defines many more settings than are covered here — most application code will only use the ones above. Additional categories include: - **Layout hints** — `setNodeFillsRemainingWidth`, `setKeyIsVisible`, `setValueWhiteSpace`, `setValueAllowsHtml`. - **JSON schema refinement** — `setJsonSchema`, `setJsonSchemaItemsType`, `setJsonSchemaItemsRef`, `setJsonSchemaItemsDescription`, `setJsonSchemaItemsIsUnique`, `setExamples`. - **Lifecycle / metadata** — `setAnnotation`, `setDuplicateOp`. For the complete list, read `Slot.js` directly — the file is heavily commented and organized by category. --- Source: /docs/Technical%20Overview/ # Technical Overview High-level architecture and key concepts of the Strvct framework. ## Introduction Strvct applications run as client-side single-page apps in the browser. The framework makes heavy use of client-side persistent storage — both for caching code and resources via a content-addressable build system, and for maintaining a persistent object database of application state in IndexedDB. Subgraphs of this object database can be transparently and lazily synced to the cloud, allowing offline-first operation with seamless cloud persistence. Strvct is not a template system, a compile-time UI generator, or a component framework in the React/Flutter sense. There is no build step that produces views, no static component tree, and no pre-rendered layout. Views are created lazily at runtime as the user navigates the object graph — each navigation step inspects the target node's annotations, discovers an appropriate view class, and instantiates it. Once created, a view stays live and in sync with its model node through bidirectional notifications. The UI at any moment is a dynamic projection of the user's current navigation path, not a pre-built artifact. This page covers the key concepts: the domain model, storage, UI synchronization, and the capabilities these enable. For the design rationale, see [Naked Objects](../Naked%20Objects/index.html). For implementation details, see the [Implementation Overview](../Implementation%20Overview/index.html). ## Domain Model The domain model is a cyclic graph of domain objects. Each domain object has: - **Properties** (instance variables) and **actions** (methods) - a `subnodes` property containing an ordered unique collection of child domain objects - a `parentNode` property pointing to its parent domain object - property **annotations** [1] which allow for the automatic handling of UI and storage mechanisms - `title` and `subtitle` properties - a unique ID The domain model can be seen as an ownership tree of domain objects, which may also contain non-ownership links between nodes. ### Collection Managers Complex collections of domain objects use Collection Manager domain objects to encapsulate collection-specific logic and data. For example, a Server class might have a guestConnections property referencing a GuestConnections instance whose subnodes are GuestConnection instances. ### Indirect UI Coupling The domain model operates independently of UI, allowing for "headless" execution. It can, however, use annotations to provide optional UI hints without direct coupling. This is possible because model objects hold no references to UI objects and can only communicate with them via notifications. ## Storage ### Annotations Domain objects have a property which determines whether the object is persisted, as well as property annotations which determine which properties are persisted. Using this information, the system automatically manages persistence. ### Transactions Mutations on persistent properties auto-queue domain objects for storage. Queued objects are bundled into a transaction committed at the end of the current event loop. ### Garbage Collection Automatic garbage collection of the stored object graph occurs on startup, or when requested. Only objects reachable from the root domain object remain after garbage collection. ### Native Collections Native JavaScript collections (Array, ArrayBuffer, Map, Object, Set, and TypedArray) referenced by persistent properties of domain objects are also automatically persisted in their own records. ### Local Storage Persistent domain objects are stored client side in IndexedDB in a single Object Store of records whose keys are the domain object unique ID and values are the domain objects' JSON records. ## Resource Delivery A naked objects application leans on having the full domain model present in the client. Real apps built this way run to hundreds of classes, plus view code, icons, and style resources. Standard JavaScript delivery mechanisms don't scale gracefully to that operating point: - Loading ES modules individually issues one request per file; cold starts degrade linearly with class count. - Bundlers collapse many files into one, but any change to any file invalidates the entire chunk. Code splitting helps but requires manual chunking and still invalidates per chunk. - HTTP caches key on URL. Because deployments change URLs — via versioned filenames or query strings — clients re-download bytes they already have. - None of the above deduplicates identical code that appears at different paths. STRVCT replaces this with a content-addressable build. Every resource is keyed by the SHA-256 hash of its content. The build produces a small manifest and a bundle indexed by hash. At runtime: - The manifest is fetched first and checked against a persistent client-side hash cache. - Any content already in the cache — from a previous load, a previous deployment, or a different STRVCT app on the same origin — is not re-fetched. - When enough content is missing to justify it, the app downloads the whole bundle in one request; when only a little is missing, it fetches those items directly. The threshold adapts to the actual delta. - Identical content at different paths is stored and transferred once. The practical behavior this produces is qualitatively different from what npm plus a bundler can deliver. A redeploy that changes a single file costs roughly that file's bytes, not a chunk's. A returning user after a year of development cycles fetches only content that is actually new. A first-time visitor who has used any other STRVCT app gets the shared framework for free. None of these properties are reachable by configuration on top of the mainstream stack; they require content-level identity, which URL-based caching doesn't have. This is what lets STRVCT keep its "usability gap" closed at the data-model scales it targets, where conventional tooling begins to impose latency and cache-invalidation costs that the framework's design intentionally eliminates. ## UI Synchronization Model-view synchronization is managed by views, which either pull or push changes to the domain objects they are presenting. Views push changes when a view property changes, and pull changes from domain objects when those objects post change notifications. Only annotated properties trigger sync operations. Both directions are coalesced and sent at the end of the event loop. ### Sync Loop Avoidance Bidirectional sync stops automatically as property changes trigger sync operations only when values actually differ, preventing infinite loops. If secondary changes do occur, the notification system detects the loop, halts it, and identifies the source. ### Reference Loop Avoidance Observations use weak references, allowing garbage collection of both posters and listeners. The Notification system automatically removes observations when the listener is collected. ## Capabilities The naked objects pattern enables several capabilities that would require significant per-component effort in a bespoke-view framework. ### Themes Themes can be used to customize the appearance of the UI. Domain objects can also request object-specific styles to be applied to them. ### Importing and Exporting Drag and drop of domain objects into the UI and out of it for export is supported. Domain objects can register which MIME types they can be exported to and imported from. For example, a domain object can be dragged out of one browser window onto a user's desktop, or dropped into another Strvct app that accepts that MIME type. Domain objects have a standard property which lists valid subnode types, and this can be used to validate drops and auto-generate subnodes for imported data. ### Internationalization Because the framework controls the model-to-view pipeline, it can intercept slot values at the view boundary and translate them transparently — no per-string wrapping required. This centralization also makes AI-powered translation viable. The framework can automatically discover every translatable string in the application by walking the model, and include semantic context with each string to improve translation quality. See the [Internationalization](../Internationalization/index.html) guide for details. ### JSON Schema Domain objects can automatically generate JSON Schema for themselves based on their properties and annotations. These schemas can be used to export metadata about the domain model, which is particularly useful when interacting with Large Language Models. [1]: https://bluishcoder.co.nz/self/transporter.pdf "David Ungar. (OOPSLA 1995). Annotating Objects for Transport to Other Worlds. In Proceedings of the Tenth Annual Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA '95). Austin, TX, USA. ACM Press." --- Source: /docs/Views/ # Views The view layer: auto-generated UI, custom views, and programmatic styling. The entire view system is built from a small number of composable elements: a node, a tile, a column, and a master-detail split. These four pieces nest recursively — a column of tiles where selecting a tile opens another column — so the same structure that displays a flat list also handles arbitrarily deep, mixed-orientation navigation without any additional wiring. The view hierarchy wraps DOM elements rather than extending them. This is deliberate: the DOM API is large and mutable, and subclassing it tightly couples framework code to browser internals that change across engines and versions. Wrapping keeps the boundary clean — each layer in the class chain adds exactly one capability (visibility, event listening, gestures, layout, styling), so any layer can be understood, tested, or replaced independently. - Auto-Generated Views - Custom Views - Programmatic Styling - Themes and Style States --- Source: /docs/Views/Auto-Generated%20Views/ # Auto-Generated Views How the view layer connects to model nodes, synchronizes state, and provides navigation — without writing any view code. ## Overview The defining feature of a naked objects framework is that the UI is derived from the model. In STRVCT, every node automatically gets a visual representation: the framework discovers the right view class, creates instances, wires up observation, and keeps the view synchronized as the model changes. Application developers define model classes and get a fully navigable, editable UI for free. ## SvDomView Hierarchy Rather than subclassing DOM elements directly, STRVCT wraps them. Each layer in the view class hierarchy adds one capability: - **`SvElementDomView`** — Wraps a DOM element. Manages creation, type, and class attributes. - **`SvVisibleDomView`** — Visibility toggling. - **`SvResponderDomView`** — Responder chain for keyboard and mouse event routing. - **`SvListenerDomView`** — Event listener registration and removal. - **`SvControlDomView`** — Target/action pattern for connecting views to handlers. - **`SvSelectableDomView`** — Selection state with styled feedback. - **`SvEditableDomView`** — Content editability and edit mode. - **`SvGesturableDomView`** — Gesture recognizers: tap, double-tap, pan, long-press, pinch. - **`SvFlexDomView`** — Flexbox layout: direction, wrap, grow, shrink, basis, alignment. - **`SvStyledDomView`** — Named style states (unselected, selected, active, disabled) with theme support. - **`SvSubviewsDomView`** — Parent/child view hierarchy. - **`SvCssDomView`** — CSS variable application from dictionaries. - **`SvDomView`** — Combines all layers above. - **`SvNodeView`** — Adds model-to-view synchronization. The primary class for application views. ## SvNodeView `SvNodeView` is the bridge between model nodes and the DOM. It holds a reference to an `SvNode`, observes change notifications, and manages the subview lifecycle. - `setNode(aNode)` — Assigns a node and begins observation via `SvNotificationCenter`. - `syncFromNode()` — Diffs visible subnodes against current subviews: creates, reuses, or removes as needed. - `subviewProtoForSubnode(aSubnode)` — Resolves which view class to use (see View Resolution). - `syncCssFromNode()` — Applies CSS variables defined on the node to the DOM element. ## View Resolution The framework discovers view classes by naming convention: append `"View"` or `"SvTile"` to the node's class name. 1. Check for an explicit `nodeViewClassName` override on the node. 2. Walk the node's class hierarchy from most-derived to base. 3. For each ancestor, look up `ClassName + "View"`. 4. Return the first match. For a `MySpecialNode` extending `SvStorableNode`, the lookup tries `MySpecialNodeView`, then `SvStorableNodeView`, and so on. No registration required — just name the view class to match. ## Synchronization `SvSyncScheduler` batches and coordinates all synchronization between nodes and views. **Model to view**: A slot change triggers `didUpdateSlot()` on the node, which posts an `onUpdatedNode` notification. Observing views schedule a sync at priority 2, executed at the end of the event loop. **View to model**: A user edit triggers `scheduleSyncToNode()` at priority 0 (higher than model-to-view). The view calls the node's setter, which posts its own change notification, completing the cycle. The scheduler coalesces duplicate calls, detects sync loops, and can be paused during bulk operations. Slot setters only fire hooks when the value actually changes, preventing redundant cascades at the source. ## Navigation ### SvStackView `SvStackView` is the single recursive building block of all navigation. It splits into two regions: - **`SvNavView`** (master) — A column with a header, a scrollable `SvTilesView`, and a footer. - **`otherView`** (detail) — The content of the selected item — typically another `SvStackView`. Selecting a tile creates a new `SvStackView` in the detail area for the selected node's subnodes. This is the entire navigation mechanism: the same master-detail split, repeated at every level. **Orientation** is set per node — `"right"` for horizontal (master left, detail right) or `"down"` for vertical (master top, detail below). Mixing orientations at different depths produces horizontal Miller Columns, vertical drill-down, or hybrids, all from the same structure. **Compaction**: When nested columns would exceed the viewport, upper columns collapse automatically. Navigating back re-expands them. Tiles along the selection path are highlighted; the focused tile gets a distinct highlight. ### SvBrowserView `SvBrowserView` is the top-level container — a `SvStackView` whose detail area contains another `SvStackView`, whose detail area contains another, to any depth. It adds a breadcrumb header that auto-compacts on narrow viewports, replacing truncated segments with a back arrow. - `navigateToNode(aNode)` — Navigate directly to a node. - `selectNodePathArray(pathArray)` — Set the navigation path programmatically. ## SvTilesView `SvTilesView` is the scrollable column that displays one `SvTile` per visible subnode. It handles selection, keyboard navigation (arrow keys, Enter, Escape), long-press reordering, pinch gestures, and drag-and-drop between columns. Layout direction follows the parent `SvStackView`. ## Tiles Tiles are the items in a navigation column. All extend `SvNodeView`. **`SvTile`** — The base class. Provides selection feedback, slide-to-delete (an inner `contentView` slides to reveal action buttons beneath), long-press reorder, and a style cascade that checks the node, then the tile, then the parent column. **`SvTitledTile`** — The default. Displays title, subtitle, and note from `SvSummaryNode`. **`SvHeaderTile`** — A non-selectable section header. **`SvBreadCrumbsTile`** — A breadcrumb path that auto-compacts to fit. ## Field Tiles Field tiles present individual slot values as editable key/value rows. The base `SvFieldTile` has four regions: key, value, error, and note. | Class | Purpose | |-------|---------| | `SvStringFieldTile` | Single-line text input | | `SvTextAreaFieldTile` | Multi-line text editing | | `SvBooleanFieldTile` | Checkbox toggle | | `SvPasswordFieldTile` | Masked password input | | `SvActionFieldTile` | Button that invokes a node method | | `SvPointerFieldTile` | Object reference with navigation arrow | | `SvImageWellFieldTile` | Image display and drag in/out | | `SvVideoWellFieldTile` | Video display and drag in/out | Not every field type needs its own tile — `SvNumberField` uses the string tile with numeric validation. --- Source: /docs/Views/Custom%20Views/ # Custom Views How to create custom view classes when the auto-generated UI doesn't fit. ## When to Create a Custom View The auto-generated view system handles the common case: a node's slots and subnodes produce tiles, field editors, and navigation automatically. Custom views are for situations where you need a specific layout, non-standard DOM elements, or visual behavior that doesn't map to the tile-based pattern — overlays, canvas-based rendering, media players, or composite displays. ## The Basic Pattern A custom view extends `SvDomView` (or one of its ancestors) and configures itself in `init()`: ```javascript (class MyOverlayView extends SvDomView { init () { super.init(); this.setPosition("fixed"); this.setTop("0"); this.setLeft("0"); this.setWidth("100vw"); this.setHeight("100vh"); this.makeFlexAndCenterContent(); this.setBackgroundColor("rgba(0, 0, 0, 0.5)"); this.setZIndex(9999); return this; } }.initThisClass()); ``` All styling uses named property methods — there are no CSS files to manage. Every setter returns `this`, so calls chain naturally. See the Programmatic Styling page for the full API. ## Creating Child Views Child views are created with `clone()` (not `new`) and added with `addSubview()`: ```javascript init () { super.init(); this.makeFlexAndCenterContent(); const label = SvDomView.clone(); label.setInnerHTML("Hello"); label.setColor("white"); label.setFontSize("24px"); this.addSubview(label); return this; } ``` `clone()` runs the full initialization lifecycle (`init()` then `finalInit()` then `afterInit()`). Use `addSubview()` to establish the parent/child relationship — it handles both the framework's view tree and the underlying DOM. ## Connecting to a Node To make a custom view respond to model changes, extend `SvNodeView` instead of `SvDomView` and implement `syncFromNode()`: ```javascript (class MyStatusView extends SvNodeView { init () { super.init(); this._label = SvDomView.clone(); this.addSubview(this._label); return this; } syncFromNode () { super.syncFromNode(); const node = this.node(); if (node) { this._label.setInnerHTML(node.statusText()); } } }.initThisClass()); ``` `syncFromNode()` is called automatically whenever the observed node posts a change notification. The sync scheduler batches these calls so multiple rapid changes produce a single update. ## View Resolution for Custom Views The framework finds views by naming convention: for a node class `MyWidget`, it looks for `MyWidgetView`. To use a custom view for a node type, just name the class to match: - `UoCharacter` uses `UoCharacterView` (if it exists) - `UoSession` uses `UoSessionView` - Falls back to ancestor class names if no exact match You can also override on the node side with `nodeViewClassName()` to point at a different view class. ## Convenience Methods `SvFlexDomView` provides shortcuts for common layout patterns: | Method | Effect | |--------|--------| | `makeFlexAndCenterContent()` | Sets display flex, centers both axes | | `flexCenterContent()` | Centers content horizontally and vertically | | `makeStandardFlexView()` | Flex display, relative positioning, centered, overflow hidden | | `fillParentView()` | Sets width and height to 100% | | `newFlexSubview()` | Creates and adds a flex child with min dimensions set | These eliminate the most common multi-property patterns and keep `init()` methods concise. --- Source: /docs/Views/Programmatic%20Styling/ # Programmatic Styling Named CSS methods, the chainable API, and why STRVCT avoids CSS files. ## Why No CSS Files? ### The cascade is additive The CSS cascade is designed for documents: you declare rules, the browser resolves conflicts by specificity and source order, and the result is static. You can mutate individual rules through the CSSOM, but the cascade itself is additive — removing a rule doesn't restore a known-good state, it just lets some other rule win, potentially one you didn't intend. This makes the cascade unreliable for UI components whose appearance changes frequently at runtime. ### State combinatorics The deeper problem is combinatorial. Consider the independent states a single view might have: editable or read-only, selected or unselected, highlighted or not, showing an error, previously navigated, disabled. Five boolean states produce 32 combinations, and each combination may need distinct styling. In a stylesheet, each combination requires its own selector or class chain — and the count doubles with every new state. You can try to treat each state independently (`.selected` sets some properties, `.error` sets others), but that only works when the states don't interact visually. When "selected + error" needs to look different from the sum of "selected" and "error" applied separately, you're back to enumerating combinations. ### Theming compounds the problem CSS custom properties can swap values at runtime, but they don't help with the structural problem of *which properties to set in which state combinations*. When a user customizes a theme, or different regions of the UI use different themes simultaneously, every state combination now has a theme axis too. The custom properties handle the value lookup, but the combinatorial selector structure they plug into still has to be authored and maintained by hand. ### The programmatic alternative Programmatic styling sidesteps all of this. Each state applies its visual changes directly to the element, and the results compose naturally — enabling "selected" and "error" at the same time just means both sets of property changes are applied, with explicit logic for cases where they interact. Themes are dictionaries of values that can be swapped or scoped to any subtree at any time — no cascade resolution, just direct assignment. The styling logic lives alongside the view logic that drives it, so the two can't drift apart. ## Named Property Methods Every view inherits named setter/getter pairs for standard CSS properties. These are the primary styling API: ```javascript this.setBackgroundColor("rgba(0, 0, 0, 0.5)"); this.setPosition("fixed"); this.setDisplay("flex"); this.setZIndex(9999); this.setTop("0"); this.setLeft("0"); this.setWidth("100vw"); this.setHeight("100vh"); this.setFontSize("14px"); this.setColor("white"); this.setBorderRadius("8px"); this.setOverflow("hidden"); this.setPadding("16px"); this.setBoxShadow("0 2px 8px rgba(0,0,0,0.15)"); ``` Every setter returns `this`, so calls chain naturally. Each property also has a corresponding getter (e.g. `backgroundColor()`, `fontSize()`). ## Flexbox Methods `SvFlexDomView` adds named methods for every flexbox property: ```javascript this.setDisplay("flex"); this.setFlexDirection("column"); this.setJustifyContent("center"); this.setAlignItems("stretch"); this.setFlexWrap("wrap"); this.setFlexGrow(1); this.setFlexShrink(0); this.setFlexBasis("auto"); this.setGap("8px"); ``` ## Layout Convenience Methods `SvFlexDomView` also provides higher-level shortcuts for common multi-property patterns: | Method | Effect | |--------|--------| | `makeFlexAndCenterContent()` | Sets display flex, centers both axes | | `flexCenterContent()` | Centers content horizontally and vertically | | `makeStandardFlexView()` | Flex display, relative positioning, centered, overflow hidden | | `fillParentView()` | Sets width and height to 100% | | `newFlexSubview()` | Creates and adds a flex child with min dimensions set | ## Sizing Shortcuts Convenience methods for constrained sizing: | Method | Effect | |--------|--------| | `setMinAndMaxWidth(v)` | Sets min-width, max-width, and width to the same value | | `setMinAndMaxHeight(v)` | Sets min-height, max-height, and height to the same value | | `setMinAndMaxWidthAndHeight(v)` | Sets all six sizing properties at once | These are useful for fixed-size elements like icons or thumbnails where you want all constraints to agree. ## Node-Driven CSS Nodes can also request CSS properties that get applied to their view automatically. A node implements `cssVariableDict()` to return a dictionary of CSS key/value pairs: ```javascript cssVariableDict () { return { "color": this.isActive() ? "white" : "gray", "--accent-color": this.themeColor() }; } ``` During the normal sync cycle, `SvNodeView.syncCssFromNode()` picks up this dictionary and applies it to the view's DOM element. This lets model logic influence presentation without the node needing any reference to its view — the node declares what it wants, and the view system handles the rest. In general, prefer keeping styling in the view layer. Node-driven CSS is available for cases where the model genuinely determines a visual property (e.g. a user-chosen color or a status-dependent highlight), but most styling belongs in views or themes, not in model code. ## Low-Level Access For unusual CSS properties that don't have a named method, `SvCssDomView` provides generic accessors: | Method | Description | |--------|-------------| | `setCssProperty(key, value)` | Sets any CSS property by name | | `getCssProperty(key)` | Gets the computed value | | `removeCssProperty(key)` | Removes a property | These should be rare in practice — the named methods cover the vast majority of styling needs. --- Source: /docs/Views/Themes%20and%20Style%20States/ # Themes and Style States How views resolve their appearance from theme classes, style states, and node configuration. ## Overview Every view has a visual state — selected, active, disabled, or the default unselected. A theme defines what each state looks like for each kind of view. The view asks the theme "what should I look like right now?", applies the answer, and re-asks whenever its state changes. This indirection means swapping a theme changes the appearance of the entire UI without touching any view code, and different subtrees can use different themes simultaneously. ## Style States `SvStyledDomView` tracks three independent boolean properties: `isSelected`, `isActive`, and `isDisabled`. These combine into a single resolved state name with a fixed priority: 1. **disabled** — checked first, takes precedence over all others 2. **active** — the view is the current focus of interaction 3. **selected** — the view has been chosen but isn't the active focus 4. **unselected** — the default when none of the above apply When any of these properties change, the view re-resolves its state and re-applies the corresponding styles from the current theme. ## Theme Architecture The theme system is a hierarchy of named objects: - **`SvThemeResources`** — Singleton that holds the active theme. - **`SvTheme`** — A complete theme containing a set of theme classes. - **`SvThemeClass`** — Defines style values for a particular kind of view (e.g. "SvTile", "TextTile", "Header"). Theme classes form a hierarchy — a class inherits from its parent, so "TextTile" inherits defaults from "SvTile" and only overrides what differs. - **`SvThemeState`** — One state within a theme class (e.g. "selected" within "SvTile"). Contains concrete style values: color, backgroundColor, fontSize, padding, border, and dozens more. ## How a View Resolves Its Style When a view needs to apply its current style: 1. The view reads its `themeClassName` (set on the node via `SvStyledNode`, or inherited from the parent view). 2. It asks the active theme for the `SvThemeClass` matching that name. 3. It determines its current state name (`disabled`, `active`, `selected`, or `unselected`). 4. It retrieves the `SvThemeState` for that state from the theme class. 5. The theme state applies its values to the view via named setter methods (`setColor()`, `setBackgroundColor()`, etc.). Style values resolve up the theme class hierarchy — if "TextTile" doesn't define a `backgroundColor` for its "selected" state, the lookup walks up to "SvTile" and uses its value. ## Node-Side Configuration Nodes control which theme class their view uses through the `themeClassName` slot on `SvStyledNode`. This slot is marked `syncsToView`, so changing it triggers a re-style automatically. The node doesn't know anything about the visual details — it just names the class, and the theme provides the rest. ## Locked Attributes Views can lock individual style attributes via `lockedStyleAttributeSet()`. Locked attributes are skipped when a theme state applies its values, allowing a view to override specific properties that the theme would otherwise control. This is useful for views that need a fixed value regardless of state — for example, a view that must always have a transparent background. ## Switching Themes Because all style values flow through the theme, switching the active theme on `SvThemeResources` and calling `resyncAllViews()` re-styles every view in the hierarchy. No individual view needs to be updated manually. Different regions of the UI can also use different theme class names, so a single theme can provide distinct appearances for different areas (e.g. a sidebar vs. a content panel) without any special-case logic. --- Source: /Example%20App/ # Example App A complete contacts application in four classes, with zero view code. ## Overview This walkthrough builds a working contacts app from scratch to show how the pieces of STRVCT fit together. The app lets you create contacts with name, email, phone, and notes fields — all editable, navigable, and persisted to IndexedDB automatically. The entire application is four small classes and a few configuration files. ## The Model ### Contact A single contact with four fields. Each slot is annotated for storage and editing: ```javascript (class Contact extends SvStorableNode { static jsonSchemaDescription () { return "A person's contact information"; } initPrototypeSlots () { { const slot = this.newSlot("name", ""); slot.setSlotType("String"); slot.setShouldStoreSlot(true); slot.setCanEditInspection(true); slot.setLabel("Name"); } { const slot = this.newSlot("email", ""); slot.setSlotType("String"); slot.setShouldStoreSlot(true); slot.setCanEditInspection(true); slot.setLabel("Email"); } { const slot = this.newSlot("phone", ""); slot.setSlotType("String"); slot.setShouldStoreSlot(true); slot.setCanEditInspection(true); slot.setLabel("Phone"); } { const slot = this.newSlot("notes", ""); slot.setSlotType("String"); slot.setShouldStoreSlot(true); slot.setCanEditInspection(true); slot.setLabel("Notes"); } } initPrototype () { this.setShouldStore(true); this.setNodeCanEditTitle(true); this.setTitle("New Contact"); this.setNodeCanInspect(true); } // The tile in the contact list shows the name as title and email as subtitle title () { return this.name() || "New Contact"; } subtitle () { return this.email(); } }.initThisClass()); ``` That's the entire Contact class. The framework reads the slot annotations and generates: - An editable tile in the contacts list (showing `title()` and `subtitle()`) - An inspector view with labeled fields for each slot when you select it - Automatic persistence to IndexedDB whenever any field changes - Change notifications that keep the tile in sync with the field values ### Contacts A collection that holds Contact items: ```javascript (class Contacts extends SvJsonArrayNode { initPrototype () { this.setTitle("Contacts"); this.setSubnodeClasses([Contact]); this.setShouldStore(true); this.setShouldStoreSubnodes(true); this.setNodeCanAddSubnode(true); this.setNodeCanReorderSubnodes(true); } }.initThisClass()); ``` `setSubnodeClasses([Contact])` tells the framework what kind of objects this collection holds. `setNodeCanAddSubnode(true)` adds an "add" action to the UI. `setShouldStoreSubnodes(true)` persists the list and its contents. New contacts are created by tapping the add button — no handler code needed. ## The App ### ContactsModel The root model node. This is the top of the object hierarchy that becomes the navigation tree: ```javascript (class ContactsModel extends SvStorableNode { initPrototypeSlots () { { const slot = this.newSlot("contacts", null); slot.setFinalInitProto(Contacts); slot.setIsSubnode(true); } } initPrototype () { this.setShouldStore(true); this.setShouldStoreSubnodes(true); this.setTitle("Contacts App"); } }.initThisClass()); ``` `setFinalInitProto(Contacts)` tells the framework to create a `Contacts` instance during initialization — but only if one wasn't already loaded from storage. This is the key mechanism that makes the three-phase lifecycle work: on first run, the `Contacts` node is created fresh; on subsequent loads, it's restored from IndexedDB with all its data intact. `setIsSubnode(true)` places it in the navigation hierarchy. ### ContactsApp The application class — just declares which model and UI to use: ```javascript (class ContactsApp extends SvApp { initPrototypeSlots () { { const slot = this.overrideSlot("model"); slot.setSlotType("ContactsModel"); } } initPrototype () { this.setName("Contacts"); } }.initThisClass()); ``` That's the entire app class. `overrideSlot("model")` tells the base `SvApp` to use `ContactsModel` as the root. The framework handles everything else: opening the store, creating or loading the model, setting up the UI, and wiring synchronization. ## Project Files ### _imports.json The import manifest tells the build system which files to include: ```json [ "Contact.js", "Contacts.js", "ContactsModel.js", "ContactsApp.js" ] ``` A root-level `_imports.json` would reference the framework and this app folder: ```json [ "strvct/_imports.json", "app/_imports.json" ] ``` ### app.html The HTML entry point loads the boot loader: ```html Contacts ``` ### Build Run the indexer to generate the content-addressable resource bundle: ```bash node ./strvct/source/boot/index-builder/ImportsIndexer.js ``` This produces `_index.json` (metadata) and `_cam.json.zip` (compressed bundle). Serve the directory with any static file server and open `app.html`. ## What You Get From these four classes, the framework generates: - A navigable list of contacts with add and reorder support - Editable inspector fields for each contact's properties - Persistent storage — close the browser, reopen, data is still there - Bidirectional sync — edit a field, the tile title updates; changes batch efficiently - Keyboard navigation, breadcrumbs, and responsive column compaction - Slide-to-delete on contacts No view classes were written. No event handlers. No storage code. No routing. The domain model is the application. ## Adding Cloud Sync Assuming you have a Firebase project with Storage enabled, making the contacts collection sync to the cloud is a two-line change. Replace the base class and add a folder name: ```javascript (class Contacts extends SvSyncableArrayNode { initPrototype () { this.setTitle("Contacts"); this.setSubnodeClasses([Contact]); this.setShouldStore(true); this.setShouldStoreSubnodes(true); this.setNodeCanAddSubnode(true); this.setNodeCanReorderSubnodes(true); } cloudFolderName () { return "contacts"; } }.initThisClass()); ``` `SvSyncableArrayNode` extends `SvJsonArrayNode` with cloud sync capabilities. The `cloudFolderName()` method tells the framework where to store this collection's data in Firebase Storage. Everything else — delta tracking, manifest management, retry with backoff, and session locking — is inherited automatically. The collection syncs when the app saves, and loads from the cloud on the next login. --- Source: /FAQ/ # FAQ Frequently asked questions about STRVCT. ## What is the naked objects pattern? The idea that the domain model should be the user interface. Instead of writing separate view code for every screen, you annotate model classes with metadata (which properties are editable, which should persist, how they relate to each other) and the framework generates a complete, navigable UI from those annotations. The pattern was proposed by Richard Pawson in his 2004 PhD thesis. STRVCT's contribution is a set of composable UI primitives — tiles, tile stacks, and nested master-detail views — that make the generated interfaces feel like hand-crafted ones. ## Do I have to use the generated UI? No. The auto-generated views cover the common case, but you can override any node's view by creating a custom view class that follows the naming convention (e.g., `MyNodeView` for `MyNode`). In practice, most applications need very few custom views — undreamedof.ai has ~90 domain classes and fewer than 10 custom views, all for inherently graphical things like 3D dice, maps, and chat. ## Does it use npm or standard ES modules? No. The choice is load-bearing rather than stylistic. **Caching at scale:** For the kind of app STRVCT targets — hundreds of model classes running client-side, long-lived installs, data that stays resident across sessions — mainstream JavaScript tooling delivers a noticeably poor experience. Loading ES modules individually makes cold starts slow once you have a few hundred files. Bundlers solve the request count but invalidate the whole chunk on any change, and browser caches key on URL rather than content, so each deployment makes clients re-download bytes they already have. Code-splitting and cache-busting configurations narrow but don't close that gap. STRVCT uses a content-addressable build instead: resources are keyed by the SHA-256 hash of their content, so unchanged code is never re-downloaded — even across deployments, and even when the same code appears at different paths. You declare dependencies in `_imports.json` files, and the build tools produce a small manifest plus a hash-indexed bundle. The tradeoff is that standard import/export syntax isn't used within the framework, and npm packages can't be used directly. A handful of third-party libraries (pako, htmlparser2, jwt-decode, js-sha256, simple-peer) are included as source files in `external-libs/` rather than managed through a package manager. **Cross-platform:** Vendoring lets the framework ensure every dependency works in both the browser and Node.js, which matters because STRVCT's model layer is designed to run in both. Arbitrary npm packages frequently assume one environment or the other, which would conflict with that goal. **Security:** There are no transitive dependencies, no post-install scripts, and no exposure to supply chain attacks through compromised or malicious npm packages. The entire dependency tree is vendored source in the repository — auditable and version-controlled. ## Why not TypeScript? Integration cost. STRVCT's content-addressable build and in-browser source-level debugging (via eval with sourceURL) work cleanly with plain JavaScript. Adding a TS compile step while preserving content-hashed caching and step-through debugging looked like meaningful work for uncertain gain, especially given that slot annotations already carry type information at runtime and serve most of the same validation and documentation roles. The option remains open for the future, but it's not currently a priority. ## How does persistence work? Mark a class with `setShouldStore(true)` and its slots with `setShouldStoreSlot(true)`. The framework handles everything else: dirty tracking, batched commits at the end of each event loop, and transparent IndexedDB storage. Objects loaded from storage go through the same initialization lifecycle as new objects — no separate code paths. Cloud sync to Firebase Storage is available by extending `SvSyncableArrayNode` and providing a folder name. ## Is it local-first? Yes. Data lives in the browser's IndexedDB by default. The application works fully offline. Cloud sync is opt-in and additive — it backs up data and enables cross-device access, but the local database is always the primary store and serves as a cache for cloud data on subsequent loads. ## How is styling handled? All styling uses named JavaScript methods (`setBackgroundColor()`, `setFlexDirection()`, `setPadding()`) rather than CSS files. Themes are swappable dictionaries that can be scoped to any subtree. This avoids the combinatorial explosion of CSS selectors when views have multiple independent states (selected, disabled, highlighted, error, etc.) that interact visually. See the [Programmatic Styling](docs/Views/Programmatic%20Styling/index.html) docs for details. ## What about routing? There is no router. The object graph is the navigation structure. Nested objects produce drill-down columns. Breadcrumbs, column compaction on narrow viewports, and keyboard navigation are built in. Adding a new object type to the model automatically makes it navigable — no route configuration needed. ## What browsers are supported? Modern evergreen browsers (Chrome, Firefox, Safari, Edge). STRVCT uses contemporary JavaScript features like WeakRef, FinalizationRegistry, and private class fields. There is no transpilation step or polyfill layer. ## Can it run outside the browser? Yes. The model layer, persistence system, and boot sequence all run in Node.js with no DOM — the same application code, the same storage behavior, the same object lifecycle, just without the view layer. This is possible because the model never references views; views observe the model through notifications, not the other way around. Useful for tests, CLI tools, and server-side processing of the same object graphs the client uses. See [Headless Execution](../docs/Lifecycle/Headless%20Execution/index.html) for details. ## Is it production-ready? STRVCT is in active development and used in production by [undreamedof.ai](https://undreamedof.ai), an AI-powered virtual tabletop for D&D with ~90 domain classes, multiplayer sessions, cloud sync, and AI integration. The framework has been in continuous development since 2018. It is not yet widely adopted and the API may still change. ## What happens if the author stops working on this? MIT-licensed, and the entire codebase is readable: plain JavaScript, no transpiler, no opaque build chain, no transitive npm dependencies. The few third-party libraries are vendored source in `external-libs/`. If development stops, a sufficiently motivated user could fork it without needing to reverse-engineer a tooling stack first. It's not a reassuring answer in the sense of "you'll get corporate backing" — but compared to frameworks that lock you into their ecosystem, the escape route is short. ## What kinds of apps is it a good fit for? **App-shell SPAs:** logged-in, state-heavy products where the running application is the product and the marketing surface, if any, is a separate concern. A lot of the highest-valued consumer software being built right now fits this shape: OpenAI, Anthropic, xAI, Perplexity, Cursor (Anysphere), Harvey, Glean, Character.ai, ElevenLabs, Suno, Gamma, Midjourney — and, from the prior generation, Notion, Linear, Figma, Discord. Almost none of these depend on SSR or SEO for their core product. ChatGPT, Claude, Cursor, Figma, Linear, Notion, Discord, Character.ai, Suno, and Midjourney are all app-shell SPAs where the logged-in product is the product. They have marketing pages that need SEO, but those are typically a separate concern, often on a different stack entirely. The app itself is a client-side application with heavy state, real-time interaction, and no meaningful SEO surface. **Where it fits:** heavy client-side state, hundreds of domain classes, local-first persistence, first-class LLM integration, and a UI generated from the model rather than hand-assembled per screen. **Where it doesn't:** content platforms, traditional e-commerce, or marketing sites — categories where SEO and first-paint latency are competitive necessities and where frameworks like Next.js exist precisely to serve. The marketing surface around an app-shell SPA can be handled separately: [undreamedof.ai](https://undreamedof.ai) pairs a static marketing site with a STRVCT app on the same domain, which is usually the right split anyway. **Visual distinctiveness as the pitch:** the auto-generated UI has a consistent look of its own. Custom views can override any piece, but products where the interface is itself a design statement will spend more effort fighting the defaults than riding them. The framework suits products where correctness, data density, and navigation consistency matter more than visual differentiation. ## What's the history of this project? **Origins:** STRVCT began as internal infrastructure, not as a framework project. The earliest code was written in 2016 as part of an application called bitmarkets.js — Miller columns, a node hierarchy, and slot-based persistence — and was carried into a second unrelated application, voluntary.app, starting in 2017. The framework code was progressively separated from application code and extracted into its own repository, strvct.net, in 2020. It has since grown to include the object pool persistence system, gestures and drag-and-drop, content-addressable builds, cloud sync, and internationalization. The [Timeline](../Timeline/index.html) has the full list of milestones. **Public presence:** The project has not been publicly marketed or announced. Its only public presence is the GitHub repository and links from the author's GitHub and Twitter profile subtitles. It is not a commercial product, has no funding or sponsoring organization, and is developed as a personal framework — used in production by [undreamedof.ai](https://undreamedof.ai). ## How does it work with AI-assisted development? **Less to coordinate:** STRVCT's architecture is well suited to AI-assisted "vibe coding." In a conventional framework, building a feature means coordinating across components, stylesheets, state management, persistence wiring, route definitions, and API layers — an AI has to understand and keep all of these in sync. In STRVCT, a feature is typically a single model class with annotated slots. The AI only needs to describe the domain — what properties an object has, which should persist, which are editable — and the framework handles the rest. **What follows:** An AI can produce working, persistent, navigable applications from high-level descriptions of the domain model without needing to generate or coordinate view code, storage logic, or navigation. The consistent slot annotation pattern is easy to learn from examples, and the same pattern applies to every class in the system. For complex, data-model-driven applications, this can dramatically reduce the amount of code an AI needs to generate and the number of places things can go wrong. ## How do I get help when I'm stuck? The ecosystem is small. There's no Stack Overflow tag, no Discord, no book. What's there: - In-repo docs, regenerated from markdown and linked from the main index - [`llms.txt`](/llms.txt) and [`llms-full.txt`](/llms-full.txt), designed to be pasted into an LLM coding assistant - The framework source itself — vendored, readable, plain JavaScript with no transitive dependencies - [GitHub issues](https://github.com/stevedekorte/strvct.net/issues) for bug reports and questions In practice the recommended workflow is to give an LLM-backed coding agent (Claude Code, Cursor, Codex, etc.) the relevant docs and source as context, then let it reason from first principles. The slot/notification/naked-objects patterns are regular enough that a capable model can internalize them from a few dozen files — which is how the framework author works with it day-to-day. ## How do I get started? See the [Example App](Example%20App/index.html) for a complete working application in four classes, or the [Getting Started](docs/Getting%20Started/index.html) guide for setup and project structure. --- Source: /Timeline/ # Project Timeline Key milestones from the first commit through present day Framework architecture, UI system, persistence, and developer tooling. - **2016-01** — bitmarkets.js: First commit; Miller column browser, node hierarchy, and initial slot-based persistence - **2016-03** — NotificationCenter: Notification system added; node-to-view sync via deferred timeouts - **2016-04** — Framework Separation: Library code separated from app code; CSS split into framework and app layers - **2016-05** — StorableNode: BMStorableNode, IndexedDB persistence with dirty tracking and circular reference handling - **2017-02** — voluntary.app: Continued framework development under the voluntary.app repository - **2017-04** — IndexedDB Rewrite: NodeStore with IndexedDB via SyncDB; automatic dirty marking on slot updates - **2017-07** — Flex Columns: Browser columns moved to flex layout; touch scrolling and mobile orientation support - **2017-08** — Boot System: Boot folder and loading infrastructure; BMStorableNode separated from BMNode - **2018-06** — ES6 Classes: Migration from prototype-based Proto system to ES6 classes throughout the framework - **2019-02** — Gesture System: GestureRecognizer state machine with EventSetListener; TapGestureRecognizer - **2019-03** — Full Gesture Suite: LongPress, Slide, Pinch, and Rotation recognizers; GestureManager arbitration - **2019-09** — Drag and Drop: Drag-and-drop protocol with animations, placeholder views, and column caching - **2019-11** — Slot System: Formal Slot class with newSlot(); ObjectPool persistence; migration from Proto to classes - **2020-01** — strvct.net: New repository created; voluntary.app codebase imported as foundation - **2020-02** — Flex Layout: DomSplitView and flexible layout system for browser columns - **2020-02** — Image & Blob: Image wells, blob drops, MIME type support, and drag views - **2020-03** — Tile System: BrowserRows renamed to Tiles; tile-based navigation pattern solidified - **2020-04** — Content Store: Content-addressable blob storage with hash-based caching - **2020-05** — Themes: Theme system for customizable visual appearance - **2020-08** — WebRTC: PeerJS integration for real-time peer-to-peer communication - **2021-02** — Resource Loader: Rebuilt resource loading system with global compatibility fixes - **2022-01** — Boot Overhaul: Major cleanup of boot process, index building, and eval debugging - **2022-04** — CAM Build: Content-addressable memory build system with hash validation - **2022-05** — Breadcrumbs: BreadCrumbRowView for hierarchical navigation context - **2022-06** — Tile Rename: RowViews renamed to Tiles throughout the framework - **2022-08** — Object Pool: Major fixes for ObjectPool persistence, key handling, and event listeners - **2023-02** — App Bootstrap: Standardized App shared() pattern and resource setup - **2023-03** — Blob Cache: Content-addressable blob cache for efficient binary storage - **2023-07** — Blob Persistence: Full support for persisting blobs with reference tracking and GC - **2023-08** — WebRTC Service: WebRTC service layer for peer connection management - **2023-10** — HaveWords App: First major application built on STRVCT; later became Undreamed Of - **2024-01** — Music Library: Audio playback infrastructure for music and sound effects - **2024-04** — Error Handling: Error.rethrow() for chained error context; improved debugging - **2024-06** — Init Refactor: Split initPrototypeSlots and initPrototype for cleaner class setup - **2024-09** — Documentation: Comprehensive docs site with architecture guides and API reference - **2024-11** — Slot Maps: allSlotsMap fixes; improved slot introspection and enumeration - **2024-12** — AI Services: AI service abstraction layer supporting multiple providers - **2025-02** — Assistant API: Generalized AI Assistant and conversation management system - **2025-04** — Tool Calls: Structured tool calling system for AI function invocation - **2025-05** — Prompt Composer: Template-based prompt composition with file inclusion and variable substitution - **2025-09** — JSON Schema: Schema validation for model classes; AI-compatible type definitions - **2025-10** — Cloud Sync: Firebase Storage sync with write-ahead delta logs - **2025-11** — JSON Patches: RFC 6902 JSON Patch support for incremental model updates - **2026-01** — Image Gen: Image generation pipeline with evaluation and scaling - **2026-02** — Docs Site: Documentation site with layout engine, cards, and markdown support - **2026-03** — Internationalization: AI-powered UI translation with per-language IndexedDB and automatic model-to-view boundary translation - **2026-03** — Anchor Scroll: AI chat anchor scrolling and scroll-to-bottom button - **2026-03** — Battery Aware: Battery level monitoring for performance throttling detection - **2026-04** — AI Image Editor: Gemini-based image editing and scaling class hierarchy - **2026-04** — Accessibility: Automatic ARIA roles, labels, states, and landmarks derived from model annotations and view classes - **2026-04** — Public Cloud: SvPublicCloudSource for serving shared content via Firebase Storage manifests