citadel-ai 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +91 -0
- package/LICENSE +5 -0
- package/README.md +254 -0
- package/bin/citadel.js +2 -0
- package/dist/agents/registry.d.ts +16 -0
- package/dist/agents/registry.js +1108 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/cli/ide-rules.d.ts +5 -0
- package/dist/cli/ide-rules.js +176 -0
- package/dist/cli/ide-rules.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +59 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +1 -0
- package/dist/cli/init.js +110 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/run.d.ts +1 -0
- package/dist/cli/run.js +64 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/core/chinese-wall.d.ts +34 -0
- package/dist/core/chinese-wall.js +62 -0
- package/dist/core/chinese-wall.js.map +1 -0
- package/dist/core/gates.d.ts +19 -0
- package/dist/core/gates.js +38 -0
- package/dist/core/gates.js.map +1 -0
- package/dist/core/loops.d.ts +20 -0
- package/dist/core/loops.js +83 -0
- package/dist/core/loops.js.map +1 -0
- package/dist/core/memory.d.ts +23 -0
- package/dist/core/memory.js +116 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/orchestrator.d.ts +22 -0
- package/dist/core/orchestrator.js +234 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/types.d.ts +139 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/provider.d.ts +8 -0
- package/dist/llm/provider.js +84 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/ui/terminal.d.ts +16 -0
- package/dist/ui/terminal.js +71 -0
- package/dist/ui/terminal.js.map +1 -0
- package/package.json +40 -0
- package/templates/.citadel/citadel.config.json +1 -0
- package/templates/.citadel/gates/gate-0-inception.json +1 -0
- package/templates/.citadel/gates/gate-1-predesign.json +1 -0
- package/templates/.citadel/gates/gate-2-prebuild.json +1 -0
- package/templates/.citadel/gates/gate-3-preship.json +1 -0
- package/templates/.citadel/gates/gate-4-postdeploy.json +1 -0
- package/templates/.citadel/memory/decisions.json +1 -0
- package/templates/.citadel/memory/errors.json +1 -0
- package/templates/.citadel/memory/project.json +1 -0
- package/templates/.citadel/memory/session.json +1 -0
- package/templates/.citadel/specs/adr.md +1 -0
- package/templates/.citadel/specs/data-model.md +1 -0
- package/templates/.citadel/specs/growth.md +1 -0
- package/templates/.citadel/specs/prd.md +1 -0
- package/templates/.citadel/specs/security.md +1 -0
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Contributing to CITADEL
|
|
2
|
+
|
|
3
|
+
First off, thanks for wanting to contribute! CITADEL is built for vibe coders — people who build with AI. You don't need to be a traditional developer to help.
|
|
4
|
+
|
|
5
|
+
## How to Contribute
|
|
6
|
+
|
|
7
|
+
### Reporting Bugs
|
|
8
|
+
|
|
9
|
+
Open an issue with:
|
|
10
|
+
- What you expected to happen
|
|
11
|
+
- What actually happened
|
|
12
|
+
- Steps to reproduce
|
|
13
|
+
- Your Node.js version (`node --version`)
|
|
14
|
+
- Your OS
|
|
15
|
+
|
|
16
|
+
### Suggesting Agents
|
|
17
|
+
|
|
18
|
+
Want a new agent in CITADEL? Open an issue with:
|
|
19
|
+
- **Agent name & role** — What does it do?
|
|
20
|
+
- **Inspiration** — Which legendary dev/designer/thinker inspires it?
|
|
21
|
+
- **Philosophy** — One line that captures its worldview
|
|
22
|
+
- **Team** — Which C-suite does it report to? (CTO, CPO, CGO, CISO, CDO)
|
|
23
|
+
- **Level** — Maker or Checker?
|
|
24
|
+
- **Rules** — 3-5 immutable rules it follows
|
|
25
|
+
|
|
26
|
+
### Submitting Code
|
|
27
|
+
|
|
28
|
+
1. Fork the repo
|
|
29
|
+
2. Create a branch: `git checkout -b feat/your-feature`
|
|
30
|
+
3. Make your changes
|
|
31
|
+
4. Run the build: `npm run build`
|
|
32
|
+
5. Test it: `node dist/cli/index.js agents` (should show 42 agents)
|
|
33
|
+
6. Commit: `git commit -m "feat: description"`
|
|
34
|
+
7. Push: `git push origin feat/your-feature`
|
|
35
|
+
8. Open a Pull Request
|
|
36
|
+
|
|
37
|
+
### Commit Convention
|
|
38
|
+
|
|
39
|
+
We use [Conventional Commits](https://www.conventionalcommits.org/):
|
|
40
|
+
|
|
41
|
+
- `feat:` — New feature or agent
|
|
42
|
+
- `fix:` — Bug fix
|
|
43
|
+
- `docs:` — Documentation only
|
|
44
|
+
- `refactor:` — Code change that doesn't add features or fix bugs
|
|
45
|
+
- `test:` — Adding tests
|
|
46
|
+
- `chore:` — Maintenance, deps, CI
|
|
47
|
+
|
|
48
|
+
### Code Standards
|
|
49
|
+
|
|
50
|
+
CITADEL enforces its own standards:
|
|
51
|
+
|
|
52
|
+
- TypeScript strict mode
|
|
53
|
+
- Max 200 lines per file
|
|
54
|
+
- Max 30 lines per function
|
|
55
|
+
- Meaningful names — no abbreviations
|
|
56
|
+
- Every public function should be documented
|
|
57
|
+
|
|
58
|
+
### Project Structure
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
src/
|
|
62
|
+
├── agents/registry.ts # All 42 agent definitions
|
|
63
|
+
├── core/
|
|
64
|
+
│ ├── orchestrator.ts # ATLAS brain
|
|
65
|
+
│ ├── memory.ts # Persistent memory
|
|
66
|
+
│ ├── gates.ts # Quality gates
|
|
67
|
+
│ ├── loops.ts # Iteration loops
|
|
68
|
+
│ ├── chinese-wall.ts # Maker ≠ Checker
|
|
69
|
+
│ └── types.ts # TypeScript types
|
|
70
|
+
├── llm/provider.ts # LLM abstraction
|
|
71
|
+
├── ui/terminal.ts # CLI interface
|
|
72
|
+
└── cli/ # CLI commands
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Development Setup
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
git clone https://github.com/YOUR_USERNAME/citadel-ai.git
|
|
79
|
+
cd citadel-ai
|
|
80
|
+
npm install
|
|
81
|
+
npm run build
|
|
82
|
+
node dist/cli/index.js agents # Should list 42 agents
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Questions?
|
|
86
|
+
|
|
87
|
+
Open a Discussion or Issue. No question is too basic.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
Built with 🏰 by humans who talk to machines.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
Copyright (c) 2026 Citadel Contributors
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
5
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
|
package/README.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# 🏰 CITADEL
|
|
2
|
+
|
|
3
|
+
**Command Intelligence Tower for Architected Development with Enforced Layers**
|
|
4
|
+
|
|
5
|
+
> Enterprise-grade AI development framework. 42 specialized agents. C-suite governance. Chinese Walls. Persistent memory. You talk, they build.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/citadel-ai)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What is CITADEL?
|
|
13
|
+
|
|
14
|
+
CITADEL is an AI-powered development framework where **you never write code**. You describe what you want to build, and a team of 42 specialized AI agents — organized like a real engineering company — designs, builds, reviews, and ships it.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx citadel-ai init
|
|
18
|
+
npx citadel-ai run
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
That's it. You talk. They build.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Why CITADEL?
|
|
26
|
+
|
|
27
|
+
Most AI coding tools are a single brain doing everything. CITADEL is an **organization** with separation of concerns, checks and balances, and enforced quality gates.
|
|
28
|
+
|
|
29
|
+
| Feature | Single AI | CITADEL |
|
|
30
|
+
|---------|-----------|---------|
|
|
31
|
+
| Architecture decisions | Vibes | ADRs reviewed by CTO agent |
|
|
32
|
+
| Security | Hope | CISO with **absolute veto power** |
|
|
33
|
+
| Code quality | Maybe | Chinese Wall: Maker ≠ Checker |
|
|
34
|
+
| Testing | Optional | 80% coverage minimum, test pyramid enforced |
|
|
35
|
+
| Data design | Inline | Schema-first, 3NF minimum, FK on every relationship |
|
|
36
|
+
| Memory | None | 4-layer persistent memory across sessions |
|
|
37
|
+
| Progress | Unknown | 5 mandatory gates with explicit sign-offs |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## The 42 Agents
|
|
42
|
+
|
|
43
|
+
### Command Layer (1)
|
|
44
|
+
|
|
45
|
+
| Agent | Role | Inspiration |
|
|
46
|
+
|-------|------|-------------|
|
|
47
|
+
| ⚡ **ATLAS** | Orchestrator | Andy Grove |
|
|
48
|
+
|
|
49
|
+
### C-Suite (5)
|
|
50
|
+
|
|
51
|
+
| Agent | Role | Inspiration | Superpower |
|
|
52
|
+
|-------|------|-------------|------------|
|
|
53
|
+
| 🏗️ **LINUS** | CTO | Linus Torvalds + Martin Fowler | Architecture, ADRs, tech stack |
|
|
54
|
+
| 🎯 **MARTY** | CPO | Marty Cagan | PRDs, user stories, scope |
|
|
55
|
+
| 📈 **SEAN** | CGO | Sean Ellis + Andrew Chen | Growth, analytics, SEO |
|
|
56
|
+
| 🛡️ **BRUCE** | CISO | Bruce Schneier | **ABSOLUTE VETO POWER** |
|
|
57
|
+
| 🗄️ **MONICA** | CDO | Monica Rogati | Data architecture, AI/ML |
|
|
58
|
+
|
|
59
|
+
### Maker Teams (20 builders)
|
|
60
|
+
|
|
61
|
+
**CTO Team:** ⚙️ UNCLE BOB (Backend) · 🎨 DAN (Frontend) · 📱 STEIPETE (Mobile) · 🚀 KELSEY (DevOps) · 📡 GRACE (API Design) · 🔭 CHARITY (Observability)
|
|
62
|
+
|
|
63
|
+
**CPO Team:** ✏️ JONY (UX) · 📊 TERESA (Analyst) · 📝 STRUNK (Spec Writer) · 📚 RICH (Documentation)
|
|
64
|
+
|
|
65
|
+
**CGO Team:** 📉 DJ PATIL (Analytics) · 🔎 CYRUS (SEO) · 🧬 CHAMATH (Growth)
|
|
66
|
+
|
|
67
|
+
**CISO Team:** 🔐 FILIPPO (Auth) · 🔒 MOXIE (Encryption) · 📋 MAX (Compliance)
|
|
68
|
+
|
|
69
|
+
**CDO Team:** 🏛️ CODD (Data Architect) · 🤖 KARPATHY (ML/AI) · 🧠 HARRISON (Agentic AI) · 🔌 ALEX (MCP)
|
|
70
|
+
|
|
71
|
+
### Checker Teams (16 validators)
|
|
72
|
+
|
|
73
|
+
**CTO Checkers:** 🔍 GUIDO (Code Review) · 🧪 KENT (Tests) · ⚡ BRENDAN (Performance)
|
|
74
|
+
|
|
75
|
+
**CPO Checkers:** 👁️ JAKOB (UX Review) · 📏 RAZOR (Scope) · ✅ LISA (Acceptance) · ♿ AARON (Accessibility)
|
|
76
|
+
|
|
77
|
+
**CGO Checkers:** ✔️ NATE (Data Validation) · 🕷️ ALEYDA (SEO Audit) · 🎯 PEEP (Conversion)
|
|
78
|
+
|
|
79
|
+
**CISO Checkers:** ⚔️ CHARLIE (Pentest) · 🔬 WINDOW (Security Audit) · 📜 TRAIL (Audit Trail)
|
|
80
|
+
|
|
81
|
+
**CDO Checkers:** 🧐 DATE (Schema Review) · 🏅 DEMING (Data Quality) · 🔄 FLYWAY (Migration)
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Core Principles
|
|
86
|
+
|
|
87
|
+
### 1. Maker ≠ Checker (Chinese Wall)
|
|
88
|
+
|
|
89
|
+
The agent that builds can **never** validate its own work. Enforced at the system level.
|
|
90
|
+
|
|
91
|
+
### 2. CISO Veto Power
|
|
92
|
+
|
|
93
|
+
BRUCE (CISO) can block **any** deployment. No exceptions. Not even from you.
|
|
94
|
+
|
|
95
|
+
### 3. 5 Mandatory Gates
|
|
96
|
+
|
|
97
|
+
| Gate | Name | Blocker |
|
|
98
|
+
|------|------|---------|
|
|
99
|
+
| Gate 0 | **Inception** | All C-levels must sign off |
|
|
100
|
+
| Gate 1 | **Pre-Design** | PRD approved, acceptance criteria complete |
|
|
101
|
+
| Gate 2 | **Pre-Build** | ADR + schema + security review approved |
|
|
102
|
+
| Gate 3 | **Pre-Ship** | All checkers PASS + CISO veto |
|
|
103
|
+
| Gate 4 | **Post-Deploy** | Auto-rollback if critical metrics degrade |
|
|
104
|
+
|
|
105
|
+
### 4. Persistent Memory
|
|
106
|
+
|
|
107
|
+
CITADEL remembers everything across sessions:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
.citadel/
|
|
111
|
+
├── memory/
|
|
112
|
+
│ ├── project.json # Tech stack, architecture, scope
|
|
113
|
+
│ ├── decisions.json # Every ADR, product decision, tradeoff
|
|
114
|
+
│ ├── errors.json # Error history + root causes + fixes
|
|
115
|
+
│ └── session.json # Current state, active agent, gate
|
|
116
|
+
├── gates/
|
|
117
|
+
│ ├── gate-0-inception.json
|
|
118
|
+
│ ├── gate-1-predesign.json
|
|
119
|
+
│ ├── gate-2-prebuild.json
|
|
120
|
+
│ ├── gate-3-preship.json
|
|
121
|
+
│ └── gate-4-postdeploy.json
|
|
122
|
+
└── specs/
|
|
123
|
+
├── prd.md
|
|
124
|
+
├── adr.md
|
|
125
|
+
├── security.md
|
|
126
|
+
└── data-model.md
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 5. Web Research When Stuck
|
|
130
|
+
|
|
131
|
+
If any agent loops more than 2 times on a problem, ATLAS automatically triggers web research.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Quick Start
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Initialize in your project directory
|
|
139
|
+
npx citadel-ai init
|
|
140
|
+
|
|
141
|
+
# Start building
|
|
142
|
+
npx citadel-ai run
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Commands
|
|
146
|
+
|
|
147
|
+
| Command | Description |
|
|
148
|
+
|---------|-------------|
|
|
149
|
+
| `citadel init` | Initialize CITADEL in your project |
|
|
150
|
+
| `citadel run` | Start the interactive build session |
|
|
151
|
+
| `citadel status` | Show current phase and gate progress |
|
|
152
|
+
| `citadel agents` | List all 42 agents |
|
|
153
|
+
|
|
154
|
+
### In-Session Commands
|
|
155
|
+
|
|
156
|
+
| Command | Description |
|
|
157
|
+
|---------|-------------|
|
|
158
|
+
| `status` | Show phase, gate, and progress |
|
|
159
|
+
| `advance` | Move to next phase (if gate passed) |
|
|
160
|
+
| `help` | Show available agents and options |
|
|
161
|
+
| `exit` | Save and quit |
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## How It Works
|
|
166
|
+
|
|
167
|
+
1. **You describe** what you want to build in plain language
|
|
168
|
+
2. **ATLAS** (orchestrator) routes your request to the right expert
|
|
169
|
+
3. **C-Suite agents** make strategic decisions (architecture, product, security, data, growth)
|
|
170
|
+
4. **Maker agents** build (backend, frontend, mobile, auth, data, etc.)
|
|
171
|
+
5. **Checker agents** validate (code review, tests, pentest, UX audit, etc.)
|
|
172
|
+
6. **Gates enforce** quality at every phase transition
|
|
173
|
+
7. **Memory persists** decisions, errors, and context across sessions
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## LLM Support
|
|
178
|
+
|
|
179
|
+
CITADEL works with:
|
|
180
|
+
|
|
181
|
+
- **Anthropic Claude** (recommended) — `claude-sonnet-4-20250514`
|
|
182
|
+
- **OpenAI GPT-4o** — `gpt-4o`
|
|
183
|
+
|
|
184
|
+
Set your API key:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
188
|
+
# or
|
|
189
|
+
export OPENAI_API_KEY=sk-...
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Coding DNA
|
|
195
|
+
|
|
196
|
+
Every agent carries these principles in their DNA:
|
|
197
|
+
|
|
198
|
+
1. **Code is for Humans First** — Readability over cleverness
|
|
199
|
+
2. **Simplicity Over Cleverness** — The simplest solution that works
|
|
200
|
+
3. **Measurement Before Optimization** — Profile, don't guess
|
|
201
|
+
4. **Single Responsibility** — One function, one job
|
|
202
|
+
5. **Test-Driven Development** — Red → Green → Refactor
|
|
203
|
+
6. **Low Coupling, High Cohesion** — Modules that stand alone
|
|
204
|
+
7. **Evolutionary Design** — Architecture that adapts
|
|
205
|
+
|
|
206
|
+
### Anti-Patterns Registry (Auto-Detected)
|
|
207
|
+
|
|
208
|
+
God Objects · Primitive Obsession · Long Parameter Lists · Magic Numbers · Error Swallowing · Callback Hell · Framework Coupling · Speculative Generality
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Architecture
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
citadel-ai/
|
|
216
|
+
├── src/
|
|
217
|
+
│ ├── agents/
|
|
218
|
+
│ │ └── registry.ts # 42 agent definitions with soul
|
|
219
|
+
│ ├── core/
|
|
220
|
+
│ │ ├── orchestrator.ts # ATLAS brain — routing & flow
|
|
221
|
+
│ │ ├── memory.ts # 4-layer persistent memory
|
|
222
|
+
│ │ ├── gates.ts # 5 mandatory quality gates
|
|
223
|
+
│ │ ├── loops.ts # Design/Build/Security/Debug loops
|
|
224
|
+
│ │ ├── chinese-wall.ts # Maker ≠ Checker enforcement
|
|
225
|
+
│ │ └── types.ts # TypeScript types
|
|
226
|
+
│ ├── llm/
|
|
227
|
+
│ │ └── provider.ts # Anthropic/OpenAI abstraction
|
|
228
|
+
│ ├── ui/
|
|
229
|
+
│ │ └── terminal.ts # CLI interface
|
|
230
|
+
│ └── cli/
|
|
231
|
+
│ ├── init.ts # npx citadel init
|
|
232
|
+
│ ├── run.ts # npx citadel run
|
|
233
|
+
│ └── index.ts # CLI router
|
|
234
|
+
├── bin/
|
|
235
|
+
│ └── citadel.js # Entry point
|
|
236
|
+
├── templates/ # .citadel scaffolding
|
|
237
|
+
└── package.json
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Contributing
|
|
243
|
+
|
|
244
|
+
CITADEL is built for vibe coders — people who build with AI without being traditional developers. If that's you, you're welcome here.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## License
|
|
249
|
+
|
|
250
|
+
MIT
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
Built with 🏰 by humans who talk to machines.
|
package/bin/citadel.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AgentDefinition, AgentLevel, TeamId } from '../core/types.js';
|
|
2
|
+
export declare const AGENT_REGISTRY: Map<string, AgentDefinition>;
|
|
3
|
+
export declare function getAgent(id: string): AgentDefinition | undefined;
|
|
4
|
+
export declare function getAgentsByTeam(team: TeamId | 'command'): AgentDefinition[];
|
|
5
|
+
export declare function getAgentsByLevel(level: AgentLevel): AgentDefinition[];
|
|
6
|
+
export declare function getMakersByTeam(team: TeamId): AgentDefinition[];
|
|
7
|
+
export declare function getCheckersByTeam(team: TeamId): AgentDefinition[];
|
|
8
|
+
export declare function getCSuiteAgents(): AgentDefinition[];
|
|
9
|
+
export declare function getAllAgentIds(): string[];
|
|
10
|
+
export declare function getAgentCount(): {
|
|
11
|
+
total: number;
|
|
12
|
+
command: number;
|
|
13
|
+
csuite: number;
|
|
14
|
+
makers: number;
|
|
15
|
+
checkers: number;
|
|
16
|
+
};
|