1729 lines
57 KiB
Python
1729 lines
57 KiB
Python
"""Diagram templates for quick-start examples."""
|
||
|
||
# Templates organized by format, then by category
|
||
PLANTUML_TEMPLATES = {
|
||
'class': {
|
||
'Basic Class Diagram': {
|
||
'description': 'Simple class with attributes and methods',
|
||
'code': '''@startuml
|
||
title Basic Class Diagram
|
||
|
||
class User {
|
||
+id: int
|
||
+name: String
|
||
+email: String
|
||
--
|
||
+login()
|
||
+logout()
|
||
}
|
||
|
||
class Order {
|
||
+id: int
|
||
+date: Date
|
||
+total: float
|
||
--
|
||
+addItem(item)
|
||
+removeItem(item)
|
||
+calculateTotal(): float
|
||
}
|
||
|
||
User "1" --> "*" Order : places
|
||
|
||
@enduml'''
|
||
},
|
||
'Inheritance Example': {
|
||
'description': 'Class hierarchy with inheritance and interfaces',
|
||
'code': '''@startuml
|
||
title Inheritance and Interfaces
|
||
|
||
interface Drawable {
|
||
+draw()
|
||
+resize(scale)
|
||
}
|
||
|
||
abstract class Shape {
|
||
#x: int
|
||
#y: int
|
||
+move(dx, dy)
|
||
{abstract} +area(): float
|
||
}
|
||
|
||
class Circle {
|
||
-radius: float
|
||
+area(): float
|
||
+draw()
|
||
}
|
||
|
||
class Rectangle {
|
||
-width: float
|
||
-height: float
|
||
+area(): float
|
||
+draw()
|
||
}
|
||
|
||
Drawable <|.. Shape
|
||
Shape <|-- Circle
|
||
Shape <|-- Rectangle
|
||
|
||
@enduml'''
|
||
},
|
||
},
|
||
'sequence': {
|
||
'Basic Sequence': {
|
||
'description': 'Simple request-response flow',
|
||
'code': '''@startuml
|
||
title Basic API Request Flow
|
||
|
||
actor User
|
||
participant "Web App" as App
|
||
participant "API Server" as API
|
||
database "Database" as DB
|
||
|
||
User -> App: Click Login
|
||
activate App
|
||
|
||
App -> API: POST /auth/login
|
||
activate API
|
||
|
||
API -> DB: SELECT user
|
||
activate DB
|
||
DB --> API: user data
|
||
deactivate DB
|
||
|
||
API --> App: JWT token
|
||
deactivate API
|
||
|
||
App --> User: Show dashboard
|
||
deactivate App
|
||
|
||
@enduml'''
|
||
},
|
||
'Authentication Flow': {
|
||
'description': 'OAuth2 authentication sequence',
|
||
'code': '''@startuml
|
||
title OAuth2 Authentication Flow
|
||
|
||
actor User
|
||
participant "Client App" as Client
|
||
participant "Auth Server" as Auth
|
||
participant "Resource Server" as Resource
|
||
|
||
User -> Client: Login request
|
||
Client -> Auth: Authorization request
|
||
Auth -> User: Login page
|
||
User -> Auth: Credentials
|
||
Auth -> Auth: Validate credentials
|
||
|
||
alt successful login
|
||
Auth --> Client: Authorization code
|
||
Client -> Auth: Exchange code for token
|
||
Auth --> Client: Access token + Refresh token
|
||
Client -> Resource: API request + Access token
|
||
Resource --> Client: Protected resource
|
||
Client --> User: Display data
|
||
else invalid credentials
|
||
Auth --> Client: Error
|
||
Client --> User: Show error
|
||
end
|
||
|
||
@enduml'''
|
||
},
|
||
},
|
||
'component': {
|
||
'System Architecture': {
|
||
'description': 'High-level system components',
|
||
'code': '''@startuml
|
||
title System Architecture
|
||
|
||
package "Frontend" {
|
||
[Web Application] as Web
|
||
[Mobile App] as Mobile
|
||
}
|
||
|
||
package "Backend Services" {
|
||
[API Gateway] as Gateway
|
||
[User Service] as UserSvc
|
||
[Order Service] as OrderSvc
|
||
}
|
||
|
||
package "Data Layer" {
|
||
database "PostgreSQL" as PG
|
||
database "Redis Cache" as Redis
|
||
}
|
||
|
||
Web --> Gateway
|
||
Mobile --> Gateway
|
||
|
||
Gateway --> UserSvc
|
||
Gateway --> OrderSvc
|
||
|
||
UserSvc --> PG
|
||
OrderSvc --> PG
|
||
Gateway --> Redis
|
||
|
||
@enduml'''
|
||
},
|
||
},
|
||
'state': {
|
||
'Order State Machine': {
|
||
'description': 'Order lifecycle states',
|
||
'code': '''@startuml
|
||
title Order State Machine
|
||
|
||
[*] --> Draft : create order
|
||
|
||
Draft --> Pending : submit
|
||
Draft --> Cancelled : cancel
|
||
|
||
Pending --> Confirmed : payment received
|
||
Pending --> Cancelled : payment failed
|
||
|
||
Confirmed --> Processing : begin fulfillment
|
||
Processing --> Shipped : dispatch
|
||
Shipped --> Delivered : delivery confirmed
|
||
|
||
Delivered --> [*]
|
||
Cancelled --> [*]
|
||
|
||
@enduml'''
|
||
},
|
||
},
|
||
'activity': {
|
||
'Checkout Process': {
|
||
'description': 'E-commerce checkout flow',
|
||
'code': '''@startuml
|
||
title Checkout Process
|
||
|
||
start
|
||
|
||
:View Cart;
|
||
|
||
if (Cart empty?) then (yes)
|
||
:Show empty cart message;
|
||
stop
|
||
endif
|
||
|
||
:Enter Shipping Address;
|
||
:Select Shipping Method;
|
||
:Enter Payment Details;
|
||
|
||
:Validate Payment;
|
||
|
||
if (Payment valid?) then (yes)
|
||
:Process Payment;
|
||
:Create Order;
|
||
:Send Confirmation Email;
|
||
:Show Success Page;
|
||
else (no)
|
||
:Show Payment Error;
|
||
endif
|
||
|
||
stop
|
||
|
||
@enduml'''
|
||
},
|
||
},
|
||
'mindmap': {
|
||
'Project Planning': {
|
||
'description': 'Project breakdown structure',
|
||
'code': '''@startmindmap
|
||
title Project Planning
|
||
|
||
* Project Launch
|
||
** Planning
|
||
*** Define scope
|
||
*** Set milestones
|
||
*** Allocate resources
|
||
** Development
|
||
*** Backend
|
||
**** API endpoints
|
||
**** Database layer
|
||
*** Frontend
|
||
**** Components
|
||
**** Styling
|
||
** Testing
|
||
*** Unit tests
|
||
*** Integration tests
|
||
** Deployment
|
||
*** CI/CD setup
|
||
*** Production release
|
||
|
||
@endmindmap'''
|
||
},
|
||
},
|
||
}
|
||
|
||
MERMAID_TEMPLATES = {
|
||
'flowchart': {
|
||
'Basic Flowchart': {
|
||
'description': 'Simple decision flowchart',
|
||
'code': '''flowchart TD
|
||
A[Start] --> B{Is it working?}
|
||
B -->|Yes| C[Great!]
|
||
B -->|No| D[Debug]
|
||
D --> B
|
||
C --> E[End]'''
|
||
},
|
||
'Process Flow': {
|
||
'description': 'Business process with multiple paths',
|
||
'code': '''flowchart LR
|
||
subgraph Input
|
||
A[User Request] --> B[Validate]
|
||
end
|
||
|
||
subgraph Processing
|
||
B --> C{Valid?}
|
||
C -->|Yes| D[Process]
|
||
C -->|No| E[Return Error]
|
||
D --> F[Store Result]
|
||
end
|
||
|
||
subgraph Output
|
||
F --> G[Send Response]
|
||
E --> G
|
||
end'''
|
||
},
|
||
'Top-Down Flow': {
|
||
'description': 'Vertical flowchart with conditions',
|
||
'code': '''flowchart TB
|
||
Start([Start]) --> Input[/Get Input/]
|
||
Input --> Validate{Valid Input?}
|
||
Validate -->|Yes| Process[Process Data]
|
||
Validate -->|No| Error[Show Error]
|
||
Error --> Input
|
||
Process --> Save[(Save to DB)]
|
||
Save --> Output[/Display Result/]
|
||
Output --> End([End])'''
|
||
},
|
||
},
|
||
'sequence': {
|
||
'Basic Sequence': {
|
||
'description': 'Simple API request flow',
|
||
'code': '''sequenceDiagram
|
||
actor User
|
||
participant App as Web App
|
||
participant API as API Server
|
||
participant DB as Database
|
||
|
||
User->>App: Click Login
|
||
activate App
|
||
App->>API: POST /auth/login
|
||
activate API
|
||
API->>DB: Query user
|
||
DB-->>API: User data
|
||
API-->>App: JWT Token
|
||
deactivate API
|
||
App-->>User: Show Dashboard
|
||
deactivate App'''
|
||
},
|
||
'Async Messaging': {
|
||
'description': 'Asynchronous message flow with loops',
|
||
'code': '''sequenceDiagram
|
||
participant Client
|
||
participant Server
|
||
participant Queue
|
||
participant Worker
|
||
|
||
Client->>+Server: Submit Job
|
||
Server->>Queue: Enqueue Job
|
||
Server-->>-Client: Job ID
|
||
|
||
loop Process Queue
|
||
Worker->>Queue: Poll for jobs
|
||
Queue-->>Worker: Job data
|
||
Worker->>Worker: Process
|
||
Worker->>Queue: Mark complete
|
||
end
|
||
|
||
Client->>Server: Check Status
|
||
Server-->>Client: Job Complete'''
|
||
},
|
||
},
|
||
'class': {
|
||
'Basic Class Diagram': {
|
||
'description': 'Classes with relationships',
|
||
'code': '''classDiagram
|
||
class Animal {
|
||
+String name
|
||
+int age
|
||
+makeSound()
|
||
}
|
||
|
||
class Dog {
|
||
+String breed
|
||
+bark()
|
||
+fetch()
|
||
}
|
||
|
||
class Cat {
|
||
+bool indoor
|
||
+meow()
|
||
+scratch()
|
||
}
|
||
|
||
Animal <|-- Dog
|
||
Animal <|-- Cat'''
|
||
},
|
||
'E-commerce Model': {
|
||
'description': 'Domain model with associations',
|
||
'code': '''classDiagram
|
||
class Customer {
|
||
+String id
|
||
+String name
|
||
+String email
|
||
+placeOrder()
|
||
}
|
||
|
||
class Order {
|
||
+String id
|
||
+Date date
|
||
+String status
|
||
+calculateTotal()
|
||
}
|
||
|
||
class Product {
|
||
+String id
|
||
+String name
|
||
+float price
|
||
}
|
||
|
||
class OrderItem {
|
||
+int quantity
|
||
+float unitPrice
|
||
}
|
||
|
||
Customer "1" --> "*" Order : places
|
||
Order "1" *-- "*" OrderItem : contains
|
||
OrderItem "*" --> "1" Product : references'''
|
||
},
|
||
},
|
||
'state': {
|
||
'Order States': {
|
||
'description': 'Order lifecycle state machine',
|
||
'code': '''stateDiagram-v2
|
||
[*] --> Draft
|
||
Draft --> Pending: submit
|
||
Draft --> Cancelled: cancel
|
||
|
||
Pending --> Confirmed: payment
|
||
Pending --> Cancelled: timeout
|
||
|
||
Confirmed --> Shipped: dispatch
|
||
Shipped --> Delivered: arrive
|
||
|
||
Delivered --> [*]
|
||
Cancelled --> [*]'''
|
||
},
|
||
'Traffic Light': {
|
||
'description': 'Simple state transitions',
|
||
'code': '''stateDiagram-v2
|
||
[*] --> Red
|
||
Red --> Green: timer
|
||
Green --> Yellow: timer
|
||
Yellow --> Red: timer
|
||
|
||
state Red {
|
||
[*] --> Waiting
|
||
Waiting --> Pedestrian: button
|
||
Pedestrian --> Waiting: timer
|
||
}'''
|
||
},
|
||
},
|
||
'er': {
|
||
'Blog Database': {
|
||
'description': 'Blog entity relationships',
|
||
'code': '''erDiagram
|
||
USER ||--o{ POST : writes
|
||
USER ||--o{ COMMENT : writes
|
||
POST ||--o{ COMMENT : has
|
||
POST }o--o{ TAG : has
|
||
|
||
USER {
|
||
uuid id PK
|
||
string username
|
||
string email
|
||
string password_hash
|
||
}
|
||
|
||
POST {
|
||
uuid id PK
|
||
uuid author_id FK
|
||
string title
|
||
text content
|
||
datetime published_at
|
||
}
|
||
|
||
COMMENT {
|
||
uuid id PK
|
||
uuid post_id FK
|
||
uuid user_id FK
|
||
text content
|
||
}
|
||
|
||
TAG {
|
||
uuid id PK
|
||
string name
|
||
}'''
|
||
},
|
||
},
|
||
'pie': {
|
||
'Simple Pie Chart': {
|
||
'description': 'Distribution pie chart',
|
||
'code': '''pie title Project Time Distribution
|
||
"Development" : 45
|
||
"Testing" : 25
|
||
"Documentation" : 15
|
||
"Meetings" : 15'''
|
||
},
|
||
},
|
||
'gantt': {
|
||
'Project Timeline': {
|
||
'description': 'Project schedule with dependencies',
|
||
'code': '''gantt
|
||
title Project Timeline
|
||
dateFormat YYYY-MM-DD
|
||
|
||
section Planning
|
||
Requirements :a1, 2024-01-01, 7d
|
||
Design :a2, after a1, 14d
|
||
|
||
section Development
|
||
Backend API :b1, after a2, 21d
|
||
Frontend UI :b2, after a2, 21d
|
||
Integration :b3, after b1, 7d
|
||
|
||
section Testing
|
||
QA Testing :c1, after b3, 14d
|
||
Bug Fixes :c2, after c1, 7d
|
||
|
||
section Deployment
|
||
Release :d1, after c2, 3d'''
|
||
},
|
||
},
|
||
}
|
||
|
||
OPENSCAD_TEMPLATES = {
|
||
'primitives': {
|
||
'Basic Shapes': {
|
||
'description': 'Cube, sphere, and cylinder primitives',
|
||
'code': '''// Basic 3D Primitives
|
||
$fn = 32; // Smoothness
|
||
|
||
// Cube
|
||
translate([-30, 0, 0])
|
||
cube([15, 15, 15], center=true);
|
||
|
||
// Sphere
|
||
sphere(r=10);
|
||
|
||
// Cylinder
|
||
translate([30, 0, 0])
|
||
cylinder(h=20, r=8, center=true);'''
|
||
},
|
||
'2D Shapes': {
|
||
'description': 'Circle, square, and polygon',
|
||
'code': '''// 2D Shapes (for extrusion)
|
||
$fn = 32;
|
||
|
||
// Circle
|
||
translate([-30, 0, 0])
|
||
circle(r=10);
|
||
|
||
// Square
|
||
square([15, 15], center=true);
|
||
|
||
// Polygon
|
||
translate([30, 0, 0])
|
||
polygon(points=[
|
||
[0, 15],
|
||
[-13, -7.5],
|
||
[13, -7.5]
|
||
]);'''
|
||
},
|
||
},
|
||
'operations': {
|
||
'Boolean Operations': {
|
||
'description': 'Union, difference, and intersection',
|
||
'code': '''// Boolean Operations Demo
|
||
$fn = 32;
|
||
|
||
// Difference: cube with spherical hole
|
||
translate([-35, 0, 0])
|
||
difference() {
|
||
cube([20, 20, 20], center=true);
|
||
sphere(r=12);
|
||
}
|
||
|
||
// Union: combined shapes
|
||
union() {
|
||
cube([15, 15, 15], center=true);
|
||
sphere(r=10);
|
||
}
|
||
|
||
// Intersection: overlapping volume
|
||
translate([35, 0, 0])
|
||
intersection() {
|
||
cube([20, 20, 20], center=true);
|
||
sphere(r=14);
|
||
}'''
|
||
},
|
||
'Extrusions': {
|
||
'description': 'Linear and rotational extrusion',
|
||
'code': '''// Extrusion Examples
|
||
$fn = 32;
|
||
|
||
// Linear extrude a shape
|
||
translate([-25, 0, 0])
|
||
linear_extrude(height=20, twist=45)
|
||
square([10, 10], center=true);
|
||
|
||
// Rotate extrude (lathe)
|
||
translate([25, 0, 0])
|
||
rotate_extrude()
|
||
translate([10, 0, 0])
|
||
circle(r=5);'''
|
||
},
|
||
},
|
||
'transforms': {
|
||
'Transformations': {
|
||
'description': 'Translate, rotate, and scale',
|
||
'code': '''// Transformation Examples
|
||
$fn = 32;
|
||
|
||
// Original
|
||
color("red")
|
||
cube([10, 10, 10], center=true);
|
||
|
||
// Translated
|
||
color("green")
|
||
translate([20, 0, 0])
|
||
cube([10, 10, 10], center=true);
|
||
|
||
// Rotated
|
||
color("blue")
|
||
translate([40, 0, 0])
|
||
rotate([45, 0, 45])
|
||
cube([10, 10, 10], center=true);
|
||
|
||
// Scaled
|
||
color("yellow")
|
||
translate([60, 0, 0])
|
||
scale([1.5, 0.5, 1])
|
||
cube([10, 10, 10], center=true);'''
|
||
},
|
||
'Mirror and Hull': {
|
||
'description': 'Mirror and convex hull operations',
|
||
'code': '''// Mirror and Hull Examples
|
||
$fn = 32;
|
||
|
||
// Mirror operation
|
||
translate([-30, 0, 0]) {
|
||
sphere(r=5);
|
||
mirror([1, 0, 0])
|
||
translate([15, 0, 0])
|
||
sphere(r=5);
|
||
}
|
||
|
||
// Hull: convex wrapper around shapes
|
||
translate([20, 0, 0])
|
||
hull() {
|
||
sphere(r=5);
|
||
translate([20, 0, 0])
|
||
sphere(r=5);
|
||
translate([10, 15, 0])
|
||
sphere(r=5);
|
||
}'''
|
||
},
|
||
},
|
||
'modules': {
|
||
'Custom Module': {
|
||
'description': 'Reusable parametric module',
|
||
'code': '''// Parametric Module Example
|
||
$fn = 32;
|
||
|
||
// Define a rounded box module
|
||
module rounded_box(size, radius) {
|
||
hull() {
|
||
for (x = [-1, 1])
|
||
for (y = [-1, 1])
|
||
for (z = [-1, 1])
|
||
translate([
|
||
x * (size[0]/2 - radius),
|
||
y * (size[1]/2 - radius),
|
||
z * (size[2]/2 - radius)
|
||
])
|
||
sphere(r=radius);
|
||
}
|
||
}
|
||
|
||
// Use the module
|
||
rounded_box([30, 20, 15], 3);
|
||
|
||
translate([40, 0, 0])
|
||
rounded_box([20, 20, 20], 5);'''
|
||
},
|
||
'Gear Module': {
|
||
'description': 'Simple parametric gear',
|
||
'code': '''// Simple Gear Module
|
||
$fn = 64;
|
||
|
||
module gear(teeth, tooth_size, thickness, hole_r) {
|
||
difference() {
|
||
union() {
|
||
// Base cylinder
|
||
cylinder(h=thickness, r=teeth*tooth_size/6.28, center=true);
|
||
|
||
// Teeth
|
||
for (i = [0:teeth-1]) {
|
||
rotate([0, 0, i * 360/teeth])
|
||
translate([teeth*tooth_size/6.28, 0, 0])
|
||
cylinder(h=thickness, r=tooth_size/2, center=true);
|
||
}
|
||
}
|
||
// Center hole
|
||
cylinder(h=thickness+1, r=hole_r, center=true);
|
||
}
|
||
}
|
||
|
||
// Create a gear
|
||
gear(teeth=12, tooth_size=5, thickness=5, hole_r=3);'''
|
||
},
|
||
},
|
||
'mechanical': {
|
||
'Enclosure Box': {
|
||
'description': 'Box with lid for electronics',
|
||
'code': '''// Electronics Enclosure
|
||
$fn = 32;
|
||
|
||
box_size = [60, 40, 25];
|
||
wall = 2;
|
||
lid_height = 8;
|
||
|
||
// Bottom part
|
||
module box_bottom() {
|
||
difference() {
|
||
cube(box_size, center=true);
|
||
translate([0, 0, wall])
|
||
cube([
|
||
box_size[0] - wall*2,
|
||
box_size[1] - wall*2,
|
||
box_size[2]
|
||
], center=true);
|
||
}
|
||
}
|
||
|
||
// Lid
|
||
module box_lid() {
|
||
translate([0, 0, box_size[2]/2 + lid_height/2 + 2])
|
||
difference() {
|
||
cube([box_size[0], box_size[1], lid_height], center=true);
|
||
translate([0, 0, -wall])
|
||
cube([
|
||
box_size[0] - wall*4,
|
||
box_size[1] - wall*4,
|
||
lid_height
|
||
], center=true);
|
||
}
|
||
}
|
||
|
||
box_bottom();
|
||
box_lid();'''
|
||
},
|
||
'Bracket': {
|
||
'description': 'L-shaped mounting bracket',
|
||
'code': '''// Mounting Bracket
|
||
$fn = 32;
|
||
|
||
thickness = 3;
|
||
width = 20;
|
||
leg1 = 30;
|
||
leg2 = 25;
|
||
hole_d = 5;
|
||
hole_margin = 8;
|
||
|
||
module bracket() {
|
||
difference() {
|
||
union() {
|
||
// Vertical leg
|
||
cube([width, thickness, leg1]);
|
||
|
||
// Horizontal leg
|
||
cube([width, leg2, thickness]);
|
||
|
||
// Fillet/gusset
|
||
translate([0, thickness, thickness])
|
||
rotate([0, 90, 0])
|
||
linear_extrude(width)
|
||
polygon([[0,0], [8,0], [0,8]]);
|
||
}
|
||
|
||
// Mounting holes
|
||
translate([width/2, -1, leg1 - hole_margin])
|
||
rotate([-90, 0, 0])
|
||
cylinder(h=thickness+2, d=hole_d);
|
||
|
||
translate([width/2, leg2 - hole_margin, -1])
|
||
cylinder(h=thickness+2, d=hole_d);
|
||
}
|
||
}
|
||
|
||
bracket();'''
|
||
},
|
||
},
|
||
}
|
||
|
||
CODE_TEMPLATES = {
|
||
'python': {
|
||
'Hello World': {
|
||
'description': 'Simple Python hello world',
|
||
'language': 'python',
|
||
'code': '''def hello_world():
|
||
"""A simple example function."""
|
||
print("Hello, World!")
|
||
|
||
if __name__ == "__main__":
|
||
hello_world()'''
|
||
},
|
||
'Class Example': {
|
||
'description': 'Python class with methods',
|
||
'language': 'python',
|
||
'code': '''class Rectangle:
|
||
"""A simple rectangle class."""
|
||
|
||
def __init__(self, width: float, height: float):
|
||
self.width = width
|
||
self.height = height
|
||
|
||
@property
|
||
def area(self) -> float:
|
||
"""Calculate the area of the rectangle."""
|
||
return self.width * self.height
|
||
|
||
@property
|
||
def perimeter(self) -> float:
|
||
"""Calculate the perimeter of the rectangle."""
|
||
return 2 * (self.width + self.height)
|
||
|
||
def __repr__(self) -> str:
|
||
return f"Rectangle({self.width}, {self.height})"
|
||
|
||
|
||
# Example usage
|
||
rect = Rectangle(10, 5)
|
||
print(f"Area: {rect.area}")
|
||
print(f"Perimeter: {rect.perimeter}")'''
|
||
},
|
||
'FastAPI Endpoint': {
|
||
'description': 'FastAPI route handler example',
|
||
'language': 'python',
|
||
'code': '''from fastapi import FastAPI, HTTPException
|
||
from pydantic import BaseModel
|
||
from typing import List, Optional
|
||
|
||
app = FastAPI()
|
||
|
||
class Item(BaseModel):
|
||
id: int
|
||
name: str
|
||
description: Optional[str] = None
|
||
price: float
|
||
|
||
items_db: List[Item] = []
|
||
|
||
@app.get("/items", response_model=List[Item])
|
||
async def get_items():
|
||
"""Get all items."""
|
||
return items_db
|
||
|
||
@app.get("/items/{item_id}", response_model=Item)
|
||
async def get_item(item_id: int):
|
||
"""Get a specific item by ID."""
|
||
for item in items_db:
|
||
if item.id == item_id:
|
||
return item
|
||
raise HTTPException(status_code=404, detail="Item not found")
|
||
|
||
@app.post("/items", response_model=Item)
|
||
async def create_item(item: Item):
|
||
"""Create a new item."""
|
||
items_db.append(item)
|
||
return item'''
|
||
},
|
||
},
|
||
'javascript': {
|
||
'Hello World': {
|
||
'description': 'Simple JavaScript hello world',
|
||
'language': 'javascript',
|
||
'code': '''// Hello World in JavaScript
|
||
function greet(name) {
|
||
return `Hello, ${name}!`;
|
||
}
|
||
|
||
console.log(greet("World"));'''
|
||
},
|
||
'Async/Await Example': {
|
||
'description': 'Async function with fetch',
|
||
'language': 'javascript',
|
||
'code': '''// Async/Await API fetch example
|
||
async function fetchUserData(userId) {
|
||
try {
|
||
const response = await fetch(`https://api.example.com/users/${userId}`);
|
||
|
||
if (!response.ok) {
|
||
throw new Error(`HTTP error! status: ${response.status}`);
|
||
}
|
||
|
||
const userData = await response.json();
|
||
return userData;
|
||
} catch (error) {
|
||
console.error("Failed to fetch user data:", error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// Usage
|
||
async function main() {
|
||
const user = await fetchUserData(123);
|
||
console.log("User:", user);
|
||
}
|
||
|
||
main();'''
|
||
},
|
||
'React Component': {
|
||
'description': 'React functional component with hooks',
|
||
'language': 'jsx',
|
||
'code': '''import React, { useState, useEffect } from 'react';
|
||
|
||
function Counter({ initialValue = 0 }) {
|
||
const [count, setCount] = useState(initialValue);
|
||
|
||
useEffect(() => {
|
||
document.title = `Count: ${count}`;
|
||
}, [count]);
|
||
|
||
const increment = () => setCount(c => c + 1);
|
||
const decrement = () => setCount(c => c - 1);
|
||
const reset = () => setCount(initialValue);
|
||
|
||
return (
|
||
<div className="counter">
|
||
<h2>Count: {count}</h2>
|
||
<div className="buttons">
|
||
<button onClick={decrement}>-</button>
|
||
<button onClick={reset}>Reset</button>
|
||
<button onClick={increment}>+</button>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export default Counter;'''
|
||
},
|
||
},
|
||
'rust': {
|
||
'Hello World': {
|
||
'description': 'Simple Rust hello world',
|
||
'language': 'rust',
|
||
'code': '''fn main() {
|
||
println!("Hello, World!");
|
||
}'''
|
||
},
|
||
'Struct Example': {
|
||
'description': 'Rust struct with implementation',
|
||
'language': 'rust',
|
||
'code': '''use std::fmt;
|
||
|
||
#[derive(Debug)]
|
||
struct Rectangle {
|
||
width: f64,
|
||
height: f64,
|
||
}
|
||
|
||
impl Rectangle {
|
||
fn new(width: f64, height: f64) -> Self {
|
||
Rectangle { width, height }
|
||
}
|
||
|
||
fn area(&self) -> f64 {
|
||
self.width * self.height
|
||
}
|
||
|
||
fn perimeter(&self) -> f64 {
|
||
2.0 * (self.width + self.height)
|
||
}
|
||
|
||
fn is_square(&self) -> bool {
|
||
(self.width - self.height).abs() < f64::EPSILON
|
||
}
|
||
}
|
||
|
||
impl fmt::Display for Rectangle {
|
||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||
write!(f, "Rectangle({}x{})", self.width, self.height)
|
||
}
|
||
}
|
||
|
||
fn main() {
|
||
let rect = Rectangle::new(10.0, 5.0);
|
||
println!("{}", rect);
|
||
println!("Area: {}", rect.area());
|
||
println!("Perimeter: {}", rect.perimeter());
|
||
println!("Is square: {}", rect.is_square());
|
||
}'''
|
||
},
|
||
},
|
||
'go': {
|
||
'Hello World': {
|
||
'description': 'Simple Go hello world',
|
||
'language': 'go',
|
||
'code': '''package main
|
||
|
||
import "fmt"
|
||
|
||
func main() {
|
||
fmt.Println("Hello, World!")
|
||
}'''
|
||
},
|
||
'HTTP Server': {
|
||
'description': 'Simple Go HTTP server',
|
||
'language': 'go',
|
||
'code': '''package main
|
||
|
||
import (
|
||
"encoding/json"
|
||
"log"
|
||
"net/http"
|
||
)
|
||
|
||
type Response struct {
|
||
Message string `json:"message"`
|
||
Status int `json:"status"`
|
||
}
|
||
|
||
func helloHandler(w http.ResponseWriter, r *http.Request) {
|
||
response := Response{
|
||
Message: "Hello, World!",
|
||
Status: 200,
|
||
}
|
||
|
||
w.Header().Set("Content-Type", "application/json")
|
||
json.NewEncoder(w).Encode(response)
|
||
}
|
||
|
||
func main() {
|
||
http.HandleFunc("/", helloHandler)
|
||
|
||
log.Println("Server starting on :8080...")
|
||
if err := http.ListenAndServe(":8080", nil); err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
}'''
|
||
},
|
||
},
|
||
'sql': {
|
||
'Create Table': {
|
||
'description': 'SQL table creation with constraints',
|
||
'language': 'sql',
|
||
'code': '''-- Create users table
|
||
CREATE TABLE users (
|
||
id SERIAL PRIMARY KEY,
|
||
username VARCHAR(50) NOT NULL UNIQUE,
|
||
email VARCHAR(100) NOT NULL UNIQUE,
|
||
password_hash VARCHAR(255) NOT NULL,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
-- Create orders table with foreign key
|
||
CREATE TABLE orders (
|
||
id SERIAL PRIMARY KEY,
|
||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||
total_amount DECIMAL(10, 2) NOT NULL,
|
||
status VARCHAR(20) DEFAULT 'pending',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
-- Create index for faster lookups
|
||
CREATE INDEX idx_orders_user_id ON orders(user_id);
|
||
CREATE INDEX idx_orders_status ON orders(status);'''
|
||
},
|
||
'Common Queries': {
|
||
'description': 'Common SQL query patterns',
|
||
'language': 'sql',
|
||
'code': '''-- Select with join
|
||
SELECT
|
||
u.username,
|
||
u.email,
|
||
COUNT(o.id) as order_count,
|
||
COALESCE(SUM(o.total_amount), 0) as total_spent
|
||
FROM users u
|
||
LEFT JOIN orders o ON u.id = o.user_id
|
||
GROUP BY u.id, u.username, u.email
|
||
ORDER BY total_spent DESC;
|
||
|
||
-- Subquery example
|
||
SELECT * FROM users
|
||
WHERE id IN (
|
||
SELECT DISTINCT user_id
|
||
FROM orders
|
||
WHERE total_amount > 100
|
||
);
|
||
|
||
-- Window function
|
||
SELECT
|
||
username,
|
||
total_amount,
|
||
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) as order_rank
|
||
FROM users u
|
||
JOIN orders o ON u.id = o.user_id;'''
|
||
},
|
||
},
|
||
'bash': {
|
||
'Script Template': {
|
||
'description': 'Bash script with common patterns',
|
||
'language': 'bash',
|
||
'code': '''#!/bin/bash
|
||
|
||
# Script description
|
||
# Usage: ./script.sh [options]
|
||
|
||
set -euo pipefail # Exit on error, undefined vars, pipe failures
|
||
|
||
# Constants
|
||
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
readonly LOG_FILE="/tmp/script.log"
|
||
|
||
# Functions
|
||
log() {
|
||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
|
||
}
|
||
|
||
die() {
|
||
log "ERROR: $*"
|
||
exit 1
|
||
}
|
||
|
||
usage() {
|
||
cat <<EOF
|
||
Usage: $(basename "$0") [OPTIONS]
|
||
|
||
Options:
|
||
-h, --help Show this help message
|
||
-v, --verbose Enable verbose output
|
||
-f, --file Input file path
|
||
|
||
EOF
|
||
exit 0
|
||
}
|
||
|
||
# Parse arguments
|
||
VERBOSE=false
|
||
INPUT_FILE=""
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
-h|--help) usage ;;
|
||
-v|--verbose) VERBOSE=true; shift ;;
|
||
-f|--file) INPUT_FILE="$2"; shift 2 ;;
|
||
*) die "Unknown option: $1" ;;
|
||
esac
|
||
done
|
||
|
||
# Main logic
|
||
main() {
|
||
log "Starting script..."
|
||
|
||
if [[ -n "$INPUT_FILE" ]]; then
|
||
log "Processing file: $INPUT_FILE"
|
||
fi
|
||
|
||
log "Done!"
|
||
}
|
||
|
||
main "$@"'''
|
||
},
|
||
},
|
||
'html': {
|
||
'Basic Page': {
|
||
'description': 'HTML5 page template',
|
||
'language': 'html',
|
||
'code': '''<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>My Page</title>
|
||
<style>
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
line-height: 1.6;
|
||
color: #333;
|
||
}
|
||
|
||
.container {
|
||
max-width: 1200px;
|
||
margin: 0 auto;
|
||
padding: 2rem;
|
||
}
|
||
|
||
header {
|
||
background: #2c3e50;
|
||
color: white;
|
||
padding: 1rem 0;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<header>
|
||
<div class="container">
|
||
<h1>Welcome</h1>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="container">
|
||
<h2>Hello, World!</h2>
|
||
<p>This is a basic HTML5 template.</p>
|
||
</main>
|
||
|
||
<script>
|
||
console.log('Page loaded!');
|
||
</script>
|
||
</body>
|
||
</html>'''
|
||
},
|
||
},
|
||
}
|
||
|
||
# SVG Templates for wireframes and diagrams
|
||
SVG_TEMPLATES = {
|
||
'wireframes': {
|
||
'Login Page': {
|
||
'description': 'Simple login form wireframe',
|
||
'code': '''<?xml version="1.0" encoding="UTF-8"?>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 500" width="400" height="500">
|
||
<rect width="100%" height="100%" fill="#f9fafb"/>
|
||
|
||
<!-- Card container -->
|
||
<rect x="50" y="80" width="300" height="340" rx="8" fill="#ffffff" stroke="#e5e7eb"/>
|
||
|
||
<!-- Logo placeholder -->
|
||
<circle cx="200" cy="130" r="30" fill="#e5e7eb"/>
|
||
<text x="200" y="135" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#9ca3af">Logo</text>
|
||
|
||
<!-- Title -->
|
||
<text x="200" y="190" text-anchor="middle" font-family="sans-serif" font-size="20" font-weight="bold" fill="#111827">Welcome Back</text>
|
||
|
||
<!-- Email input -->
|
||
<text x="70" y="230" font-family="sans-serif" font-size="12" fill="#374151">Email</text>
|
||
<rect x="70" y="240" width="260" height="40" rx="4" fill="#ffffff" stroke="#d1d5db"/>
|
||
<text x="82" y="265" font-family="sans-serif" font-size="14" fill="#9ca3af">you@example.com</text>
|
||
|
||
<!-- Password input -->
|
||
<text x="70" y="300" font-family="sans-serif" font-size="12" fill="#374151">Password</text>
|
||
<rect x="70" y="310" width="260" height="40" rx="4" fill="#ffffff" stroke="#d1d5db"/>
|
||
<text x="82" y="335" font-family="sans-serif" font-size="14" fill="#9ca3af">••••••••</text>
|
||
|
||
<!-- Sign in button -->
|
||
<rect x="70" y="370" width="260" height="40" rx="4" fill="#3b82f6"/>
|
||
<text x="200" y="395" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#ffffff">Sign In</text>
|
||
|
||
<!-- Forgot password link -->
|
||
<text x="200" y="435" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#3b82f6">Forgot password?</text>
|
||
</svg>'''
|
||
},
|
||
'Dashboard Layout': {
|
||
'description': 'Dashboard with sidebar and cards',
|
||
'code': '''<?xml version="1.0" encoding="UTF-8"?>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600" width="800" height="600">
|
||
<rect width="100%" height="100%" fill="#f3f4f6"/>
|
||
|
||
<!-- Sidebar -->
|
||
<rect x="0" y="0" width="200" height="600" fill="#1f2937"/>
|
||
<text x="20" y="40" font-family="sans-serif" font-size="20" font-weight="bold" fill="#ffffff">Dashboard</text>
|
||
|
||
<!-- Sidebar menu items -->
|
||
<rect x="0" y="70" width="200" height="40" fill="#374151"/>
|
||
<text x="20" y="95" font-family="sans-serif" font-size="14" fill="#ffffff">Overview</text>
|
||
|
||
<text x="20" y="135" font-family="sans-serif" font-size="14" fill="#9ca3af">Analytics</text>
|
||
<text x="20" y="175" font-family="sans-serif" font-size="14" fill="#9ca3af">Reports</text>
|
||
<text x="20" y="215" font-family="sans-serif" font-size="14" fill="#9ca3af">Settings</text>
|
||
|
||
<!-- Top header -->
|
||
<rect x="200" y="0" width="600" height="60" fill="#ffffff" stroke="#e5e7eb"/>
|
||
<text x="220" y="38" font-family="sans-serif" font-size="18" fill="#111827">Welcome back, User</text>
|
||
|
||
<!-- Search box -->
|
||
<rect x="500" y="15" width="180" height="30" rx="4" fill="#f3f4f6" stroke="#d1d5db"/>
|
||
<text x="515" y="35" font-family="sans-serif" font-size="12" fill="#9ca3af">Search...</text>
|
||
|
||
<!-- Avatar -->
|
||
<circle cx="760" cy="30" r="18" fill="#e5e7eb"/>
|
||
|
||
<!-- Stats cards -->
|
||
<rect x="220" y="80" width="170" height="100" rx="8" fill="#ffffff" stroke="#e5e7eb"/>
|
||
<text x="240" y="115" font-family="sans-serif" font-size="12" fill="#6b7280">Total Users</text>
|
||
<text x="240" y="150" font-family="sans-serif" font-size="28" font-weight="bold" fill="#111827">12,345</text>
|
||
|
||
<rect x="410" y="80" width="170" height="100" rx="8" fill="#ffffff" stroke="#e5e7eb"/>
|
||
<text x="430" y="115" font-family="sans-serif" font-size="12" fill="#6b7280">Revenue</text>
|
||
<text x="430" y="150" font-family="sans-serif" font-size="28" font-weight="bold" fill="#111827">$54,321</text>
|
||
|
||
<rect x="600" y="80" width="170" height="100" rx="8" fill="#ffffff" stroke="#e5e7eb"/>
|
||
<text x="620" y="115" font-family="sans-serif" font-size="12" fill="#6b7280">Orders</text>
|
||
<text x="620" y="150" font-family="sans-serif" font-size="28" font-weight="bold" fill="#111827">1,234</text>
|
||
|
||
<!-- Main content area -->
|
||
<rect x="220" y="200" width="550" height="280" rx="8" fill="#ffffff" stroke="#e5e7eb"/>
|
||
<text x="240" y="230" font-family="sans-serif" font-size="16" font-weight="bold" fill="#111827">Recent Activity</text>
|
||
|
||
<!-- Chart placeholder -->
|
||
<rect x="240" y="250" width="510" height="200" rx="4" fill="#f9fafb" stroke="#e5e7eb" stroke-dasharray="4,4"/>
|
||
<text x="495" y="355" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#9ca3af">Chart Placeholder</text>
|
||
</svg>'''
|
||
},
|
||
'Mobile App Screen': {
|
||
'description': 'Mobile app layout wireframe',
|
||
'code': '''<?xml version="1.0" encoding="UTF-8"?>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 375 812" width="375" height="812">
|
||
<!-- Phone frame -->
|
||
<rect width="100%" height="100%" fill="#ffffff" rx="40"/>
|
||
|
||
<!-- Status bar -->
|
||
<rect x="0" y="0" width="375" height="44" fill="#f9fafb"/>
|
||
<text x="187" y="28" text-anchor="middle" font-family="sans-serif" font-size="14" font-weight="bold" fill="#111827">9:41</text>
|
||
|
||
<!-- Header -->
|
||
<rect x="0" y="44" width="375" height="56" fill="#ffffff" stroke="#e5e7eb"/>
|
||
<text x="20" y="78" font-family="sans-serif" font-size="24" fill="#3b82f6">←</text>
|
||
<text x="187" y="80" text-anchor="middle" font-family="sans-serif" font-size="17" font-weight="bold" fill="#111827">Profile</text>
|
||
|
||
<!-- Profile section -->
|
||
<circle cx="187" cy="170" r="50" fill="#e5e7eb"/>
|
||
<text x="187" y="175" text-anchor="middle" font-family="sans-serif" font-size="16" fill="#9ca3af">Photo</text>
|
||
<text x="187" y="245" text-anchor="middle" font-family="sans-serif" font-size="22" font-weight="bold" fill="#111827">John Doe</text>
|
||
<text x="187" y="270" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#6b7280">john@example.com</text>
|
||
|
||
<!-- Menu items -->
|
||
<g transform="translate(0, 300)">
|
||
<rect x="20" y="0" width="335" height="56" fill="#ffffff"/>
|
||
<line x1="20" y1="56" x2="355" y2="56" stroke="#e5e7eb"/>
|
||
<text x="40" y="35" font-family="sans-serif" font-size="16" fill="#111827">Edit Profile</text>
|
||
<text x="335" y="35" font-family="sans-serif" font-size="20" fill="#9ca3af">›</text>
|
||
|
||
<rect x="20" y="56" width="335" height="56" fill="#ffffff"/>
|
||
<line x1="20" y1="112" x2="355" y2="112" stroke="#e5e7eb"/>
|
||
<text x="40" y="91" font-family="sans-serif" font-size="16" fill="#111827">Notifications</text>
|
||
<text x="335" y="91" font-family="sans-serif" font-size="20" fill="#9ca3af">›</text>
|
||
|
||
<rect x="20" y="112" width="335" height="56" fill="#ffffff"/>
|
||
<line x1="20" y1="168" x2="355" y2="168" stroke="#e5e7eb"/>
|
||
<text x="40" y="147" font-family="sans-serif" font-size="16" fill="#111827">Privacy</text>
|
||
<text x="335" y="147" font-family="sans-serif" font-size="20" fill="#9ca3af">›</text>
|
||
|
||
<rect x="20" y="168" width="335" height="56" fill="#ffffff"/>
|
||
<text x="40" y="203" font-family="sans-serif" font-size="16" fill="#111827">Help & Support</text>
|
||
<text x="335" y="203" font-family="sans-serif" font-size="20" fill="#9ca3af">›</text>
|
||
</g>
|
||
|
||
<!-- Logout button -->
|
||
<rect x="40" y="580" width="295" height="48" rx="8" fill="none" stroke="#ef4444"/>
|
||
<text x="187" y="610" text-anchor="middle" font-family="sans-serif" font-size="16" fill="#ef4444">Log Out</text>
|
||
|
||
<!-- Tab bar -->
|
||
<rect x="0" y="730" width="375" height="82" fill="#ffffff" stroke="#e5e7eb"/>
|
||
<text x="62" y="770" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#9ca3af">Home</text>
|
||
<text x="145" y="770" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#9ca3af">Search</text>
|
||
<text x="230" y="770" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#3b82f6">Profile</text>
|
||
<text x="313" y="770" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#9ca3af">Settings</text>
|
||
</svg>'''
|
||
},
|
||
},
|
||
'diagrams': {
|
||
'Simple Flowchart': {
|
||
'description': 'Basic flowchart with shapes and arrows',
|
||
'code': '''<?xml version="1.0" encoding="UTF-8"?>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 400" width="600" height="400">
|
||
<defs>
|
||
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||
<polygon points="0 0, 10 3.5, 0 7" fill="#374151"/>
|
||
</marker>
|
||
</defs>
|
||
|
||
<rect width="100%" height="100%" fill="#ffffff"/>
|
||
|
||
<!-- Start (oval) -->
|
||
<ellipse cx="300" cy="40" rx="60" ry="25" fill="#10b981" stroke="#059669" stroke-width="2"/>
|
||
<text x="300" y="46" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#ffffff">Start</text>
|
||
|
||
<!-- Arrow down -->
|
||
<line x1="300" y1="65" x2="300" y2="100" stroke="#374151" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||
|
||
<!-- Process box -->
|
||
<rect x="220" y="110" width="160" height="50" rx="4" fill="#3b82f6" stroke="#2563eb" stroke-width="2"/>
|
||
<text x="300" y="140" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#ffffff">Process Data</text>
|
||
|
||
<!-- Arrow down -->
|
||
<line x1="300" y1="160" x2="300" y2="195" stroke="#374151" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||
|
||
<!-- Decision diamond -->
|
||
<polygon points="300,200 380,250 300,300 220,250" fill="#fbbf24" stroke="#d97706" stroke-width="2"/>
|
||
<text x="300" y="255" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#111827">Valid?</text>
|
||
|
||
<!-- Yes path -->
|
||
<line x1="380" y1="250" x2="450" y2="250" stroke="#374151" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||
<text x="410" y="240" font-family="sans-serif" font-size="12" fill="#374151">Yes</text>
|
||
<rect x="460" y="225" width="100" height="50" rx="4" fill="#10b981" stroke="#059669" stroke-width="2"/>
|
||
<text x="510" y="255" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#ffffff">Save</text>
|
||
|
||
<!-- No path -->
|
||
<line x1="220" y1="250" x2="150" y2="250" stroke="#374151" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||
<text x="180" y="240" font-family="sans-serif" font-size="12" fill="#374151">No</text>
|
||
<rect x="40" y="225" width="100" height="50" rx="4" fill="#ef4444" stroke="#dc2626" stroke-width="2"/>
|
||
<text x="90" y="255" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#ffffff">Error</text>
|
||
|
||
<!-- End -->
|
||
<line x1="300" y1="300" x2="300" y2="340" stroke="#374151" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||
<ellipse cx="300" cy="365" rx="60" ry="25" fill="#6b7280" stroke="#4b5563" stroke-width="2"/>
|
||
<text x="300" y="371" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#ffffff">End</text>
|
||
</svg>'''
|
||
},
|
||
'System Architecture': {
|
||
'description': 'Simple system architecture diagram',
|
||
'code': '''<?xml version="1.0" encoding="UTF-8"?>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 500" width="800" height="500">
|
||
<defs>
|
||
<marker id="arrow" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||
<polygon points="0 0, 10 3.5, 0 7" fill="#6b7280"/>
|
||
</marker>
|
||
</defs>
|
||
|
||
<rect width="100%" height="100%" fill="#f9fafb"/>
|
||
|
||
<!-- Title -->
|
||
<text x="400" y="30" text-anchor="middle" font-family="sans-serif" font-size="18" font-weight="bold" fill="#111827">System Architecture</text>
|
||
|
||
<!-- Client layer -->
|
||
<rect x="50" y="60" width="700" height="80" rx="8" fill="none" stroke="#d1d5db" stroke-dasharray="5,5"/>
|
||
<text x="70" y="85" font-family="sans-serif" font-size="12" fill="#6b7280">Client Layer</text>
|
||
|
||
<rect x="100" y="90" width="120" height="40" rx="4" fill="#dbeafe" stroke="#3b82f6"/>
|
||
<text x="160" y="115" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#1e40af">Web App</text>
|
||
|
||
<rect x="250" y="90" width="120" height="40" rx="4" fill="#dbeafe" stroke="#3b82f6"/>
|
||
<text x="310" y="115" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#1e40af">Mobile App</text>
|
||
|
||
<rect x="400" y="90" width="120" height="40" rx="4" fill="#dbeafe" stroke="#3b82f6"/>
|
||
<text x="460" y="115" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#1e40af">Desktop App</text>
|
||
|
||
<!-- Arrows to API Gateway -->
|
||
<line x1="160" y1="130" x2="400" y2="190" stroke="#6b7280" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||
<line x1="310" y1="130" x2="400" y2="190" stroke="#6b7280" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||
<line x1="460" y1="130" x2="400" y2="190" stroke="#6b7280" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||
|
||
<!-- API Gateway -->
|
||
<rect x="300" y="190" width="200" height="50" rx="4" fill="#fef3c7" stroke="#f59e0b"/>
|
||
<text x="400" y="220" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#92400e">API Gateway</text>
|
||
|
||
<!-- Arrow to services -->
|
||
<line x1="400" y1="240" x2="400" y2="280" stroke="#6b7280" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||
|
||
<!-- Services layer -->
|
||
<rect x="50" y="280" width="700" height="100" rx="8" fill="none" stroke="#d1d5db" stroke-dasharray="5,5"/>
|
||
<text x="70" y="305" font-family="sans-serif" font-size="12" fill="#6b7280">Microservices</text>
|
||
|
||
<rect x="80" y="320" width="130" height="45" rx="4" fill="#d1fae5" stroke="#10b981"/>
|
||
<text x="145" y="348" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#065f46">Auth Service</text>
|
||
|
||
<rect x="235" y="320" width="130" height="45" rx="4" fill="#d1fae5" stroke="#10b981"/>
|
||
<text x="300" y="348" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#065f46">User Service</text>
|
||
|
||
<rect x="390" y="320" width="130" height="45" rx="4" fill="#d1fae5" stroke="#10b981"/>
|
||
<text x="455" y="348" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#065f46">Order Service</text>
|
||
|
||
<rect x="545" y="320" width="130" height="45" rx="4" fill="#d1fae5" stroke="#10b981"/>
|
||
<text x="610" y="348" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#065f46">Payment Service</text>
|
||
|
||
<!-- Data layer -->
|
||
<rect x="50" y="410" width="700" height="70" rx="8" fill="none" stroke="#d1d5db" stroke-dasharray="5,5"/>
|
||
<text x="70" y="435" font-family="sans-serif" font-size="12" fill="#6b7280">Data Layer</text>
|
||
|
||
<!-- Databases -->
|
||
<ellipse cx="200" cy="455" rx="60" ry="20" fill="#fce7f3" stroke="#ec4899"/>
|
||
<text x="200" y="460" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9d174d">PostgreSQL</text>
|
||
|
||
<ellipse cx="400" cy="455" rx="60" ry="20" fill="#fce7f3" stroke="#ec4899"/>
|
||
<text x="400" y="460" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9d174d">Redis Cache</text>
|
||
|
||
<ellipse cx="600" cy="455" rx="60" ry="20" fill="#fce7f3" stroke="#ec4899"/>
|
||
<text x="600" y="460" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9d174d">MongoDB</text>
|
||
|
||
<!-- Arrows from services to databases -->
|
||
<line x1="145" y1="365" x2="190" y2="435" stroke="#6b7280" stroke-width="1" marker-end="url(#arrow)"/>
|
||
<line x1="300" y1="365" x2="395" y2="435" stroke="#6b7280" stroke-width="1" marker-end="url(#arrow)"/>
|
||
<line x1="610" y1="365" x2="600" y2="435" stroke="#6b7280" stroke-width="1" marker-end="url(#arrow)"/>
|
||
</svg>'''
|
||
},
|
||
},
|
||
'basic': {
|
||
'Shapes Gallery': {
|
||
'description': 'Common SVG shapes reference',
|
||
'code': '''<?xml version="1.0" encoding="UTF-8"?>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 400" width="600" height="400">
|
||
<rect width="100%" height="100%" fill="#f9fafb"/>
|
||
|
||
<text x="300" y="30" text-anchor="middle" font-family="sans-serif" font-size="18" font-weight="bold" fill="#111827">SVG Shapes Reference</text>
|
||
|
||
<!-- Rectangle -->
|
||
<rect x="50" y="60" width="120" height="80" rx="8" fill="#3b82f6" stroke="#1d4ed8" stroke-width="2"/>
|
||
<text x="110" y="170" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#374151">Rectangle</text>
|
||
|
||
<!-- Circle -->
|
||
<circle cx="280" cy="100" r="45" fill="#10b981" stroke="#059669" stroke-width="2"/>
|
||
<text x="280" y="170" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#374151">Circle</text>
|
||
|
||
<!-- Ellipse -->
|
||
<ellipse cx="450" cy="100" rx="70" ry="40" fill="#f59e0b" stroke="#d97706" stroke-width="2"/>
|
||
<text x="450" y="170" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#374151">Ellipse</text>
|
||
|
||
<!-- Line -->
|
||
<line x1="50" y1="220" x2="170" y2="280" stroke="#6366f1" stroke-width="3"/>
|
||
<text x="110" y="310" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#374151">Line</text>
|
||
|
||
<!-- Polygon (triangle) -->
|
||
<polygon points="280,200 330,280 230,280" fill="#ec4899" stroke="#be185d" stroke-width="2"/>
|
||
<text x="280" y="310" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#374151">Polygon</text>
|
||
|
||
<!-- Path (curve) -->
|
||
<path d="M 380 280 Q 450 180 520 280" fill="none" stroke="#8b5cf6" stroke-width="3"/>
|
||
<text x="450" y="310" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#374151">Path (Curve)</text>
|
||
|
||
<!-- Text -->
|
||
<text x="110" y="370" text-anchor="middle" font-family="sans-serif" font-size="24" font-weight="bold" fill="#111827">Text</text>
|
||
<text x="110" y="390" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#374151">Text Element</text>
|
||
|
||
<!-- Polyline -->
|
||
<polyline points="230,330 260,380 290,340 320,370" fill="none" stroke="#14b8a6" stroke-width="3"/>
|
||
<text x="280" y="390" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#374151">Polyline</text>
|
||
|
||
<!-- Group with transform -->
|
||
<g transform="translate(450, 350)">
|
||
<rect x="-30" y="-20" width="60" height="40" fill="#f43f5e"/>
|
||
<circle cx="0" cy="0" r="15" fill="#fef2f2"/>
|
||
</g>
|
||
<text x="450" y="390" text-anchor="middle" font-family="sans-serif" font-size="12" fill="#374151">Group</text>
|
||
</svg>'''
|
||
},
|
||
},
|
||
}
|
||
|
||
# Excalidraw Templates (JSON format)
|
||
EXCALIDRAW_TEMPLATES = {
|
||
'diagrams': {
|
||
'Simple Flowchart': {
|
||
'description': 'Hand-drawn flowchart with shapes and arrows',
|
||
'code': '''{
|
||
"type": "excalidraw",
|
||
"version": 2,
|
||
"elements": [
|
||
{"type": "rectangle", "id": "start", "x": 200, "y": 20, "width": 120, "height": 50, "strokeColor": "#087f5b", "backgroundColor": "#c3fae8", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "start-txt", "x": 230, "y": 35, "width": 60, "height": 25, "text": "Start", "fontSize": 20, "strokeColor": "#087f5b"},
|
||
|
||
{"type": "arrow", "id": "a1", "x": 260, "y": 70, "width": 0, "height": 40, "points": [[0, 0], [0, 40]], "strokeColor": "#495057"},
|
||
|
||
{"type": "rectangle", "id": "proc1", "x": 180, "y": 120, "width": 160, "height": 60, "strokeColor": "#1864ab", "backgroundColor": "#d0ebff", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "proc1-txt", "x": 200, "y": 140, "width": 120, "height": 25, "text": "Process", "fontSize": 20, "strokeColor": "#1864ab"},
|
||
|
||
{"type": "arrow", "id": "a2", "x": 260, "y": 180, "width": 0, "height": 40, "points": [[0, 0], [0, 40]], "strokeColor": "#495057"},
|
||
|
||
{"type": "diamond", "id": "decision", "x": 185, "y": 230, "width": 150, "height": 100, "strokeColor": "#e67700", "backgroundColor": "#fff3bf", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "dec-txt", "x": 225, "y": 270, "width": 70, "height": 25, "text": "Valid?", "fontSize": 18, "strokeColor": "#e67700"},
|
||
|
||
{"type": "arrow", "id": "a3-yes", "x": 335, "y": 280, "width": 80, "height": 0, "points": [[0, 0], [80, 0]], "strokeColor": "#2b8a3e"},
|
||
{"type": "text", "id": "yes-lbl", "x": 355, "y": 260, "width": 40, "height": 20, "text": "Yes", "fontSize": 14, "strokeColor": "#2b8a3e"},
|
||
|
||
{"type": "rectangle", "id": "success", "x": 420, "y": 255, "width": 100, "height": 50, "strokeColor": "#2b8a3e", "backgroundColor": "#d3f9d8", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "succ-txt", "x": 445, "y": 270, "width": 50, "height": 25, "text": "Done", "fontSize": 18, "strokeColor": "#2b8a3e"},
|
||
|
||
{"type": "arrow", "id": "a3-no", "x": 185, "y": 280, "width": -80, "height": 0, "points": [[0, 0], [-80, 0]], "strokeColor": "#c92a2a"},
|
||
{"type": "text", "id": "no-lbl", "x": 130, "y": 260, "width": 40, "height": 20, "text": "No", "fontSize": 14, "strokeColor": "#c92a2a"},
|
||
|
||
{"type": "rectangle", "id": "error", "x": 0, "y": 255, "width": 100, "height": 50, "strokeColor": "#c92a2a", "backgroundColor": "#ffe3e3", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "err-txt", "x": 25, "y": 270, "width": 50, "height": 25, "text": "Error", "fontSize": 18, "strokeColor": "#c92a2a"}
|
||
],
|
||
"appState": {"viewBackgroundColor": "#ffffff"}
|
||
}'''
|
||
},
|
||
'Mind Map': {
|
||
'description': 'Simple mind map with central topic',
|
||
'code': '''{
|
||
"type": "excalidraw",
|
||
"version": 2,
|
||
"elements": [
|
||
{"type": "ellipse", "id": "center", "x": 300, "y": 200, "width": 160, "height": 80, "strokeColor": "#1864ab", "backgroundColor": "#d0ebff", "fillStyle": "solid", "roughness": 1, "strokeWidth": 2},
|
||
{"type": "text", "id": "center-txt", "x": 335, "y": 230, "width": 90, "height": 30, "text": "Main Topic", "fontSize": 20, "strokeColor": "#1864ab"},
|
||
|
||
{"type": "line", "id": "l1", "x": 380, "y": 200, "width": 100, "height": -80, "points": [[0, 0], [100, -80]], "strokeColor": "#495057"},
|
||
{"type": "rectangle", "id": "t1", "x": 480, "y": 80, "width": 120, "height": 50, "strokeColor": "#087f5b", "backgroundColor": "#c3fae8", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "t1-txt", "x": 505, "y": 95, "width": 70, "height": 25, "text": "Topic 1", "fontSize": 16, "strokeColor": "#087f5b"},
|
||
|
||
{"type": "line", "id": "l2", "x": 460, "y": 240, "width": 80, "height": 0, "points": [[0, 0], [80, 0]], "strokeColor": "#495057"},
|
||
{"type": "rectangle", "id": "t2", "x": 540, "y": 215, "width": 120, "height": 50, "strokeColor": "#e67700", "backgroundColor": "#fff3bf", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "t2-txt", "x": 565, "y": 230, "width": 70, "height": 25, "text": "Topic 2", "fontSize": 16, "strokeColor": "#e67700"},
|
||
|
||
{"type": "line", "id": "l3", "x": 380, "y": 280, "width": 100, "height": 80, "points": [[0, 0], [100, 80]], "strokeColor": "#495057"},
|
||
{"type": "rectangle", "id": "t3", "x": 480, "y": 350, "width": 120, "height": 50, "strokeColor": "#862e9c", "backgroundColor": "#f3d9fa", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "t3-txt", "x": 505, "y": 365, "width": 70, "height": 25, "text": "Topic 3", "fontSize": 16, "strokeColor": "#862e9c"},
|
||
|
||
{"type": "line", "id": "l4", "x": 300, "y": 240, "width": -80, "height": 60, "points": [[0, 0], [-80, 60]], "strokeColor": "#495057"},
|
||
{"type": "rectangle", "id": "t4", "x": 100, "y": 290, "width": 120, "height": 50, "strokeColor": "#c92a2a", "backgroundColor": "#ffe3e3", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "t4-txt", "x": 125, "y": 305, "width": 70, "height": 25, "text": "Topic 4", "fontSize": 16, "strokeColor": "#c92a2a"}
|
||
],
|
||
"appState": {"viewBackgroundColor": "#ffffff"}
|
||
}'''
|
||
},
|
||
},
|
||
'wireframes': {
|
||
'Login Sketch': {
|
||
'description': 'Hand-drawn login form sketch',
|
||
'code': '''{
|
||
"type": "excalidraw",
|
||
"version": 2,
|
||
"elements": [
|
||
{"type": "rectangle", "id": "card", "x": 100, "y": 50, "width": 280, "height": 350, "strokeColor": "#495057", "backgroundColor": "#f8f9fa", "fillStyle": "solid", "roughness": 1, "strokeWidth": 2},
|
||
|
||
{"type": "ellipse", "id": "logo", "x": 200, "y": 80, "width": 80, "height": 80, "strokeColor": "#1864ab", "backgroundColor": "#d0ebff", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "logo-txt", "x": 220, "y": 110, "width": 40, "height": 25, "text": "Logo", "fontSize": 14, "strokeColor": "#1864ab"},
|
||
|
||
{"type": "text", "id": "title", "x": 175, "y": 180, "width": 130, "height": 30, "text": "Welcome Back", "fontSize": 20, "strokeColor": "#212529"},
|
||
|
||
{"type": "rectangle", "id": "email", "x": 130, "y": 220, "width": 220, "height": 40, "strokeColor": "#adb5bd", "backgroundColor": "#ffffff", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "email-txt", "x": 145, "y": 233, "width": 50, "height": 20, "text": "Email...", "fontSize": 14, "strokeColor": "#adb5bd"},
|
||
|
||
{"type": "rectangle", "id": "pass", "x": 130, "y": 275, "width": 220, "height": 40, "strokeColor": "#adb5bd", "backgroundColor": "#ffffff", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "pass-txt", "x": 145, "y": 288, "width": 70, "height": 20, "text": "Password...", "fontSize": 14, "strokeColor": "#adb5bd"},
|
||
|
||
{"type": "rectangle", "id": "btn", "x": 130, "y": 335, "width": 220, "height": 45, "strokeColor": "#1864ab", "backgroundColor": "#339af0", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "btn-txt", "x": 200, "y": 350, "width": 80, "height": 20, "text": "Sign In", "fontSize": 16, "strokeColor": "#ffffff"}
|
||
],
|
||
"appState": {"viewBackgroundColor": "#ffffff"}
|
||
}'''
|
||
},
|
||
'Mobile Screen': {
|
||
'description': 'Hand-drawn mobile app screen',
|
||
'code': '''{
|
||
"type": "excalidraw",
|
||
"version": 2,
|
||
"elements": [
|
||
{"type": "rectangle", "id": "phone", "x": 100, "y": 20, "width": 240, "height": 480, "strokeColor": "#212529", "backgroundColor": "#f8f9fa", "fillStyle": "solid", "roughness": 1, "strokeWidth": 3},
|
||
|
||
{"type": "rectangle", "id": "statusbar", "x": 100, "y": 20, "width": 240, "height": 30, "strokeColor": "#212529", "backgroundColor": "#e9ecef", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "time", "x": 195, "y": 30, "width": 50, "height": 20, "text": "9:41", "fontSize": 14, "strokeColor": "#212529"},
|
||
|
||
{"type": "rectangle", "id": "header", "x": 100, "y": 50, "width": 240, "height": 50, "strokeColor": "#1864ab", "backgroundColor": "#339af0", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "header-txt", "x": 180, "y": 68, "width": 80, "height": 20, "text": "My App", "fontSize": 18, "strokeColor": "#ffffff"},
|
||
|
||
{"type": "rectangle", "id": "card1", "x": 115, "y": 115, "width": 210, "height": 80, "strokeColor": "#adb5bd", "backgroundColor": "#ffffff", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "card1-txt", "x": 130, "y": 140, "width": 100, "height": 20, "text": "Item 1", "fontSize": 16, "strokeColor": "#212529"},
|
||
|
||
{"type": "rectangle", "id": "card2", "x": 115, "y": 210, "width": 210, "height": 80, "strokeColor": "#adb5bd", "backgroundColor": "#ffffff", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "card2-txt", "x": 130, "y": 235, "width": 100, "height": 20, "text": "Item 2", "fontSize": 16, "strokeColor": "#212529"},
|
||
|
||
{"type": "rectangle", "id": "card3", "x": 115, "y": 305, "width": 210, "height": 80, "strokeColor": "#adb5bd", "backgroundColor": "#ffffff", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "card3-txt", "x": 130, "y": 330, "width": 100, "height": 20, "text": "Item 3", "fontSize": 16, "strokeColor": "#212529"},
|
||
|
||
{"type": "rectangle", "id": "tabbar", "x": 100, "y": 450, "width": 240, "height": 50, "strokeColor": "#212529", "backgroundColor": "#ffffff", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "tab1", "x": 130, "y": 468, "width": 40, "height": 15, "text": "Home", "fontSize": 12, "strokeColor": "#1864ab"},
|
||
{"type": "text", "id": "tab2", "x": 200, "y": 468, "width": 40, "height": 15, "text": "Search", "fontSize": 12, "strokeColor": "#868e96"},
|
||
{"type": "text", "id": "tab3", "x": 275, "y": 468, "width": 40, "height": 15, "text": "Profile", "fontSize": 12, "strokeColor": "#868e96"}
|
||
],
|
||
"appState": {"viewBackgroundColor": "#ffffff"}
|
||
}'''
|
||
},
|
||
},
|
||
'basic': {
|
||
'Shapes Demo': {
|
||
'description': 'Basic shapes in Excalidraw style',
|
||
'code': '''{
|
||
"type": "excalidraw",
|
||
"version": 2,
|
||
"elements": [
|
||
{"type": "rectangle", "id": "rect", "x": 50, "y": 50, "width": 120, "height": 80, "strokeColor": "#1864ab", "backgroundColor": "#d0ebff", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "rect-lbl", "x": 75, "y": 150, "width": 70, "height": 20, "text": "Rectangle", "fontSize": 12, "strokeColor": "#495057"},
|
||
|
||
{"type": "ellipse", "id": "ellipse", "x": 220, "y": 50, "width": 100, "height": 80, "strokeColor": "#087f5b", "backgroundColor": "#c3fae8", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "ell-lbl", "x": 245, "y": 150, "width": 50, "height": 20, "text": "Ellipse", "fontSize": 12, "strokeColor": "#495057"},
|
||
|
||
{"type": "diamond", "id": "diamond", "x": 370, "y": 40, "width": 100, "height": 100, "strokeColor": "#e67700", "backgroundColor": "#fff3bf", "fillStyle": "solid", "roughness": 1},
|
||
{"type": "text", "id": "dia-lbl", "x": 390, "y": 150, "width": 60, "height": 20, "text": "Diamond", "fontSize": 12, "strokeColor": "#495057"},
|
||
|
||
{"type": "line", "id": "line", "x": 50, "y": 200, "width": 100, "height": 60, "points": [[0, 0], [100, 60]], "strokeColor": "#862e9c", "strokeWidth": 2, "roughness": 1},
|
||
{"type": "text", "id": "line-lbl", "x": 75, "y": 280, "width": 50, "height": 20, "text": "Line", "fontSize": 12, "strokeColor": "#495057"},
|
||
|
||
{"type": "arrow", "id": "arrow", "x": 220, "y": 200, "width": 100, "height": 60, "points": [[0, 0], [100, 60]], "strokeColor": "#c92a2a", "strokeWidth": 2, "roughness": 1},
|
||
{"type": "text", "id": "arr-lbl", "x": 250, "y": 280, "width": 50, "height": 20, "text": "Arrow", "fontSize": 12, "strokeColor": "#495057"},
|
||
|
||
{"type": "text", "id": "text-demo", "x": 370, "y": 220, "width": 100, "height": 40, "text": "Text\\nElement", "fontSize": 20, "strokeColor": "#212529"},
|
||
{"type": "text", "id": "txt-lbl", "x": 395, "y": 280, "width": 50, "height": 20, "text": "Text", "fontSize": 12, "strokeColor": "#495057"}
|
||
],
|
||
"appState": {"viewBackgroundColor": "#ffffff"}
|
||
}'''
|
||
},
|
||
},
|
||
}
|
||
|
||
# Combined templates dict for backwards compatibility
|
||
TEMPLATES = PLANTUML_TEMPLATES
|
||
|
||
|
||
def get_template_categories(format_type: str = 'plantuml') -> list:
|
||
"""Get list of template categories for a format."""
|
||
templates = get_templates_for_format(format_type)
|
||
return list(templates.keys())
|
||
|
||
|
||
def get_templates_for_format(format_type: str) -> dict:
|
||
"""Get all templates for a format type."""
|
||
format_map = {
|
||
'plantuml': PLANTUML_TEMPLATES,
|
||
'mermaid': MERMAID_TEMPLATES,
|
||
'openscad': OPENSCAD_TEMPLATES,
|
||
'code': CODE_TEMPLATES,
|
||
'svg': SVG_TEMPLATES,
|
||
'excalidraw': EXCALIDRAW_TEMPLATES,
|
||
}
|
||
return format_map.get(format_type, PLANTUML_TEMPLATES)
|
||
|
||
|
||
def get_templates_for_category(category: str, format_type: str = 'plantuml') -> dict:
|
||
"""Get all templates for a diagram type category."""
|
||
templates = get_templates_for_format(format_type)
|
||
return templates.get(category, {})
|
||
|
||
|
||
def get_template(category: str, name: str, format_type: str = 'plantuml') -> dict:
|
||
"""Get a specific template by category and name."""
|
||
templates = get_templates_for_format(format_type)
|
||
return templates.get(category, {}).get(name, {})
|
||
|
||
|
||
def get_all_templates(format_type: str = 'plantuml') -> list:
|
||
"""Get all templates as a flat list with category info."""
|
||
result = []
|
||
templates = get_templates_for_format(format_type)
|
||
for category, category_templates in templates.items():
|
||
for name, template in category_templates.items():
|
||
result.append({
|
||
'category': category,
|
||
'name': name,
|
||
'description': template.get('description', ''),
|
||
'code': template.get('code', ''),
|
||
})
|
||
return result
|