Upgrade request analysis routing
This commit is contained in:
parent
1cd446bae8
commit
db3e080640
19 changed files with 1520 additions and 66 deletions
|
|
@ -18,12 +18,18 @@ The goal is to give request-processing tools stable system summaries instead of
|
|||
- JSON schema for structured request parsing output.
|
||||
- `tags.json`
|
||||
- Standardized request tags for queue analysis and admin review.
|
||||
- `terminology.json`
|
||||
- Canonical editor terminology and user-language aliases.
|
||||
- `modules.json`
|
||||
- Machine-readable index of granular KB slices for targeted retrieval.
|
||||
- `queue-workflow.md`
|
||||
- First-pass automation and review flow.
|
||||
- `editor-capabilities.md`
|
||||
- Shorthand capability matrix for common request-analysis questions.
|
||||
- `systems/*.md`
|
||||
- Human-readable system notes, organized by editor subsystem.
|
||||
- `modules/*.md`
|
||||
- Smaller topical docs that can be mixed into model context without sending the whole KB.
|
||||
|
||||
## Current System Coverage
|
||||
|
||||
|
|
@ -40,14 +46,15 @@ The scaffold currently covers:
|
|||
- Persistence and save pipeline
|
||||
- Floating windows and popout shell
|
||||
- Content catalog and record APIs
|
||||
- Routing terminology and modular retrieval slices
|
||||
|
||||
## How To Use This For Request Analysis
|
||||
|
||||
Suggested queue flow:
|
||||
|
||||
1. Pull a raw request submission from the launcher request store.
|
||||
2. Retrieve likely systems from `systems.json` using tags, aliases, and file names.
|
||||
3. Provide the matching `systems/*.md` files to the local model as context.
|
||||
2. Run a routing pass using `systems.json`, `modules.json`, and `terminology.json`.
|
||||
3. Retrieve only the most relevant `systems/*.md` and `modules/*.md` files.
|
||||
4. Require the model to use only tags from `tags.json`.
|
||||
5. Ask the model to split the submission into atomic requests.
|
||||
6. Require output that matches `request-analysis-schema.json`.
|
||||
|
|
@ -56,6 +63,7 @@ Suggested queue flow:
|
|||
|
||||
## Recommended Next Additions
|
||||
|
||||
- Keep expanding modules until every major tool and runtime handoff has at least one focused doc.
|
||||
- Add concrete file-level notes for major controllers as they evolve.
|
||||
- Add a small extractor script that refreshes endpoint lists from `server.js`.
|
||||
- Add examples of well-tagged historical requests for few-shot prompting.
|
||||
|
|
|
|||
96
docs/kb/modules.json
Normal file
96
docs/kb/modules.json
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"generatedFromRepoDate": "2026-06-27",
|
||||
"modules": [
|
||||
{
|
||||
"id": "request-routing-playbook",
|
||||
"name": "Request Routing Playbook",
|
||||
"docPath": "docs/kb/modules/request-routing-playbook.md",
|
||||
"tags": ["Request Board", "Wiki", "General"],
|
||||
"systemIds": ["request-board", "launcher-home"],
|
||||
"aliases": ["triage", "routing", "request parsing", "review flow"],
|
||||
"priority": "high"
|
||||
},
|
||||
{
|
||||
"id": "terminology-engine-language",
|
||||
"name": "Terminology And Engine Language",
|
||||
"docPath": "docs/kb/modules/terminology-engine-language.md",
|
||||
"tags": ["General", "Wiki", "Content", "Graphics Painter", "Tiling", "Rendering", "Worlds"],
|
||||
"systemIds": ["graphics-painter", "layers-tile-editing", "rendering-viewport", "content-catalog-records", "world-bootstrap"],
|
||||
"aliases": ["synonyms", "naming", "engine terminology", "language map"],
|
||||
"priority": "high"
|
||||
},
|
||||
{
|
||||
"id": "launcher-and-site",
|
||||
"name": "Launcher And Website Surface",
|
||||
"docPath": "docs/kb/modules/launcher-and-site.md",
|
||||
"tags": ["Launcher", "Website", "Polish", "Request Board"],
|
||||
"systemIds": ["launcher-home", "request-board"],
|
||||
"aliases": ["site", "homepage", "launcher", "main page"],
|
||||
"priority": "medium"
|
||||
},
|
||||
{
|
||||
"id": "request-board-operations",
|
||||
"name": "Request Board Operations",
|
||||
"docPath": "docs/kb/modules/request-board-operations.md",
|
||||
"tags": ["Request Board", "Website", "UI / Workflow", "Wiki"],
|
||||
"systemIds": ["request-board"],
|
||||
"aliases": ["request board", "admin review", "queue worker", "moderation"],
|
||||
"priority": "high"
|
||||
},
|
||||
{
|
||||
"id": "tile-canvas-tools",
|
||||
"name": "Tile Canvas Tools",
|
||||
"docPath": "docs/kb/modules/tile-canvas-tools.md",
|
||||
"tags": ["Tiling", "Layers", "Chunks", "UI / Workflow"],
|
||||
"systemIds": ["layers-tile-editing", "chunk-storage-streaming", "content-catalog-records"],
|
||||
"aliases": ["map painting", "rectangle tool", "brush", "eraser", "grid editing"],
|
||||
"priority": "high"
|
||||
},
|
||||
{
|
||||
"id": "graphics-painter-features",
|
||||
"name": "Graphics Painter Features",
|
||||
"docPath": "docs/kb/modules/graphics-painter-features.md",
|
||||
"tags": ["Graphics Painter", "Animation", "Content", "Windows"],
|
||||
"systemIds": ["graphics-painter", "content-catalog-records", "floating-window-shell"],
|
||||
"aliases": ["sprite editor", "art editor", "painting tool", "recoloring", "frame editing"],
|
||||
"priority": "high"
|
||||
},
|
||||
{
|
||||
"id": "chunk-and-world-ops",
|
||||
"name": "Chunk And World Operations",
|
||||
"docPath": "docs/kb/modules/chunk-and-world-ops.md",
|
||||
"tags": ["Chunks", "World Overview", "Worlds", "Performance"],
|
||||
"systemIds": ["chunk-storage-streaming", "world-overview", "world-bootstrap"],
|
||||
"aliases": ["chunk ops", "world overview", "world map", "chunk movement", "streaming"],
|
||||
"priority": "high"
|
||||
},
|
||||
{
|
||||
"id": "rendering-runtime-bridge",
|
||||
"name": "Rendering And Runtime Bridge",
|
||||
"docPath": "docs/kb/modules/rendering-runtime-bridge.md",
|
||||
"tags": ["Rendering", "Performance", "Animation", "Worlds"],
|
||||
"systemIds": ["rendering-viewport", "world-bootstrap", "chunk-storage-streaming"],
|
||||
"aliases": ["runtime", "game engine", "renderer", "viewport", "scene draw"],
|
||||
"priority": "medium"
|
||||
},
|
||||
{
|
||||
"id": "content-assets-and-imports",
|
||||
"name": "Content Assets And Imports",
|
||||
"docPath": "docs/kb/modules/content-assets-and-imports.md",
|
||||
"tags": ["Content", "Graphics Painter", "Tiling", "Persistence"],
|
||||
"systemIds": ["content-catalog-records", "graphics-painter", "persistence-save-pipeline"],
|
||||
"aliases": ["assets", "tile catalog", "sprite catalog", "imports", "images"],
|
||||
"priority": "medium"
|
||||
},
|
||||
{
|
||||
"id": "persistence-history-and-api",
|
||||
"name": "Persistence, History, And API Writes",
|
||||
"docPath": "docs/kb/modules/persistence-history-and-api.md",
|
||||
"tags": ["Persistence", "Chunks", "Content", "UI / Workflow"],
|
||||
"systemIds": ["persistence-save-pipeline", "chunk-storage-streaming", "content-catalog-records"],
|
||||
"aliases": ["saving", "undo", "redo", "history", "api writes"],
|
||||
"priority": "medium"
|
||||
}
|
||||
]
|
||||
}
|
||||
13
docs/kb/modules/chunk-and-world-ops.md
Normal file
13
docs/kb/modules/chunk-and-world-ops.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Chunk And World Operations
|
||||
|
||||
## What This Module Covers
|
||||
|
||||
This module handles world-scale navigation and chunk-backed operations rather than single-asset editing.
|
||||
|
||||
## Existing Capabilities
|
||||
|
||||
- neighborhood chunk loading around the current viewport
|
||||
- chunk move, duplicate, rotate, flip, and delete flows
|
||||
- world overview interactions
|
||||
- bookmark and point-of-interest navigation
|
||||
- batch save paths for chunk edits
|
||||
12
docs/kb/modules/content-assets-and-imports.md
Normal file
12
docs/kb/modules/content-assets-and-imports.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Content Assets And Imports
|
||||
|
||||
## What This Module Covers
|
||||
|
||||
This module tracks how tiles, sprites, images, and related metadata are stored, imported, previewed, and connected to editor features.
|
||||
|
||||
## Existing Capabilities
|
||||
|
||||
- content records for tiles, sprites, and images
|
||||
- imports and source-image handling
|
||||
- preview generation for art assets
|
||||
- tile and sprite catalog usage across editor tools
|
||||
15
docs/kb/modules/graphics-painter-features.md
Normal file
15
docs/kb/modules/graphics-painter-features.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# Graphics Painter Features
|
||||
|
||||
## What This Module Covers
|
||||
|
||||
This module is the detailed quick-reference for the asset art editor. It is where requests about painting graphics, recoloring sprites, frame editing, and art-side tooling should route.
|
||||
|
||||
## Existing Capabilities
|
||||
|
||||
- rectangle, circle, triangle, and line tools
|
||||
- outline, fill, and combined shape modes
|
||||
- shape erasers
|
||||
- animation timeline editing
|
||||
- frame duplication and ordering workflows
|
||||
- preview background support
|
||||
- animation preview window
|
||||
14
docs/kb/modules/launcher-and-site.md
Normal file
14
docs/kb/modules/launcher-and-site.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Launcher And Website Surface
|
||||
|
||||
## What This Module Covers
|
||||
|
||||
This module focuses on the public-facing launcher, its presentation, its navigation, and the supporting request/news board behavior shown outside the main editor runtime.
|
||||
|
||||
## Features
|
||||
|
||||
- floating-window launch flow for the studio
|
||||
- branded landing presentation
|
||||
- launcher background art treatment
|
||||
- request/news tab switching
|
||||
- repo link and launch affordances
|
||||
- admin-window entry point from the public board
|
||||
12
docs/kb/modules/persistence-history-and-api.md
Normal file
12
docs/kb/modules/persistence-history-and-api.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Persistence, History, And API Writes
|
||||
|
||||
## What This Module Covers
|
||||
|
||||
This module explains how edits become saved data, how history interacts with those edits, and where API writes sit in the workflow.
|
||||
|
||||
## Existing Capabilities
|
||||
|
||||
- save pipeline for chunk data
|
||||
- save pipeline for content records
|
||||
- history-aware editor state
|
||||
- server endpoints for persisted editor data
|
||||
12
docs/kb/modules/rendering-runtime-bridge.md
Normal file
12
docs/kb/modules/rendering-runtime-bridge.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Rendering And Runtime Bridge
|
||||
|
||||
## What This Module Covers
|
||||
|
||||
This module explains the handoff between authored editor data and runtime-facing map rendering behavior.
|
||||
|
||||
## What It Usually Means
|
||||
|
||||
- how edited data appears in the viewport
|
||||
- whether animations actually play in live rendering
|
||||
- how runtime entities or assets would consume editor-authored records
|
||||
- how gameplay requests may imply editor-side metadata
|
||||
15
docs/kb/modules/request-board-operations.md
Normal file
15
docs/kb/modules/request-board-operations.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# Request Board Operations
|
||||
|
||||
## What This Module Covers
|
||||
|
||||
This module describes the request intake, queue automation, admin review experience, deletion flow, and protected moderation tools.
|
||||
|
||||
## Core Capabilities
|
||||
|
||||
- public request submission storage
|
||||
- pending versus active request state
|
||||
- structured review metadata
|
||||
- admin-protected editing and deletion
|
||||
- queue worker launch and rerun flows
|
||||
- recent log viewing
|
||||
- popup review details for long-form analysis
|
||||
39
docs/kb/modules/request-routing-playbook.md
Normal file
39
docs/kb/modules/request-routing-playbook.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Request Routing Playbook
|
||||
|
||||
## Purpose
|
||||
|
||||
This module exists to help the queue worker turn messy, broad, or slang-heavy requests into a useful first interpretation before the deeper implementation pass begins.
|
||||
|
||||
## Routing Rules
|
||||
|
||||
- Prefer existing Worldshaper terminology when a user uses nearby language.
|
||||
- Split one submission into multiple request items only when the text clearly asks for separate changes.
|
||||
- If a request is broad, still produce a useful interpretation instead of returning an empty or dismissive review.
|
||||
- Low confidence should change the recommendation and review notes, not erase the attempt to help.
|
||||
|
||||
## Ambiguous Request Handling
|
||||
|
||||
- "Make the game better" is not zero-information. Treat it as a broad improvement request and map it to `General` plus the most likely systems.
|
||||
- "Add horses" is a content-plus-runtime request unless the text narrows it down. It may imply:
|
||||
- visual assets
|
||||
- placement on maps
|
||||
- runtime entity support
|
||||
- "Fix painting" should first determine whether the user means map tile painting or the Graphics Painter.
|
||||
|
||||
## What The First Pass Should Produce
|
||||
|
||||
- matched terms and likely meanings
|
||||
- candidate tags
|
||||
- likely systems
|
||||
- ambiguity level
|
||||
- a short rationale safe for admin review
|
||||
- possible directions if the user intent could branch
|
||||
|
||||
## What The Second Pass Should Produce
|
||||
|
||||
- clean title
|
||||
- primary category
|
||||
- standardized tags
|
||||
- parsed interpretation
|
||||
- implementation approach
|
||||
- review rationale and options when the request is still uncertain
|
||||
20
docs/kb/modules/terminology-engine-language.md
Normal file
20
docs/kb/modules/terminology-engine-language.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Terminology And Engine Language
|
||||
|
||||
## Purpose
|
||||
|
||||
Users often describe systems with game-development slang instead of the editor's exact names. This module helps map that language back into Worldshaper concepts.
|
||||
|
||||
## Common Term Bridges
|
||||
|
||||
- "sprite editor", "painting tool", and "recoloring tool" usually point toward `Graphics Painter`.
|
||||
- "map painting", "brush", and "grid editing" usually point toward `Tile Canvas Tools` and `Layers And Tile Editing`.
|
||||
- "engine", "runtime", or "actual game" usually point toward runtime-facing systems, not just editor windows.
|
||||
- "characters", "actors", and "entities" often cross `Content`, `Rendering`, and `Worlds`.
|
||||
- "map", "grid", and "tiles" can refer to chunk-backed tile placement rather than image editing.
|
||||
|
||||
## Meaning Differences That Matter
|
||||
|
||||
- Painting on the map is not the same as painting an asset.
|
||||
- A tile is usually a world-placement record. A sprite is usually an art asset or entity-facing image record.
|
||||
- A chunk is the storage and streaming unit, not just a visible square on screen.
|
||||
- A runtime request can require editor metadata even if the user only talks about gameplay.
|
||||
14
docs/kb/modules/tile-canvas-tools.md
Normal file
14
docs/kb/modules/tile-canvas-tools.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Tile Canvas Tools
|
||||
|
||||
## What This Module Covers
|
||||
|
||||
This module is about painting and editing the live map grid, not editing the source art for tiles or sprites.
|
||||
|
||||
## Existing Capabilities
|
||||
|
||||
- freehand paint on the active layer
|
||||
- rectangle, circle, and line-based placement workflows
|
||||
- erasing on active layers
|
||||
- height-aware sparse paint behavior
|
||||
- background tile and background-hole modes
|
||||
- grid-backed placement within chunk data
|
||||
|
|
@ -15,13 +15,14 @@ Turn raw launcher submissions into structured request items that are:
|
|||
## Recommended Pipeline
|
||||
|
||||
1. Read one pending submission.
|
||||
2. Split it into candidate atomic requests.
|
||||
2. Run a light routing pass that maps slang and broad language onto likely systems and tags.
|
||||
3. Retrieve likely systems from `docs/kb/systems.json`.
|
||||
4. Load the matching `docs/kb/systems/*.md` files.
|
||||
5. Load the standardized request tags from `docs/kb/tags.json`.
|
||||
6. Ask the local model for JSON that matches `docs/kb/request-analysis-schema.json`.
|
||||
7. Validate the JSON.
|
||||
8. Promote high-confidence items and hold low-confidence items for review.
|
||||
4. Retrieve likely focused modules from `docs/kb/modules.json`.
|
||||
5. Load only the matching `docs/kb/systems/*.md` and `docs/kb/modules/*.md` files.
|
||||
6. Load the standardized request tags from `docs/kb/tags.json`.
|
||||
7. Ask the local model for JSON that matches `docs/kb/request-analysis-schema.json`.
|
||||
8. Validate the JSON.
|
||||
9. Promote high-confidence items and hold low-confidence items for review.
|
||||
|
||||
## Suggested Confidence Rules
|
||||
|
||||
|
|
@ -41,7 +42,9 @@ Search `systems.json` using:
|
|||
- aliases
|
||||
- past tags from similar requests
|
||||
|
||||
If a submission touches multiple subsystems, feed the model the top two to four matching docs instead of the whole KB.
|
||||
If a submission touches multiple subsystems, feed the model the top two to four matching system docs plus the smallest helpful focused modules instead of the whole KB.
|
||||
|
||||
Use `terminology.json` during the routing pass so phrases like "sprite editor", "painting tool", "recoloring", and "engine" still resolve to the intended Worldshaper concepts.
|
||||
|
||||
## Prompt Skeleton
|
||||
|
||||
|
|
@ -67,6 +70,7 @@ If you are unsure, lower confidence and use statusRecommendation = "needs_review
|
|||
Then provide:
|
||||
|
||||
- the raw submission
|
||||
- the routing summary
|
||||
- the JSON schema
|
||||
- the retrieved KB docs
|
||||
|
||||
|
|
@ -121,6 +125,7 @@ Behavior:
|
|||
- high-confidence all-active results replace the pending submission with active request rows
|
||||
- mixed or lower-confidence results stay on the pending submission as review metadata
|
||||
- failures are stored as analysis errors instead of silently disappearing
|
||||
- broad or ambiguous requests should still receive a useful interpretation, likely systems, and possible directions instead of a dead-end review
|
||||
|
||||
## What Not To Automate First
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,70 @@
|
|||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"routing": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"summary": {
|
||||
"type": "string"
|
||||
},
|
||||
"ambiguity": {
|
||||
"type": "string",
|
||||
"enum": ["low", "medium", "high"]
|
||||
},
|
||||
"matchedTerms": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"suggestedTags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"suggestedSystems": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"suggestedModules": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"rationale": {
|
||||
"type": "string"
|
||||
},
|
||||
"possibleDirections": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"kbSections": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
|
|
|
|||
66
docs/kb/terminology.json
Normal file
66
docs/kb/terminology.json
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"generatedFromRepoDate": "2026-06-27",
|
||||
"terms": [
|
||||
{
|
||||
"canonical": "Graphics Painter",
|
||||
"aliases": ["graphic painter", "sprite editor", "art editor", "painting tool", "pixel editor", "recoloring tool"],
|
||||
"tags": ["Graphics Painter", "Content", "Animation"],
|
||||
"systemIds": ["graphics-painter", "content-catalog-records"]
|
||||
},
|
||||
{
|
||||
"canonical": "Tile Canvas",
|
||||
"aliases": ["map canvas", "map paint", "tile brush", "grid painter", "rectangle tile tool", "tile tool"],
|
||||
"tags": ["Tiling", "Layers", "Chunks"],
|
||||
"systemIds": ["layers-tile-editing", "chunk-storage-streaming"]
|
||||
},
|
||||
{
|
||||
"canonical": "Chunk",
|
||||
"aliases": ["map section", "region", "chunk cell", "chunk area"],
|
||||
"tags": ["Chunks", "World Overview", "Worlds"],
|
||||
"systemIds": ["chunk-storage-streaming", "world-overview"]
|
||||
},
|
||||
{
|
||||
"canonical": "World Overview",
|
||||
"aliases": ["overview map", "chunk overview", "world map", "big map"],
|
||||
"tags": ["World Overview", "Chunks", "Worlds"],
|
||||
"systemIds": ["world-overview", "chunk-storage-streaming"]
|
||||
},
|
||||
{
|
||||
"canonical": "Renderer",
|
||||
"aliases": ["runtime renderer", "viewport", "draw system", "scene draw", "engine view"],
|
||||
"tags": ["Rendering", "Performance", "Animation"],
|
||||
"systemIds": ["rendering-viewport"]
|
||||
},
|
||||
{
|
||||
"canonical": "Runtime",
|
||||
"aliases": ["engine", "game runtime", "play mode", "actual game"],
|
||||
"tags": ["Worlds", "Rendering", "Performance"],
|
||||
"systemIds": ["world-bootstrap", "rendering-viewport"]
|
||||
},
|
||||
{
|
||||
"canonical": "Character Entity",
|
||||
"aliases": ["character", "npc", "actor", "unit", "entity"],
|
||||
"tags": ["Content", "Rendering", "Worlds"],
|
||||
"systemIds": ["content-catalog-records", "rendering-viewport", "world-bootstrap"]
|
||||
},
|
||||
{
|
||||
"canonical": "Grid",
|
||||
"aliases": ["tile grid", "map grid", "cells", "squares"],
|
||||
"tags": ["Tiling", "Chunks", "Layers"],
|
||||
"systemIds": ["layers-tile-editing", "chunk-storage-streaming"]
|
||||
},
|
||||
{
|
||||
"canonical": "Asset Catalog",
|
||||
"aliases": ["sprite list", "tile list", "catalog", "content records", "asset database"],
|
||||
"tags": ["Content", "Persistence"],
|
||||
"systemIds": ["content-catalog-records", "persistence-save-pipeline"]
|
||||
},
|
||||
{
|
||||
"canonical": "Launcher Request Board",
|
||||
"aliases": ["request board", "requests", "admin review", "pending queue"],
|
||||
"tags": ["Request Board", "Website", "Wiki"],
|
||||
"systemIds": ["request-board", "launcher-home"]
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue