{"uuid": "928db57c-a7a2-4990-bf6f-901dd413fe51", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2024-47764", "type": "seen", "source": "https://gist.github.com/Adcbda/3e82259b6deb6a426fbb5c89ed5ded87", "content": "\n\n\n\n\nexpress \u2014 Wiki\n\n\n\n\n*{margin:0;padding:0;box-sizing:border-box}\n:root{\n  --bg:#ffffff;--sidebar-bg:#f8f9fb;--border:#e5e7eb;\n  --text:#1e293b;--text-muted:#64748b;--primary:#2563eb;\n  --primary-soft:#eff6ff;--hover:#f1f5f9;--code-bg:#f1f5f9;\n  --radius:8px;--shadow:0 1px 3px rgba(0,0,0,.08);\n}\nbody{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;\n  line-height:1.65;color:var(--text);background:var(--bg)}\n\n.layout{display:flex;min-height:100vh}\n.sidebar{width:280px;background:var(--sidebar-bg);border-right:1px solid var(--border);\n  position:fixed;top:0;left:0;bottom:0;overflow-y:auto;padding:24px 16px;\n  display:flex;flex-direction:column;z-index:10}\n.content{margin-left:280px;flex:1;padding:48px 64px;max-width:960px}\n\n.sidebar-header{margin-bottom:20px;padding-bottom:16px;border-bottom:1px solid var(--border)}\n.sidebar-title{font-size:16px;font-weight:700;color:var(--text);display:flex;align-items:center;gap:8px}\n.sidebar-title svg{flex-shrink:0}\n.sidebar-meta{font-size:11px;color:var(--text-muted);margin-top:6px}\n.nav-section{margin-bottom:2px}\n.nav-item{display:block;padding:7px 12px;border-radius:var(--radius);cursor:pointer;\n  font-size:13px;color:var(--text);text-decoration:none;transition:all .15s;\n  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.nav-item:hover{background:var(--hover)}\n.nav-item.active{background:var(--primary-soft);color:var(--primary);font-weight:600}\n.nav-item.overview{font-weight:600;margin-bottom:4px}\n.nav-children{padding-left:14px;border-left:1px solid var(--border);margin-left:12px}\n.nav-group-label{font-size:11px;font-weight:600;color:var(--text-muted);\n  text-transform:uppercase;letter-spacing:.5px;padding:12px 12px 4px;user-select:none}\n.sidebar-footer{margin-top:auto;padding-top:16px;border-top:1px solid var(--border);\n  font-size:11px;color:var(--text-muted);text-align:center}\n\n.content h1{font-size:28px;font-weight:700;margin-bottom:8px;line-height:1.3}\n.content h2{font-size:22px;font-weight:600;margin:32px 0 12px;padding-bottom:6px;border-bottom:1px solid var(--border)}\n.content h3{font-size:17px;font-weight:600;margin:24px 0 8px}\n.content h4{font-size:15px;font-weight:600;margin:20px 0 6px}\n.content p{margin:12px 0}\n.content ul,.content ol{margin:12px 0 12px 24px}\n.content li{margin:4px 0}\n.content a{color:var(--primary);text-decoration:none}\n.content a:hover{text-decoration:underline}\n.content blockquote{border-left:3px solid var(--primary);padding:8px 16px;margin:16px 0;\n  background:var(--primary-soft);border-radius:0 var(--radius) var(--radius) 0;\n  color:var(--text-muted);font-size:14px}\n.content code{font-family:'SF Mono',Consolas,'Courier New',monospace;font-size:13px;\n  background:var(--code-bg);padding:2px 6px;border-radius:4px}\n.content pre{background:#1e293b;color:#e2e8f0;border-radius:var(--radius);padding:16px;\n  overflow-x:auto;margin:16px 0}\n.content pre code{background:none;padding:0;font-size:13px;line-height:1.6;color:inherit}\n.content table{border-collapse:collapse;width:100%;margin:16px 0}\n.content th,.content td{border:1px solid var(--border);padding:8px 12px;text-align:left;font-size:14px}\n.content th{background:var(--sidebar-bg);font-weight:600}\n.content img{max-width:100%;border-radius:var(--radius)}\n.content hr{border:none;border-top:1px solid var(--border);margin:32px 0}\n.content .mermaid{margin:20px 0;text-align:center}\n\n.menu-toggle{display:none;position:fixed;top:12px;left:12px;z-index:20;\n  background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);\n  padding:8px 12px;cursor:pointer;font-size:18px;box-shadow:var(--shadow)}\n@media(max-width:768px){\n  .sidebar{transform:translateX(-100%);transition:transform .2s}\n  .sidebar.open{transform:translateX(0);box-shadow:2px 0 12px rgba(0,0,0,.1)}\n  .content{margin-left:0;padding:24px 20px;padding-top:56px}\n  .menu-toggle{display:block}\n}\n.empty-state{text-align:center;padding:80px 20px;color:var(--text-muted)}\n.empty-state h2{font-size:20px;margin-bottom:8px;border:none}\n\n\n\n\n&#9776;\n\n\n\n\n\n\n\n\n\nexpress\n\n\n\n\n\n\n\nGenerated by GitNexus\n\n\n\n\n\nLoading\u2026\n\n\n\nvar PAGES = {\"authentication-sessions\":\"# Authentication &amp; Sessions\\n\\n# Authentication &amp; Sessions Module\\n\\nThis module provides example implementations for authentication and session management in Express applications. It demonstrates multiple approaches: password-based authentication with sessions, cookie-based sessions, and Redis-backed session storage.\\n\\n## Architecture Overview\\n\\n```mermaid\\ngraph TD\\n    A[Client Request] --&gt; B{Session Exists?}\\n    B --&gt;|No| C[Create Session]\\n    B --&gt;|Yes| D[Load Session Data]\\n    C --&gt; E[Route Handler]\\n    D --&gt; E\\n    E --&gt; F{Protected Route?}\\n    F --&gt;|Yes| G[restrict Middleware]\\n    G --&gt; H{Authenticated?}\\n    H --&gt;|No| I[Redirect to Login]\\n    H --&gt;|Yes| J[Process Request]\\n    F --&gt;|No| J\\n```\\n\\n## Core Components\\n\\n### Authentication Example (`examples/auth/`)\\n\\nA complete username/password authentication system with session persistence.\\n\\n#### Key Functions\\n\\n**`authenticate(name, pass, fn)`**\\n\\nValidates user credentials against the in-memory user store.\\n\\n- **Parameters:**\\n  - `name` - Username to authenticate\\n  - `pass` - Plaintext password\\n  - `fn` - Callback `(err, user)` where `user` is `null` on failure\\n- **Behavior:** Retrieves the user by name, then hashes the submitted password with the stored salt. Compares the result against the stored hash.\\n\\n**`restrict(req, res, next)`**\\n\\nMiddleware that protects routes from unauthenticated access.\\n\\n- Sets `req.session.error` and redirects to `/login` if no `req.session.user` exists\\n- Calls `next()` when authentication is present\\n\\n#### Authentication Flow\\n\\n1. **POST /login** receives credentials via `req.body.username` and `req.body.password`\\n2. `authenticate()` verifies credentials using PBKDF2 password hashing\\n3. On success, `req.session.regenerate()` creates a new session (prevents session fixation)\\n4. User object stored in `req.session.user`\\n5. Subsequent requests check `req.session.user` via `restrict` middleware\\n\\n#### Session Configuration\\n\\n```javascript\\napp.use(session({\\n  resave: false,           // Skip saving unmodified sessions\\n  saveUninitialized: false, // Don't create session until data stored\\n  secret: 'shhhh, very secret'\\n}));\\n```\\n\\n#### Password Hashing\\n\\nUses `pbkdf2-password` for secure password storage. When a user is created, a salt is generated and the password is hashed:\\n\\n```javascript\\nhash({ password: 'foobar' }, function (err, pass, salt, hash) {\\n  users.tj.salt = salt;\\n  users.tj.hash = hash;\\n});\\n```\\n\\nDuring authentication, the same salt is applied to the submitted password:\\n\\n```javascript\\nhash({ password: pass, salt: user.salt }, function (err, pass, salt, hash) {\\n  if (hash === user.hash) return fn(null, user);\\n  fn(null, null);\\n});\\n```\\n\\n#### Flash Messages\\n\\nThe session-persisted message middleware extracts `error` and `success` from the session and makes them available in `res.locals.message` for template rendering:\\n\\n```javascript\\napp.use(function(req, res, next){\\n  var err = req.session.error;\\n  var msg = req.session.success;\\n  delete req.session.error;\\n  delete req.session.success;\\n  res.locals.message = '';\\n  if (err) res.locals.message = '\n' + err + '&lt;\\/p&gt;';\\n  if (msg) res.locals.message = '\n' + msg + '&lt;\\/p&gt;';\\n  next();\\n});\\n```\\n\\n---\\n\\n### Cookie Sessions (`examples/cookie-sessions/`)\\n\\nLightweight session storage using client-side cookies via `cookie-session`.\\n\\n```javascript\\napp.use(cookieSession({ secret: 'manny is cool' }));\\n\\napp.get('/', function (req, res) {\\n  req.session.count = (req.session.count || 0) + 1;\\n  res.send('viewed ' + req.session.count + ' times\\\\n');\\n});\\n```\\n\\n**Use case:** Small session data that doesn't require server-side storage. Session data is encrypted and stored in the client cookie.\\n\\n---\\n\\n### Cookie Parser (`examples/cookies/`)\\n\\nDemonstrates reading and writing cookies with `cookie-parser`.\\n\\n**Key operations:**\\n\\n- `req.cookies` - Parsed unsigned cookies\\n- `req.signedCookies` - Parsed signed cookies\\n- `res.cookie(name, value, options)` - Set a cookie\\n- `res.clearCookie(name)` - Remove a cookie\\n\\n**Remember-me example:**\\n\\n```javascript\\n// Set cookie with expiration\\nres.cookie('remember', 1, { maxAge: 60000 });\\n\\n// Check for cookie\\nif (req.cookies.remember) {\\n  // User is remembered\\n}\\n\\n// Clear cookie\\nres.clearCookie('remember');\\n```\\n\\n---\\n\\n### Redis-Backed Sessions (`examples/session/redis.js`)\\n\\nProduction-ready session storage using Redis via `connect-redis`.\\n\\n```javascript\\nvar RedisStore = require('connect-redis')(session);\\n\\napp.use(session({\\n  resave: false,\\n  saveUninitialized: false,\\n  secret: 'keyboard cat',\\n  store: new RedisStore\\n}));\\n```\\n\\n**Benefits:**\\n- Sessions persist across server restarts\\n- Shared session storage for multiple server instances\\n- Automatic session expiration via Redis TTL\\n\\n**Prerequisites:**\\n- Redis server running (`redis-server`)\\n- `npm install redis connect-redis`\\n\\n---\\n\\n### Online User Tracking (`examples/online/`)\\n\\nTracks active users using Redis and the `online` package.\\n\\n```javascript\\nvar online = require('online');\\nvar redis = require('redis');\\nvar db = redis.createClient();\\nonline = online(db);\\n\\n// Track each request\\napp.use(function(req, res, next){\\n  online.add(req.headers['user-agent']);\\n  next();\\n});\\n\\n// Query recent users\\napp.get('/', function(req, res, next){\\n  online.last(5, function(err, ids){\\n    // ids = array of recent user identifiers\\n  });\\n});\\n```\\n\\n---\\n\\n## Routes Reference\\n\\n### Authentication Example Routes\\n\\n| Route | Method | Handler | Description |\\n|-------|--------|---------|-------------|\\n| `/` | GET | redirects to `/login` | Root redirect |\\n| `/login` | GET | renders login view | Display login form |\\n| `/login` | POST | authenticate, session regenerate | Process credentials |\\n| `/logout` | GET | `req.session.destroy()` | End session |\\n| `/restricted` | GET | `restrict` middleware, send response | Protected content |\\n\\n### Session Example Routes\\n\\n| Route | Method | Handler | Description |\\n|-------|--------|---------|-------------|\\n| `/` | GET | increment `req.session.views` | View counter |\\n\\n---\\n\\n## Security Considerations\\n\\n### Session Fixation Prevention\\n\\nThe authentication example regenerates the session ID on successful login:\\n\\n```javascript\\nreq.session.regenerate(function(){\\n  req.session.user = user;\\n  // ...\\n});\\n```\\n\\nThis prevents attackers from using a known session ID to hijack authenticated sessions.\\n\\n### Password Storage\\n\\n- Passwords are never stored in plaintext\\n- PBKDF2 derives a key from the password with a unique salt per user\\n- The salt and hash are stored; the plaintext password is discarded\\n\\n### Session Configuration\\n\\n- `resave: false` - Avoids unnecessary session store writes\\n- `saveUninitialized: false` - Prevents creating empty session records for unauthenticated users\\n\\n### Production Requirements\\n\\nBefore deploying to production:\\n\\n1. Replace hardcoded secrets with environment variables\\n2. Use HTTPS to protect cookies in transit\\n3. Set `secure: true` and `httpOnly: true` cookie options\\n4. Use Redis or another persistent store for sessions\\n5. Implement proper user database (replace placeholder `users` object)\\n\\n---\\n\\n## Dependencies\\n\\n| Package | Purpose |\\n|---------|---------|\\n| `express-session` | Server-side session management |\\n| `cookie-session` | Client-side cookie-based sessions |\\n| `cookie-parser` | Parse cookies from request headers |\\n| `pbkdf2-password` | Password hashing with PBKDF2 |\\n| `connect-redis` | Redis session store adapter |\\n| `redis` | Redis client |\\n| `online` | Online user tracking with Redis |\",\"basic-usage\":\"# Basic Usage\\n\\n# Basic Usage Examples\\n\\nThis module contains example applications demonstrating core Express.js patterns. Each example is self-contained and runnable, progressing from minimal setup to more realistic use cases.\\n\\n## Examples Overview\\n\\n| Example | Purpose | Dependencies |\\n|---------|---------|--------------|\\n| `hello-world` | Minimal Express server | None |\\n| `search` | Redis-backed search API | redis |\\n\\n---\\n\\n## Hello World\\n\\n**Location:** `examples/hello-world/index.js`\\n\\nThe simplest Express application. Creates a server that responds to GET requests on the root path.\\n\\n### Code Structure\\n\\n```javascript\\nvar express = require('../../');\\nvar app = module.exports = express();\\n\\napp.get('/', function(req, res){\\n  res.send('Hello World');\\n});\\n\\nif (!module.parent) {\\n  app.listen(3000);\\n  console.log('Express started on port 3000');\\n}\\n```\\n\\n### Key Patterns\\n\\n**Exportable App Pattern:** The `app` is assigned to `module.exports`, allowing the application to be imported by tests or other modules without starting the server:\\n\\n```javascript\\nvar app = module.exports = express()\\n```\\n\\n**Conditional Server Start:** The `!module.parent` check ensures the server only starts when the file is run directly, not when imported:\\n\\n```javascript\\nif (!module.parent) {\\n  app.listen(3000);\\n}\\n```\\n\\n### Running\\n\\n```bash\\nnode examples/hello-world/index.js\\n# Visit http://localhost:3000\\n```\\n\\n---\\n\\n## Search Example\\n\\n**Location:** `examples/search/index.js`\\n\\nA more complete application demonstrating static file serving, Redis integration, and dynamic routing.\\n\\n### Architecture\\n\\n```mermaid\\nflowchart LR\\n    A[Client Browser] --&gt; B[Express Server]\\n    B --&gt; C[Redis Database]\\n    B --&gt; D[Static Files]\\n    A --&gt;|AJAX /search/:query| B\\n    B --&gt;|sMembers| C\\n    C --&gt;|results| B\\n    B --&gt;|JSON response| A\\n```\\n\\n### Components\\n\\n#### Redis Initialization\\n\\nThe `initializeRedis()` function handles async database setup:\\n\\n```javascript\\nasync function initializeRedis() {\\n  await db.connect();\\n  await db.sAdd('ferret', 'tobi');\\n  await db.sAdd('ferret', 'loki');\\n  await db.sAdd('ferret', 'jane');\\n  await db.sAdd('cat', 'manny');\\n  await db.sAdd('cat', 'luna');\\n}\\n```\\n\\nPopulates Redis sets with sample data for demonstration.\\n\\n#### Static File Serving\\n\\n```javascript\\napp.use(express.static(path.join(__dirname, 'public')));\\n```\\n\\nServes files from `public/` directory. Note: This middleware is placed before route definitions, allowing explicit routes to override static files when needed.\\n\\n#### Search Endpoint\\n\\n```javascript\\napp.get('/search/{:query}', function (req, res, next) {\\n  var query = req.params.query || '';\\n  db.sMembers(query)\\n    .then((vals) =&gt; res.send(vals))\\n    .catch((err) =&gt; {\\n      console.error(`Redis error for query \\\"${query}\\\":`, err);\\n      next(err);\\n    });\\n});\\n```\\n\\n**Route Pattern:** `/search/{:query}` captures the search term as a route parameter.\\n\\n**Error Handling:** Redis errors are passed to Express error middleware via `next(err)`.\\n\\n#### Explicit File Route\\n\\n```javascript\\napp.get('/client.js', function(req, res){\\n  res.sendFile(path.join(__dirname, 'client.js'));\\n});\\n```\\n\\nDemonstrates `sendFile()` for serving individual files with full path resolution. This pattern is useful when you need to serve specific files outside the static directory or with additional logic.\\n\\n### Client-Side Integration\\n\\n**Location:** `examples/search/public/client.js`\\n\\nImplements live search using XMLHttpRequest:\\n\\n```javascript\\nvar search = document.querySelector('[type=search]');\\nsearch.addEventListener('keyup', function(){\\n  var xhr = new XMLHttpRequest;\\n  xhr.open('GET', '/search/' + search.value, true);\\n  xhr.onreadystatechange = function(){\\n    if (xhr.readyState === 4) {\\n      code.textContent = xhr.responseText;\\n    }\\n  };\\n  xhr.send();\\n}, false);\\n```\\n\\nTriggers a search request on each keystroke and displays results in a `\n` element.\\n\\n### Running\\n\\n```bash\\n# Prerequisites\\nnpm install redis\\nredis-server\\n\\n# Start the application\\nnode examples/search/index.js\\n# Visit http://localhost:3000\\n```\\n\\n---\\n\\n## Common Patterns Demonstrated\\n\\n### Response Methods\\n\\n| Method | Example | Use Case |\\n|--------|---------|----------|\\n| `res.send()` | `res.send('Hello World')` | Text or JSON responses |\\n| `res.sendFile()` | `res.sendFile(path.join(...))` | Serving individual files |\\n\\n### Middleware Order\\n\\nThe search example demonstrates middleware ordering importance:\\n\\n1. `express.static()` \u2014 serves public assets first\\n2. Route handlers \u2014 explicit routes can intercept or add logic\\n3. Error handling \u2014 `next(err)` propagates to error middleware\\n\\n### Module Export Pattern\\n\\nBoth examples use the exportable app pattern for testability:\\n\\n```javascript\\n// In test file\\nvar app = require('../examples/hello-world');\\n// App is available without starting server\\n```\",\"core-framework\":\"# Core Framework\\n\\n# Express Core Framework\\n\\nThe Express Core Framework provides the foundational building blocks for creating web applications and APIs. It implements the application factory, request/response prototypes, middleware system, routing infrastructure, and view rendering.\\n\\n## Architecture Overview\\n\\n```mermaid\\ngraph TD\\n    A[createApplication] --&gt; B[app function]\\n    B --&gt; C[EventEmitter.prototype]\\n    B --&gt; D[application prototype]\\n    D --&gt; E[router - lazy init]\\n    B --&gt; F[request prototype]\\n    B --&gt; G[response prototype]\\n    F --&gt; H[http.IncomingMessage]\\n    G --&gt; I[http.ServerResponse]\\n    D --&gt; J[View class]\\n    D --&gt; K[utils]\\n```\\n\\n## Application Factory\\n\\nThe `createApplication()` function in `lib/express.js` is the main entry point that constructs an Express application:\\n\\n```javascript\\nfunction createApplication() {\\n  var app = function(req, res, next) {\\n    app.handle(req, res, next);\\n  };\\n\\n  mixin(app, EventEmitter.prototype, false);\\n  mixin(app, proto, false);\\n\\n  app.request = Object.create(req, {\\n    app: { configurable: true, enumerable: true, writable: true, value: app }\\n  });\\n\\n  app.response = Object.create(res, {\\n    app: { configurable: true, enumerable: true, writable: true, value: app }\\n  });\\n\\n  app.init();\\n  return app;\\n}\\n```\\n\\nThe returned `app` is both a callable function (for use with `http.createServer`) and an object with methods for configuration, routing, and middleware registration.\\n\\n## Application Prototype (`lib/application.js`)\\n\\n### Initialization\\n\\n**`app.init()`** \u2014 Sets up the application's internal state:\\n- Creates empty `cache`, `engines`, and `settings` objects\\n- Calls `defaultConfiguration()` to apply default settings\\n- Lazily initializes the router via a getter\\n\\n**`app.defaultConfiguration()`** \u2014 Applies default settings:\\n\\n| Setting | Default Value |\\n|---------|---------------|\\n| `x-powered-by` | `true` |\\n| `etag` | `'weak'` |\\n| `env` | `process.env.NODE_ENV \\\\|\\\\| 'development'` |\\n| `query parser` | `'simple'` |\\n| `subdomain offset` | `2` |\\n| `trust proxy` | `false` |\\n| `view` | `View` class |\\n| `views` | `'views'` (resolved path) |\\n| `jsonp callback name` | `'callback'` |\\n\\nIn production mode, `view cache` is automatically enabled.\\n\\n### Request Handling\\n\\n**`app.handle(req, res, callback)`** \u2014 The core request dispatcher:\\n\\n1. Creates a final handler for uncaught errors\\n2. Sets `X-Powered-By: Express` header if enabled\\n3. Establishes circular `req.res` and `res.req` references\\n4. Sets prototypes on `req` and `res` to extend them with Express methods\\n5. Initializes `res.locals` if not present\\n6. Delegates to `this.router.handle()`\\n\\n### Middleware &amp; Routing\\n\\n**`app.use(fn)`** \u2014 Registers middleware on the application router:\\n\\n```javascript\\n// Mount middleware at root\\napp.use(express.json());\\n\\n// Mount middleware at path\\napp.use('/api', authMiddleware);\\n\\n// Mount sub-application\\napp.use('/admin', adminApp);\\n```\\n\\nWhen mounting a sub-application:\\n- The sub-app's `mountpath` and `parent` properties are set\\n- A wrapper function restores request/response prototypes after the sub-app handles\\n- The `'mount'` event is emitted on the sub-app\\n\\n**`app.route(path)`** \u2014 Creates a new `Route` instance for the given path. Routes are isolated middleware stacks for specific paths.\\n\\n**`app.param(name, fn)`** \u2014 Registers parameter middleware. The `name` can be a string or array of strings.\\n\\n**HTTP Method Methods** \u2014 `app.get()`, `app.post()`, `app.put()`, `app.delete()`, etc.:\\n- `app.get(setting)` with one argument retrieves a setting value\\n- `app.get(path, ...handlers)` with multiple arguments creates a route\\n\\n**`app.all(path, ...handlers)`** \u2014 Registers handlers for all HTTP methods on the given path.\\n\\n### Settings Management\\n\\n**`app.set(setting, val)`** \u2014 Sets or retrieves settings:\\n\\n```javascript\\napp.set('title', 'My App');  // Set\\napp.set('title');            // Get \u2192 'My App'\\n```\\n\\nSpecial settings trigger compiled functions:\\n\\n| Setting | Compiled Function |\\n|---------|-------------------|\\n| `etag` | `etag fn` (via `compileETag`) |\\n| `query parser` | `query parser fn` (via `compileQueryParser`) |\\n| `trust proxy` | `trust proxy fn` (via `compileTrust`) |\\n\\n**`app.enable(setting)`** / **`app.disable(setting)`** \u2014 Set to `true` or `false`.\\n\\n**`app.enabled(setting)`** / **`app.disabled(setting)`** \u2014 Check boolean state.\\n\\n### View Rendering\\n\\n**`app.render(name, options, callback)`** \u2014 Renders a view template:\\n\\n1. Merges options with `app.locals` and `opts._locals`\\n2. Checks cache if `view cache` is enabled\\n3. Creates a new `View` instance if not cached\\n4. Calls `view.render()` with the merged options\\n\\n### Server\\n\\n**`app.listen(...)`** \u2014 Creates and starts an HTTP server:\\n\\n```javascript\\napp.listen(3000);\\napp.listen(3000, '127.0.0.1');\\napp.listen(3000, () =&gt; console.log('Server started'));\\n```\\n\\n## Request Prototype (`lib/request.js`)\\n\\nExtends `http.IncomingMessage` with properties and methods for handling incoming requests.\\n\\n### Header Access\\n\\n**`req.get(name)`** / **`req.header(name)`** \u2014 Retrieves request headers (case-insensitive). Special-cases `Referer`/`Referrer`.\\n\\n### Content Negotiation\\n\\n| Method | Description |\\n|--------|-------------|\\n| `req.accepts(types)` | Best matching MIME type from Accept header |\\n| `req.acceptsEncodings(...encodings)` | Accepted encodings |\\n| `req.acceptsCharsets(...charsets)` | Accepted charsets |\\n| `req.acceptsLanguages(...languages)` | Accepted languages |\\n\\n### Request Properties\\n\\nAll properties are defined via getters for lazy evaluation:\\n\\n| Property | Description |\\n|----------|-------------|\\n| `req.query` | Parsed query string object |\\n| `req.protocol` | `'http'` or `'https'` |\\n| `req.secure` | `true` if HTTPS |\\n| `req.ip` | Client IP address (respects trust proxy) |\\n| `req.ips` | Array of IPs from X-Forwarded-For |\\n| `req.subdomains` | Array of subdomain parts |\\n| `req.path` | URL pathname |\\n| `req.host` | Host header (respects X-Forwarded-Host) |\\n| `req.hostname` | Host without port |\\n| `req.fresh` | `true` if cache is fresh (ETag/Last-Modified) |\\n| `req.stale` | Opposite of `fresh` |\\n| `req.xhr` | `true` if XMLHttpRequest |\\n\\n### Other Methods\\n\\n**`req.range(size, options)`** \u2014 Parses the `Range` header. Returns `undefined` if no range, `-1` if unsatisfiable, `-2` if invalid, or an array of range objects.\\n\\n**`req.is(types)`** \u2014 Checks if the request Content-Type matches the given types.\\n\\n## Response Prototype (`lib/response.js`)\\n\\nExtends `http.ServerResponse` with methods for sending responses.\\n\\n### Status &amp; Headers\\n\\n**`res.status(code)`** \u2014 Sets HTTP status code. Validates integer range 100-999.\\n\\n**`res.set(field, val)`** / **`res.header(field, val)`** \u2014 Sets response headers. Accepts object or key-value pairs.\\n\\n**`res.get(field)`** \u2014 Retrieves a response header.\\n\\n**`res.append(field, val)`** \u2014 Appends to an existing header.\\n\\n**`res.vary(field)`** \u2014 Adds to the `Vary` header.\\n\\n**`res.links(links)`** \u2014 Sets `Link` header from an object.\\n\\n### Sending Responses\\n\\n**`res.send(body)`** \u2014 Universal response sender:\\n- Strings: sent as HTML with UTF-8 charset\\n- Objects/Arrays: converted to JSON\\n- Buffers: sent as binary\\n- Numbers/Booleans: converted to JSON\\n- Automatically sets `Content-Length` and `ETag`\\n- Handles 204, 205, 304 status codes specially\\n\\n**`res.json(obj)`** \u2014 Sends JSON response with `Content-Type: application/json`.\\n\\n**`res.jsonp(obj)`** \u2014 Sends JSONP response. Uses the query parameter specified by `jsonp callback name` setting.\\n\\n**`res.sendStatus(statusCode)`** \u2014 Sends status code with its standard message.\\n\\n### Files &amp; Downloads\\n\\n**`res.sendFile(path, options, callback)`** \u2014 Streams a file:\\n- Options: `maxAge`, `root`, `headers`, `dotfiles`\\n- Requires absolute path or `root` option\\n- Uses the `send` module internally\\n\\n**`res.download(path, filename, options, callback)`** \u2014 Sends file as attachment with `Content-Disposition` header.\\n\\n**`res.attachment(filename)`** \u2014 Sets `Content-Disposition: attachment` header.\\n\\n### Content Type\\n\\n**`res.type(type)`** / **`res.contentType(type)`** \u2014 Sets Content-Type. Accepts extensions or full MIME types.\\n\\n**`res.format(obj)`** \u2014 Content negotiation based on Accept header:\\n\\n```javascript\\nres.format({\\n  'text/plain': () =&gt; res.send('text'),\\n  'text/html': () =&gt; res.send('\nhtml&lt;\\/p&gt;'),\\n  'application/json': () =&gt; res.json({ data: 'json' }),\\n  default: () =&gt; res.status(406).send('Not Acceptable')\\n});\\n```\\n\\n### Cookies\\n\\n**`res.cookie(name, value, options)`** \u2014 Sets a cookie:\\n- `maxAge`: milliseconds until expiry\\n- `signed`: sign with `req.secret`\\n- `path`: defaults to `/`\\n- Other options: `expires`, `httpOnly`, `secure`, `sameSite`, etc.\\n\\n**`res.clearCookie(name, options)`** \u2014 Clears a cookie by setting expiry to the past.\\n\\n### Redirects\\n\\n**`res.location(url)`** \u2014 Sets `Location` header. Handles `'back'` for referrer.\\n\\n**`res.redirect(url)`** / **`res.redirect(status, url)`** \u2014 Performs HTTP redirect (default 302). Responds with appropriate body based on Accept header.\\n\\n### Rendering\\n\\n**`res.render(view, options, callback)`** \u2014 Renders a view template:\\n1. Merges `res.locals` into options\\n2. Calls `app.render()` with the view name\\n3. Default callback sends the rendered HTML\\n\\n## View Class (`lib/view.js`)\\n\\nHandles template lookup and rendering.\\n\\n### Constructor\\n\\n```javascript\\nnew View(name, {\\n  defaultEngine: 'ejs',\\n  root: './views',\\n  engines: { '.ejs': ejs.__express }\\n});\\n```\\n\\n- Resolves the file extension from the name or default engine\\n- Loads the template engine if not already cached\\n- Looks up the view file\\n\\n### Methods\\n\\n**`view.lookup(name)`** \u2014 Searches for the view file in configured root directories.\\n\\n**`view.resolve(dir, file)`** \u2014 Resolves a file within a directory, checking:\\n1. `.`\\n2. `/index.`\\n\\n**`view.render(options, callback)`** \u2014 Renders the view using the loaded engine. Ensures the callback is always invoked asynchronously via `process.nextTick()`.\\n\\n## Utilities (`lib/utils.js`)\\n\\nInternal helper functions used throughout the framework:\\n\\n| Function | Purpose |\\n|----------|---------|\\n| `methods` | Array of lowercase HTTP methods from Node.js |\\n| `etag(body, encoding)` | Generate strong ETag |\\n| `wetag(body, encoding)` | Generate weak ETag |\\n| `compileETag(val)` | Convert setting to ETag function |\\n| `compileQueryParser(val)` | Convert setting to query parser function |\\n| `compileTrust(val)` | Convert setting to trust proxy function |\\n| `normalizeType(type)` | Normalize MIME type with params |\\n| `normalizeTypes(types)` | Normalize array of types |\\n| `setCharset(type, charset)` | Add charset to Content-Type |\\n\\n## Sub-Application Mounting\\n\\nWhen mounting an Express app within another app:\\n\\n```javascript\\nvar admin = express();\\nadmin.locals.title = 'Admin';\\n\\napp.use('/admin', admin);\\n```\\n\\nThe sub-app:\\n- Receives `mountpath` set to `/admin`\\n- Receives `parent` reference to the main app\\n- Emits `'mount'` event\\n- Inherits `request`, `response`, `engines`, and `settings` prototypes from parent\\n- Inherits `trust proxy` setting if not explicitly set\\n\\n## Error Handling\\n\\nThe `finalhandler` module is used as the default error handler when no callback is provided to `app.handle()`. Errors are logged via `logerror()` in non-test environments.\\n\\n## Exports\\n\\nThe main `express` module exports:\\n\\n```javascript\\nexpress()              // createApplication factory\\nexpress.application    // application prototype\\nexpress.request        // request prototype\\nexpress.response       // response prototype\\nexpress.Route          // Route class from router\\nexpress.Router         // Router class\\nexpress.json()         // JSON body parser\\nexpress.raw()          // Raw body parser\\nexpress.text()         // Text body parser\\nexpress.urlencoded()   // URL-encoded body parser\\nexpress.static()       // Static file server\\n```\",\"error-handling\":\"# Error Handling\\n\\n# Error Handling Module\\n\\nThis module demonstrates Express.js error handling patterns through two example applications: a comprehensive error pages example with content negotiation, and a minimal error handling example.\\n\\n## Overview\\n\\nExpress distinguishes between two types of middleware:\\n- **Regular middleware**: signature `(req, res, next)` \u2014 handles normal request flow\\n- **Error-handling middleware**: signature `(err, req, res, next)` \u2014 catches errors passed through `next(err)` or thrown synchronously\\n\\nError-handling middleware must be registered **after** all routes and regular middleware to receive errors.\\n\\n## Architecture\\n\\n```mermaid\\nflowchart TD\\n    A[Request] --&gt; B{Route Handler}\\n    B --&gt;|Success| C[Response]\\n    B --&gt;|throw Error| D[Error Middleware]\\n    B --&gt;|next err| D\\n    B --&gt;|next without response| E[404 Handler]\\n    D --&gt; F[Error Response]\\n    E --&gt; G[404 Response]\\n```\\n\\n## Examples\\n\\n### Error Pages Example (`examples/error-pages/`)\\n\\nA full-featured error handling demonstration with custom views and content negotiation.\\n\\n#### Configuration\\n\\n```javascript\\napp.set('views', path.join(__dirname, 'views'));\\napp.set('view engine', 'ejs');\\napp.enable('verbose errors');\\n\\n// Disable verbose errors in production\\nif (app.settings.env === 'production') app.disable('verbose errors')\\n```\\n\\nThe `verbose errors` setting controls whether stack traces are displayed in error pages. This is exposed to templates via `settings['verbose errors']`.\\n\\n#### Triggering Errors\\n\\n| Route | Method | Behavior |\\n|-------|--------|----------|\\n| `GET /404` | `next()` | No response sent, falls through to 404 handler |\\n| `GET /403` | `next(err)` | Passes a 403 error to error middleware |\\n| `GET /500` | `next(new Error(...))` | Triggers a generic 500 error |\\n\\n```javascript\\napp.get('/403', function(req, res, next){\\n  var err = new Error('not allowed!');\\n  err.status = 403;\\n  next(err);\\n});\\n```\\n\\n#### 404 Handler\\n\\nPlaced after all routes. If no route matched or no middleware responded, this handler creates a 404 response:\\n\\n```javascript\\napp.use(function(req, res, next){\\n  res.status(404);\\n  res.format({\\n    html: function () {\\n      res.render('404', { url: req.url })\\n    },\\n    json: function () {\\n      res.json({ error: 'Not found' })\\n    },\\n    default: function () {\\n      res.type('txt').send('Not found')\\n    }\\n  })\\n});\\n```\\n\\nThe `res.format()` method performs content negotiation based on the `Accept` header.\\n\\n#### Error Middleware\\n\\n```javascript\\napp.use(function(err, req, res, next){\\n  res.status(err.status || 500);\\n  res.render('500', { error: err });\\n});\\n```\\n\\nUses `err.status` if available, otherwise defaults to 500 (Internal Server Error).\\n\\n#### Views\\n\\n**500.ejs** \u2014 Conditionally displays stack traces:\\n\\n```ejs\\n\nError: &lt;%= error.message %&gt;&lt;\\/h2&gt;\\n&lt;% if (settings['verbose errors']) { %&gt;\\n  \n&lt;%= error.stack %&gt;&lt;\\/pre&gt;\\n&lt;% } else { %&gt;\\n  \nAn error occurred!&lt;\\/p&gt;\\n&lt;% } %&gt;\\n```\\n\\n### Minimal Error Example (`examples/error/`)\\n\\nDemonstrates two ways errors reach error-handling middleware:\\n\\n#### Synchronous Throw\\n\\n```javascript\\napp.get('/', function () {\\n  throw new Error('something broke!');\\n});\\n```\\n\\nThrown errors are automatically caught by Express and passed to error middleware.\\n\\n#### Async with next(err)\\n\\n```javascript\\napp.get('/next', function(req, res, next){\\n  process.nextTick(function(){\\n    next(new Error('oh no!'));\\n  });\\n});\\n```\\n\\nFor async operations, pass errors to `next()`. Throwing inside async callbacks won't be caught by Express.\\n\\n#### Error Handler\\n\\n```javascript\\nfunction error(err, req, res, next) {\\n  if (!test) console.error(err.stack);\\n  res.status(500);\\n  res.send('Internal Server Error');\\n}\\n\\napp.use(error);\\n```\\n\\n## Key Concepts\\n\\n### Middleware Arity\\n\\nExpress uses function arity (argument count) to identify error-handling middleware:\\n\\n| Arity | Type | Signature |\\n|-------|------|-----------|\\n| 3 | Regular | `(req, res, next)` |\\n| 4 | Error | `(err, req, res, next)` |\\n\\n### Error Propagation\\n\\n1. **Synchronous throws**: Caught automatically by Express\\n2. **`next(err)`**: Passes error to next error-handling middleware\\n3. **`next()`**: Continues to next regular middleware (no error)\\n4. **No response + no next()**: Falls through to subsequent middleware\\n\\n### Middleware Order\\n\\nError handlers must be registered **after** routes:\\n\\n```javascript\\n// \u2713 Correct\\napp.get('/', routeHandler);\\napp.use(errorHandler);\\n\\n// \u2717 Wrong - handler never receives errors\\napp.use(errorHandler);\\napp.get('/', routeHandler);\\n```\\n\\n### Production vs Development\\n\\n| Environment | Verbose Errors | Stack Traces |\\n|--------------|----------------|--------------|\\n| Development | Enabled | Shown |\\n| Production | Disabled | Hidden |\\n\\n## Testing Error Responses\\n\\n```bash\\n# 404 with different Accept headers\\ncurl http://localhost:3000/notfound\\ncurl http://localhost:3000/notfound -H \\\"Accept: application/json\\\"\\ncurl http://localhost:3000/notfound -H \\\"Accept: text/plain\\\"\\n```\",\"other-acceptance\":\"# Other \u2014 acceptance\\n\\n# Acceptance Tests Module\\n\\nThe `test/acceptance/` directory contains integration tests for Express example applications. Each test file validates the end-to-end behavior of a corresponding example in the `examples/` directory using HTTP requests via `supertest`.\\n\\n## Purpose\\n\\nThese tests serve as:\\n- **Integration verification** \u2014 Confirm example apps work correctly as complete systems\\n- **Documentation by example** \u2014 Demonstrate expected HTTP behavior for each feature\\n- **Regression protection** \u2014 Catch breaking changes in example applications\\n\\n## Architecture\\n\\n```\\ntest/acceptance/\\n\u251c\u2500\u2500 auth.js              \u2192 examples/auth\\n\u251c\u2500\u2500 content-negotiation.js \u2192 examples/content-negotiation\\n\u251c\u2500\u2500 cookie-sessions.js   \u2192 examples/cookie-sessions\\n\u251c\u2500\u2500 cookies.js           \u2192 examples/cookies\\n\u251c\u2500\u2500 downloads.js         \u2192 examples/downloads\\n\u251c\u2500\u2500 ejs.js               \u2192 examples/ejs\\n\u251c\u2500\u2500 error.js             \u2192 examples/error\\n\u251c\u2500\u2500 error-pages.js       \u2192 examples/error-pages\\n\u251c\u2500\u2500 hello-world.js       \u2192 examples/hello-world\\n\u251c\u2500\u2500 markdown.js          \u2192 examples/markdown\\n\u251c\u2500\u2500 multi-router.js      \u2192 examples/multi-router\\n\u251c\u2500\u2500 mvc.js               \u2192 examples/mvc\\n\u251c\u2500\u2500 params.js            \u2192 examples/params\\n\u251c\u2500\u2500 resource.js          \u2192 examples/resource\\n\u251c\u2500\u2500 route-map.js         \u2192 examples/route-map\\n\u251c\u2500\u2500 route-separation.js  \u2192 examples/route-separation\\n\u251c\u2500\u2500 vhost.js             \u2192 examples/vhost\\n\u2514\u2500\u2500 web-service.js       \u2192 examples/web-service\\n```\\n\\n## Test Structure\\n\\nAll tests follow a consistent pattern using Mocha and supertest:\\n\\n```javascript\\nvar request = require('supertest');\\nvar app = require('../../examples/example-name');\\n\\ndescribe('example-name', function(){\\n  describe('GET /path', function(){\\n    it('should respond with expected behavior', function(done){\\n      request(app)\\n        .get('/path')\\n        .expect(200, done);\\n    });\\n  });\\n});\\n```\\n\\n## Key Test Categories\\n\\n### Authentication &amp; Sessions\\n\\n**auth.js** \u2014 Tests login/logout flow, session persistence, and route protection:\\n- Redirects unauthenticated users to `/login`\\n- Validates credentials (username: `tj`, password: `foobar`)\\n- Sets session cookies on successful login\\n- Restricts `/restricted` to authenticated users\\n\\n**cookie-sessions.js** \u2014 Tests cookie-based session state:\\n- Tracks view counts across requests\\n- Persists session data via cookies\\n\\n**cookies.js** \u2014 Tests cookie handling:\\n- Setting and clearing cookies\\n- \\\"Remember me\\\" functionality\\n\\n### Content Handling\\n\\n**content-negotiation.js** \u2014 Tests response format negotiation:\\n- `Accept: text/html` \u2192 HTML list\\n- `Accept: text/plain` \u2192 Plain text list\\n- `Accept: application/json` \u2192 JSON array\\n\\n**downloads.js** \u2014 Tests file download behavior:\\n- Sets `Content-Disposition: attachment` headers\\n- Blocks path traversal attacks (`/files/../index.js` returns 403)\\n- Returns 404 for missing files\\n\\n**ejs.js** \u2014 Tests EJS template rendering with proper HTML escaping\\n\\n**markdown.js** \u2014 Tests markdown-to-HTML conversion\\n\\n### Routing Patterns\\n\\n**multi-router.js** \u2014 Tests multiple Express routers:\\n- Root routes (`/`)\\n- Versioned API routes (`/api/v1/`, `/api/v2/`)\\n\\n**route-map.js** \u2014 Tests route mapping with HTTP method verbs\\n\\n**route-separation.js** \u2014 Tests modular route organization:\\n- User routes (`/users`, `/user/:id`)\\n- Pet routes (`/pet/:id`)\\n- Post routes (`/posts`)\\n\\n**params.js** \u2014 Tests route parameter preconditions:\\n- User lookup by ID\\n- Range parsing (`/users/0-2`)\\n- Error handling for invalid params\\n\\n### Error Handling\\n\\n**error.js** \u2014 Tests error middleware:\\n- Synchronous errors return 500\\n- Missing routes return 404\\n\\n**error-pages.js** \u2014 Tests custom error pages with content negotiation:\\n- HTML, JSON, and plain text error responses\\n- Status codes: 403, 404, 500\\n\\n### API Patterns\\n\\n**web-service.js** \u2014 Tests REST API with API key authentication:\\n- Missing API key \u2192 400 Bad Request\\n- Invalid API key \u2192 401 Unauthorized\\n- Valid API key (`foo` or `bar`) \u2192 JSON response\\n\\n**resource.js** \u2014 Tests resource-based routing:\\n- CRUD operations on `/users`\\n- Range queries (`/users/1..3`)\\n- JSON format suffix (`.json`)\\n\\n### Virtual Hosting\\n\\n**vhost.js** \u2014 Tests virtual host routing:\\n- `example.com` \u2192 main app\\n- `foo.example.com` \u2192 redirects to `/foo`\\n- `bar.example.com` \u2192 redirects to `/bar`\\n\\n### MVC Pattern\\n\\n**mvc.js** \u2014 Tests full MVC implementation:\\n- User CRUD operations\\n- Pet management per user\\n- Edit forms and updates\\n\\n## Helper Functions\\n\\n### getCookie (auth.js)\\n\\nExtracts session cookie from response headers:\\n\\n```javascript\\nfunction getCookie(res) {\\n  return res.headers['set-cookie'][0].split(';')[0];\\n}\\n```\\n\\n### getCookies (cookie-sessions.js)\\n\\nExtracts all cookies for multi-cookie responses:\\n\\n```javascript\\nfunction getCookies(res) {\\n  return res.headers['set-cookie'].map(function (val) {\\n    return val.split(';')[0]\\n  }).join('; ');\\n}\\n```\\n\\n## External Dependencies\\n\\n- **supertest** \u2014 HTTP assertion library for testing Express apps\\n- **test/support/utils.js** \u2014 Shared test utilities:\\n  - `shouldNotHaveHeader(headerName)` \u2014 Asserts response lacks a specific header\\n\\n## Running Tests\\n\\n```bash\\n# Run all acceptance tests\\nnpm test -- --grep \\\"acceptance\\\"\\n\\n# Run specific example test\\nnpm test -- test/acceptance/auth.js\\n```\\n\\n## Adding New Acceptance Tests\\n\\n1. Create `test/acceptance/your-feature.js`\\n2. Import the example app: `var app = require('../../examples/your-feature')`\\n3. Structure tests by HTTP method and route\\n4. Test both success and error scenarios\\n5. Verify status codes, response bodies, and headers\",\"other-examples\":\"# Other \u2014 examples\\n\\n# Express Examples\\n\\nThe `examples/` directory contains reference applications demonstrating Express.js features and common patterns. Each subdirectory is a self-contained, runnable application focused on a specific concept.\\n\\n## Overview\\n\\nThese examples serve as practical guides for implementing common web application features with Express. They range from basic request handling to advanced patterns like MVC architecture and virtual hosting.\\n\\n## Example Categories\\n\\n### Core Concepts\\n\\n| Example | Description |\\n|---------|-------------|\\n| `hello-world` | Minimal Express server with a single request handler |\\n| `static-files` | Serving static assets (CSS, JS, images) |\\n| `error` | Error handling middleware implementation |\\n| `error-pages` | Custom error page rendering |\\n\\n### Routing Patterns\\n\\n| Example | Description |\\n|---------|-------------|\\n| `params` | Route parameter extraction and validation |\\n| `route-middleware` | Middleware specific to routes |\\n| `route-separation` | Organizing routes by resource |\\n| `route-map` | Route definitions using configuration maps |\\n| `multi-router` | Multiple Express routers for modular routing |\\n| `resource` | RESTful resource handling with multiple HTTP methods |\\n\\n### Sessions and Authentication\\n\\n| Example | Description |\\n|---------|-------------|\\n| `auth` | Login and password authentication flow |\\n| `session` | Server-side session management |\\n| `cookie-sessions` | Client-side session storage via cookies |\\n| `cookies` | Reading and writing HTTP cookies |\\n| `online` | Real-time user activity tracking with Redis |\\n\\n### Views and Templating\\n\\n| Example | Description |\\n|---------|-------------|\\n| `ejs` | Embedded JavaScript templates |\\n| `markdown` | Markdown as a template engine |\\n| `view-constructor` | Dynamic view rendering |\\n| `view-locals` | Passing data through `res.locals` |\\n\\n### HTTP Features\\n\\n| Example | Description |\\n|---------|-------------|\\n| `content-negotiation` | Responding based on `Accept` headers |\\n| `downloads` | File transfer to clients |\\n| `search` | Search API implementation |\\n| `web-service` | RESTful API service |\\n| `vhost` | Virtual hosting for multiple domains |\\n\\n### Architecture Patterns\\n\\n| Example | Description |\\n|---------|-------------|\\n| `mvc` | Model-View-Controller structure |\\n| `online` | Integration with external services (Redis) |\\n\\n## Running an Example\\n\\nEach example is a standalone Node.js application:\\n\\n```bash\\ncd examples/hello-world\\nnpm install\\nnode app.js\\n```\\n\\nMost examples follow this pattern, though some (like `online`) require additional setup such as a running Redis instance.\\n\\n## Directory Structure\\n\\nEach example typically contains:\\n\\n```\\nexample-name/\\n\u251c\u2500\u2500 app.js          # Main application entry point\\n\u251c\u2500\u2500 package.json    # Dependencies and scripts\\n\u251c\u2500\u2500 routes/         # Route handlers (in larger examples)\\n\u251c\u2500\u2500 views/          # Template files (when applicable)\\n\u2514\u2500\u2500 public/         # Static assets (when applicable)\\n```\\n\\n## Learning Path\\n\\nRecommended order for newcomers:\\n\\n1. `hello-world` \u2014 Understand basic server setup\\n2. `static-files` \u2014 Learn to serve assets\\n3. `route-middleware` \u2014 Grasp middleware chains\\n4. `params` \u2014 Work with dynamic routes\\n5. `error` \u2014 Implement error handling\\n6. `session` \u2014 Add state management\\n7. `auth` \u2014 Secure your application\\n8. `mvc` \u2014 Structure larger applications\",\"other-history-md\":\"# Other \u2014 History.md\\n\\n# History.md - Express.js Changelog\\n\\n## Overview\\n\\n`History.md` is the canonical changelog for Express.js, documenting the complete evolution of the framework from early 0.x releases through the current 5.x series. It serves as the primary historical record of all changes, including new features, bug fixes, breaking changes, deprecations, security updates, and dependency updates.\\n\\n## Purpose\\n\\nThis file provides:\\n\\n- **Release history**: Chronological record of all published versions with release dates\\n- **Migration guidance**: Breaking changes and deprecation notices to help developers upgrade\\n- **Feature documentation**: New capabilities added in each release\\n- **Security tracking**: CVE references and security advisory links\\n- **Dependency evolution**: External package version changes and their impact\\n\\n## Structure\\n\\nThe changelog follows a reverse-chronological format with these conventions:\\n\\n### Version Headers\\n\\n```\\n5.2.1 / 2025-12-01\\n===================\\n```\\n\\nEach version entry includes:\\n- Version number (semver format)\\n- Release date in `YYYY-MM-DD` format\\n\\n### Change Categories\\n\\nChanges are organized by type using emoji prefixes:\\n\\n| Category | Prefix | Description |\\n|----------|--------|-------------|\\n| Improvements | \ud83d\ude80 | Enhancements and refinements |\\n| Performance | \u26a1 | Optimizations and speed improvements |\\n| Breaking | `breaking:` | Changes requiring code modification |\\n| Remove | `remove:` | Deprecated features removed |\\n| Change | `change:` | Modified behavior |\\n| Add | `add:` | New features |\\n| Fix | `fix:` | Bug corrections |\\n| Deps | `deps:` | Dependency updates |\\n| Deprecate | `deprecate` | Features scheduled for removal |\\n| Perf | `perf:` | Performance improvements |\\n| Security | Security fix | CVE and security advisory references |\\n\\n### Pull Request References\\n\\nChanges link to their source:\\n\\n```\\n- by [@username](https://github.com/username) in [#1234](https://github.com/expressjs/express/pull/1234)\\n```\\n\\n### Code Examples\\n\\nSignificant changes include usage examples:\\n\\n```js\\napp.render('index', null, callback); // now works as expected\\n```\\n\\n## Key Version Milestones\\n\\n### Express 5.x (Current)\\n\\nThe 5.x series represents a major evolution with significant breaking changes:\\n\\n**5.0.0 (2024-09-10)** - Major release highlights:\\n- `res.status()` now validates integer status codes (99 &lt; code &lt; 1000)\\n- Removed `res.redirect('back')` magic string support\\n- `res.clearCookie` ignores user-provided `maxAge` and `expires`\\n- Removed `path-is-absolute` dependency (use `path.isAbsolute`)\\n- Multiple dependency updates to modern versions\\n\\n**5.1.0 (2025-03-31)** - Feature additions:\\n- `Uint8Array` support in `res.send()`\\n- ETag option in `res.sendFile()`\\n- Multiple links with same rel in `res.links()`\\n- Removed legacy dependencies: `setprototypeof`, `safe-buffer`, `utils-merge`, `methods`, `depd`\\n\\n**Unreleased** - Upcoming improvements:\\n- Enhanced HTML structure in `res.redirect()` responses\\n- `app.render()` now handles `null` options correctly\\n- Performance: reduced duplicate Content-Type processing in `res.send()`\\n\\n### Express 4.x (Stable Legacy)\\n\\nThe 4.x series remains widely used with active maintenance:\\n\\n**4.20.0 (2024-09-10)** - Security and dependency updates:\\n- Removed link renderization in `res.redirect` HTML responses\\n- `body-parser` depth option (default: 32, previously Infinity)\\n- `path-to-regexp@0.1.10` with named matching groups support\\n\\n**4.19.x (2024-03)** - Security fixes:\\n- Open redirect allow list bypass prevention\\n- Non-string encoding handling in `res.location`\\n\\n**4.18.x (2022)** - Feature additions:\\n- `res.download` \\\"root\\\" option\\n- `res.status` deprecation for non-integer arguments\\n- Proper 205 response handling\\n\\n### Express 3.x (Deprecated)\\n\\nHistorical reference for legacy applications. Key transitions from 3.x to 4.x:\\n\\n- Removed bundled middleware (except `static`)\\n- `app.router` removed\\n- `req.params` changed from array to object\\n- `res.locals` changed from function to plain object\\n\\n## Breaking Changes Reference\\n\\n### Response Method Signatures\\n\\nSeveral response method signatures changed across versions:\\n\\n| Version | Old Signature | New Signature |\\n|---------|---------------|---------------|\\n| 5.0.0-alpha.6 | `res.redirect(url, status)` | `res.redirect(status, url)` |\\n| 5.0.0-alpha.6 | `res.send(status, body)` | `res.status(status).send(body)` |\\n| 5.0.0-alpha.3 | `res.json(status, obj)` | `res.status(status).json(obj)` |\\n| 5.0.0-alpha.3 | `res.jsonp(status, obj)` | `res.status(status).jsonp(obj)` |\\n\\n### Removed Features\\n\\n| Feature | Removed In | Replacement |\\n|---------|------------|-------------|\\n| `app.del()` | 5.0.0-alpha.1 | `app.delete()` |\\n| `req.param()` | 5.0.0-alpha.2 | `req.params`, `req.body`, `req.query` |\\n| `res.sendfile` | 5.0.0-beta.1 | `res.sendFile` |\\n| `res.redirect('back')` | 5.0.0 | `req.get('Referrer') || '/'` |\\n| `express.query` | 5.0.0-alpha.1 | Use body-parser middleware |\\n\\n## Security Advisories\\n\\nThe changelog documents security vulnerabilities with full references:\\n\\n| CVE | Version Fixed | Description |\\n|-----|---------------|-------------|\\n| CVE-2024-47764 | 5.0.1 | Cookie semver vulnerability |\\n| CVE-2024-51999 | 5.2.0 (reverted in 5.2.1) | Extended query parser (rejected CVE) |\\n| GHSA-pj86-cfqh-vqx6 | 5.2.0 | Related to CVE-2024-51999 |\\n\\n## Dependency Evolution\\n\\n### Core Dependencies (5.x)\\n\\n```\\nbody-parser@^2.2.1\\nrouter@^2.2.0\\ndebug@^4.4.0\\nqs@^6.14.0\\ncontent-type@^1.0.5\\nfinalhandler@^2.1.0\\n```\\n\\n### Removed Dependencies (5.1.0)\\n\\nSeveral legacy compatibility packages were removed:\\n- `setprototypeof` - now uses native `Object.setPrototypeOf`\\n- `safe-buffer` - uses native `Buffer` API\\n- `utils-merge` - replaced with native spread/assign\\n- `methods` - internalized\\n- `depd` - deprecation handling simplified\\n\\n## Usage for Developers\\n\\n### When Upgrading\\n\\n1. **Identify target version** - Locate the version header for your upgrade target\\n2. **Review breaking changes** - Check `breaking:` and `remove:` entries\\n3. **Note deprecations** - Plan for `deprecate` items in future releases\\n4. **Check dependencies** - Verify compatible dependency versions\\n5. **Test security fixes** - Ensure security-related changes don't affect behavior\\n\\n### Version Range Navigation\\n\\nFor upgrading across multiple versions, read entries between your current and target versions. Each entry is self-contained with sufficient context for understanding the change impact.\\n\\n### Pull Request Investigation\\n\\nEach change links to its originating PR. For detailed implementation details, discussion context, or related issues, follow the PR links provided.\",\"other-package-json\":\"# Other \u2014 package.json\\n\\n# package.json\\n\\nExpress.js package manifest defining project metadata, dependencies, and development workflows.\\n\\n## Overview\\n\\nThis is the npm package configuration for Express 5.2.1. It declares the framework's public API surface, runtime requirements, and development toolchain.\\n\\n## Runtime Requirements\\n\\n```json\\n\\\"engines\\\": {\\n  \\\"node\\\": \\\"&gt;= 18\\\"\\n}\\n```\\n\\nExpress 5.x requires Node.js 18 or later. This aligns with the framework's use of modern JavaScript features and the updated dependency versions.\\n\\n## Published Files\\n\\n```json\\n\\\"files\\\": [\\n  \\\"LICENSE\\\",\\n  \\\"Readme.md\\\",\\n  \\\"index.js\\\",\\n  \\\"lib/\\\"\\n]\\n```\\n\\nWhen published to npm, only these files are included. The `lib/` directory contains the core framework implementation, while `index.js` serves as the main entry point.\\n\\n## Production Dependencies\\n\\n| Package | Version | Purpose |\\n|---------|---------|---------|\\n| `accepts` | ^2.0.0 | Content negotiation for Accept headers |\\n| `body-parser` | ^2.2.1 | Request body parsing middleware |\\n| `content-disposition` | ^1.0.0 | Content-Disposition header generation |\\n| `content-type` | ^1.0.5 | Content-Type header parsing |\\n| `cookie` | ^0.7.1 | Cookie parsing and serialization |\\n| `cookie-signature` | ^1.2.1 | Cookie signing for tamper detection |\\n| `debug` | ^4.4.0 | Debugging output with namespace support |\\n| `depd` | ^2.0.0 | Deprecation warnings |\\n| `encodeurl` | ^2.0.0 | URL encoding utilities |\\n| `escape-html` | ^1.0.3 | HTML entity escaping for XSS prevention |\\n| `etag` | ^1.8.1 | ETag header generation for caching |\\n| `finalhandler` | ^2.1.0 | Final request handler for cleanup |\\n| `fresh` | ^2.0.0 | HTTP cache freshness validation |\\n| `http-errors` | ^2.0.0 | HTTP error object creation |\\n| `merge-descriptors` | ^2.0.0 | Property descriptor merging |\\n| `mime-types` | ^3.0.0 | MIME type lookup and resolution |\\n| `on-finished` | ^2.4.1 | Callback attachment for request/response completion |\\n| `once` | ^1.4.0 | Single-execution function wrapper |\\n| `parseurl` | ^1.3.3 | URL parsing with caching |\\n| `proxy-addr` | ^2.0.7 | Proxy address resolution for X-Forwarded-For |\\n| `qs` | ^6.14.2 | Query string parsing with nesting support |\\n| `range-parser` | ^1.2.1 | Range header parsing for file downloads |\\n| `router` | ^2.2.0 | Core routing implementation |\\n| `send` | ^1.1.0 | Static file serving with caching |\\n| `serve-static` | ^2.2.0 | Static file serving middleware |\\n| `statuses` | ^2.0.1 | HTTP status code mappings |\\n| `type-is` | ^2.0.1 | Request content-type checking |\\n| `vary` | ^1.1.2 | Vary header manipulation for caching |\\n\\n### Key Dependency Groups\\n\\n**Request Processing**: `body-parser`, `qs`, `type-is`, `content-type`\\n\\n**Response Handling**: `send`, `serve-static`, `content-disposition`, `etag`, `fresh`\\n\\n**Routing**: `router`, `parseurl`\\n\\n**Security**: `cookie-signature`, `escape-html`, `proxy-addr`, `http-errors`\\n\\n**HTTP Utilities**: `accepts`, `vary`, `statuses`, `range-parser`\\n\\n## Development Dependencies\\n\\n| Package | Version | Purpose |\\n|---------|---------|---------|\\n| `mocha` | ^10.7.3 | Test framework |\\n| `supertest` | ^6.3.0 | HTTP assertion testing |\\n| `nyc` | ^17.1.0 | Code coverage instrumentation |\\n| `eslint` | 8.47.0 | Code linting |\\n| `marked` | ^15.0.3 | Markdown processing for docs |\\n\\n### Session and Auth Testing\\n\\n| Package | Version | Purpose |\\n|---------|---------|---------|\\n| `express-session` | ^1.18.1 | Session middleware testing |\\n| `connect-redis` | ^8.0.1 | Redis session store testing |\\n| `cookie-parser` | 1.4.7 | Cookie parsing middleware testing |\\n| `cookie-session` | 2.1.1 | Cookie-based session testing |\\n| `pbkdf2-password` | 1.2.1 | Password hashing for auth examples |\\n\\n### Template Engine Testing\\n\\n| Package | Version | Purpose |\\n|---------|---------|---------|\\n| `ejs` | ^3.1.10 | Embedded JavaScript templates |\\n| `hbs` | 4.2.0 | Handlebars templates |\\n\\n### Middleware Testing\\n\\n| Package | Version | Purpose |\\n|---------|---------|---------|\\n| `morgan` | 1.10.1 | HTTP request logger |\\n| `method-override` | 3.0.0 | HTTP method override support |\\n| `vhost` | ~3.0.2 | Virtual host routing |\\n\\n## NPM Scripts\\n\\n### Linting\\n\\n```bash\\nnpm run lint        # Check code style\\nnpm run lint:fix    # Auto-fix style issues\\n```\\n\\nUses ESLint 8.47.0 for code quality enforcement.\\n\\n### Testing\\n\\n```bash\\nnpm test            # Run full test suite with spec reporter\\nnpm run test-tap    # Run tests with TAP output for CI parsing\\nnpm run test-cov    # Run tests with HTML coverage report\\nnpm run test-ci     # Run tests with lcov output for CI services\\n```\\n\\n**Test Configuration**:\\n- Test files: `test/` and `test/acceptance/`\\n- Environment setup: `test/support/env`\\n- Leak detection enabled (`--check-leaks`)\\n\\n**Coverage Exclusions**: `examples/`, `test/`, `benchmarks/`\\n\\n## Version Information\\n\\n- **Current Version**: 5.2.1\\n- **License**: MIT\\n- **Author**: TJ Holowaychuk\\n- **Repository**: expressjs/express\\n\\n## Funding\\n\\nThe project accepts funding through Open Collective:\\n\\n```json\\n\\\"funding\\\": {\\n  \\\"type\\\": \\\"opencollective\\\",\\n  \\\"url\\\": \\\"https://opencollective.com/express\\\"\\n}\\n```\",\"other-readme-md\":\"# Other \u2014 Readme.md\\n\\n# Express.js README\\n\\n## Overview\\n\\nThe `Readme.md` file serves as the primary entry point for developers discovering and adopting Express.js. It provides essential information for installation, quick start, and contribution to the project.\\n\\n## Purpose\\n\\nThis documentation file fulfills several key functions:\\n\\n1. **Project Introduction** \u2014 Establishes Express.js as a fast, unopinionated, minimalist web framework for Node.js\\n2. **Installation Guidance** \u2014 Provides step-by-step setup instructions\\n3. **Feature Overview** \u2014 Summarizes core capabilities\\n4. **Community Resources** \u2014 Links to documentation, discussions, and governance\\n5. **Contribution Guidelines** \u2014 Directs contributors to proper channels and procedures\\n\\n## Key Sections\\n\\n### Requirements\\n\\nThe README specifies the minimum Node.js version requirement:\\n\\n```\\nNode.js 18 or higher is required\\n```\\n\\nThis is critical information for developers before installation.\\n\\n### Installation\\n\\nStandard npm installation:\\n\\n```bash\\nnpm install express\\n```\\n\\nFor new projects, developers should initialize with `npm init` first.\\n\\n### Quick Start Options\\n\\nTwo paths are documented:\\n\\n| Approach | Use Case |\\n|----------|----------|\\n| Manual setup | Simple applications, learning |\\n| `express-generator` | Full application scaffolding |\\n\\n**Generator-based setup:**\\n\\n```bash\\nnpm install -g express-generator@4\\nexpress /tmp/foo &amp;&amp; cd /tmp/foo\\nnpm install\\nnpm start\\n```\\n\\n### Core Features\\n\\nThe README highlights these capabilities:\\n\\n- **Robust routing** \u2014 URL pattern matching and HTTP method handling\\n- **High performance** \u2014 Optimized for speed\\n- **Test coverage** \u2014 Comprehensive test suite\\n- **HTTP helpers** \u2014 Built-in utilities for redirection, caching, etc.\\n- **View system** \u2014 Support for 14+ template engines via `@ladjs/consolidate`\\n- **Content negotiation** \u2014 Automatic response format handling\\n- **Application generator** \u2014 CLI tool for rapid scaffolding\\n\\n### Philosophy\\n\\nExpress.js is intentionally unopinionated:\\n\\n&gt; Express does not force you to use any specific ORM or template engine.\\n\\nThis design principle means developers can:\\n- Choose their own database layer\\n- Select any template engine\\n- Structure applications as needed\\n\\n### Contributing\\n\\nThe README directs contributors to:\\n\\n1. **[Contributing Guide]** \u2014 Technical details on contributing\\n2. **Security Issues** \u2014 Security policy for vulnerability reporting\\n3. **Running Tests** \u2014 Test suite execution via `npm test`\\n\\n### Project Governance\\n\\nTeam structure is documented:\\n\\n- **Technical Committee (TC)** \u2014 8 active members with decision-making authority\\n- **TC Emeriti** \u2014 Former TC members\\n- **Triagers** \u2014 11 active members handling issue triage\\n- **Emeritus Triagers** \u2014 Former triage team members\\n\\nGovernance details: [GOVERNANCE.md](https://github.com/expressjs/discussions/blob/HEAD/docs/GOVERNANCE.md)\\n\\n## Important Links\\n\\n| Resource | URL |\\n|----------|-----|\\n| Official Documentation | https://expressjs.com/ |\\n| GitHub Organization | https://github.com/expressjs |\\n| GitHub Discussions | https://github.com/expressjs/discussions |\\n| Migration Guide to v5 | https://expressjs.com/en/guide/migrating-5 |\\n| Security Policy | https://github.com/expressjs/express/security/policy |\\n\\n## Badge Status Indicators\\n\\nThe README displays real-time project health indicators:\\n\\n- **NPM Version** \u2014 Current published version\\n- **NPM Downloads** \u2014 Download statistics\\n- **CI Status** \u2014 GitHub Actions build status\\n- **Test Coverage** \u2014 Coveralls coverage percentage\\n- **OpenSSF Scorecard** \u2014 Security assessment score\\n\\n## License\\n\\nMIT License \u2014 see [LICENSE](LICENSE) file for full text.\\n\\n## Related Files\\n\\n- `CONTRIBUTING.md` \u2014 Detailed contribution guidelines\\n- `CODE_OF_CONDUCT.md` \u2014 Community standards\\n- `GOVERNANCE.md` \u2014 Project governance structure\\n- `Security Policy` \u2014 Vulnerability reporting procedures\\n\\n---\\n\\n*Note: This README is the primary onboarding document. For API documentation, refer to the [official Express.js documentation site](https://expressjs.com/).*\",\"other-support\":\"# Other \u2014 support\\n\\n# Test Support Module\\n\\nThe `test/support` directory provides shared utilities for the Express test suite, including environment configuration, template rendering, and supertest assertion helpers.\\n\\n## Overview\\n\\n```\\ntest/support/\\n\u251c\u2500\u2500 env.js      # Test environment configuration\\n\u251c\u2500\u2500 tmpl.js     # Simple template renderer\\n\u2514\u2500\u2500 utils.js    # Supertest assertion helpers\\n```\\n\\n## Environment Configuration (`env.js`)\\n\\nSets required environment variables before tests execute:\\n\\n```javascript\\nprocess.env.NODE_ENV = 'test';\\nprocess.env.NO_DEPRECATION = 'body-parser,express';\\n```\\n\\n- **NODE_ENV**: Ensures Express runs in test mode\\n- **NO_DEPRECATION**: Suppresses deprecation warnings from body-parser and express to keep test output clean\\n\\nThis file should be imported at the top of test files that need these settings.\\n\\n## Template Renderer (`tmpl.js`)\\n\\nA minimal template engine for test fixtures that performs variable substitution.\\n\\n### Usage\\n\\n```javascript\\nconst renderFile = require('./support/tmpl');\\n\\nrenderFile('/path/to/template.html', { name: 'Express' }, (err, result) =&gt; {\\n  // result contains the rendered template\\n});\\n```\\n\\n### Variable Syntax\\n\\nVariables use `$` prefix notation and support dot notation for nested objects:\\n\\n```\\nHello, $user.name!\\nEmail: $user.email\\n```\\n\\n### How It Works\\n\\n1. Reads the template file asynchronously\\n2. Replaces all `$variable.path` patterns with corresponding values from the options object\\n3. Returns the rendered string via callback\\n\\nThe `generateVariableLookup` function traverses nested objects using the dot-separated path:\\n\\n```javascript\\n// $user.profile.name resolves to options.user.profile.name\\n```\\n\\n## Assertion Helpers (`utils.js`)\\n\\nFactory functions that create supertest assertion callbacks. Each function returns a function that receives a supertest response object.\\n\\n### `shouldHaveBody(buf)`\\n\\nAsserts the response body matches the expected buffer (hex comparison).\\n\\n```javascript\\nconst expected = Buffer.from('Hello World');\\nrequest(app)\\n  .get('/')\\n  .expect(shouldHaveBody(expected));\\n```\\n\\nHandles both buffer and text responses internally by converting to Buffer for comparison.\\n\\n### `shouldHaveHeader(header)`\\n\\nAsserts the response includes a specific header (case-insensitive).\\n\\n```javascript\\nrequest(app)\\n  .get('/')\\n  .expect(shouldHaveHeader('Content-Type'));\\n```\\n\\n### `shouldNotHaveBody()`\\n\\nAsserts the response has no body (empty or undefined text).\\n\\n```javascript\\nrequest(app)\\n  .get('/empty')\\n  .expect(shouldNotHaveBody());\\n```\\n\\n### `shouldNotHaveHeader(header)`\\n\\nAsserts the response does not include a specific header.\\n\\n```javascript\\nrequest(app)\\n  .get('/')\\n  .expect(shouldNotHaveHeader('X-Custom-Header'));\\n```\\n\\n### `shouldSkipQuery(versionString)`\\n\\nDetermines whether to skip HTTP QUERY method tests based on Node.js version.\\n\\n```javascript\\nconst nodeVersion = process.version; // e.g., 'v20.10.0'\\nif (shouldSkipQuery(nodeVersion)) {\\n  // Skip QUERY tests\\n}\\n```\\n\\nHTTP QUERY support was added in Node.js 22. This helper ensures tests don't fail on older Node versions.\\n\\n## Usage Across Test Suite\\n\\nThe assertion helpers are used throughout the Express test files:\\n\\n| Helper | Used In |\\n|--------|---------|\\n| `shouldHaveBody` | `res.send.js`, `res.sendFile.js`, `res.download.js`, `express.static.js` |\\n| `shouldNotHaveBody` | `res.send.js`, `res.redirect.js`, `express.static.js` |\\n| `shouldHaveHeader` | `res.sendFile.js`, `express.static.js` |\\n| `shouldNotHaveHeader` | `res.jsonp.js`, `res.download.js`, `res.vary.js`, `res.send.js`, `res.redirect.js`, `res.sendFile.js`, `cookies.js`, `express.static.js` |\\n\\n## Adding New Assertions\\n\\nWhen adding new helpers, follow the existing pattern:\\n\\n```javascript\\nfunction shouldHaveCustomProperty(prop) {\\n  return function (res) {\\n    assert.ok(prop in res.body, 'should have property ' + prop);\\n  };\\n}\\n\\nexports.shouldHaveCustomProperty = shouldHaveCustomProperty;\\n```\\n\\nAll assertion helpers:\\n1. Return a function that accepts a supertest response object\\n2. Use Node's built-in `assert` module\\n3. Include descriptive error messages\",\"overview\":\"# express \u2014 Wiki\\n\\n# Express\\n\\n**Fast, unopinionated, minimalist web framework for Node.js**\\n\\nExpress provides a thin layer of fundamental web application features without obscuring Node.js features you already know. It's designed to build web applications and APIs with minimal overhead, giving you the flexibility to structure your project however you see fit.\\n\\n## Architecture at a Glance\\n\\nExpress is built around a small, focused core that handles HTTP request/response processing, middleware orchestration, and routing. Everything else\u2014template rendering, static file serving, session management\u2014is either built on top of this core or provided through extensions.\\n\\n```mermaid\\ngraph TD\\n    A[HTTP Request] --&gt; B[Express App]\\n    B --&gt; C[Middleware Stack]\\n    C --&gt; D[Router]\\n    D --&gt; E[Route Handlers]\\n    E --&gt; F[Response]\\n    \\n    B --&gt; G[Request Prototype]\\n    B --&gt; H[Response Prototype]\\n    \\n    I[Views &amp; Templates] --&gt; E\\n    J[Static Files] --&gt; C\\n    K[Error Handling] --&gt; C\\n```\\n\\n## Core Concepts\\n\\nThe **[Core Framework](core-framework.md)** is the heart of Express. It creates the application instance, extends Node's `http.IncomingMessage` and `http.ServerResponse` with useful properties and methods, and implements the middleware system that makes Express so flexible. When you call `express()`, you're getting an application object that inherits from EventEmitter and manages a stack of middleware functions.\\n\\nRouting is handled lazily\u2014the router isn't initialized until the first route is defined, keeping the minimal footprint Express is known for.\\n\\n## Learning by Example\\n\\nThe repository includes a rich set of examples organized by feature area:\\n\\n- **[Basic Usage](basic-usage.md)** \u2014 Start here. The `hello-world` example shows the minimal Express server in about 10 lines, while the `search` example demonstrates a more realistic application with Redis integration.\\n\\n- **[Routing Patterns](routing-patterns.md)** \u2014 Once you're comfortable with basics, explore patterns for organizing routes: multi-router setups for API versioning, parameter preprocessing, RESTful resource conventions, and declarative route mapping.\\n\\n- **[Views &amp; Templates](views-templates.md)** \u2014 Express supports any template engine that follows the `(path, options, callback)` signature. This module shows how to register engines, render views, and pass data to templates.\\n\\n- **[Static Files &amp; Downloads](static-files-downloads.md)** \u2014 Serving CSS, JavaScript, and images with `express.static()`, plus triggering file downloads with proper error handling.\\n\\n- **[Error Handling](error-handling.md)** \u2014 Understanding Express's error-handling middleware is crucial for production applications. Learn the difference between regular and error-handling middleware, and how to structure error responses.\\n\\n- **[Web Services &amp; APIs](web-services-apis.md)** \u2014 Building REST APIs? This covers content negotiation, API key validation, virtual hosting for multi-tenant applications, and proper error responses.\\n\\n- **[Authentication &amp; Sessions](authentication-sessions.md)** \u2014 Example implementations for password-based authentication, cookie sessions, and Redis-backed session storage.\\n\\n## Getting Started\\n\\n### Prerequisites\\n\\n- Node.js (see `.nvmrc` or `package.json` for supported versions)\\n- npm or yarn\\n\\n### Installation\\n\\n```bash\\ngit clone https://github.com/expressjs/express.git\\ncd express\\nnpm install\\n```\\n\\n### Running Tests\\n\\nExpress has a comprehensive test suite. Run tests with:\\n\\n```bash\\nnpm test           # Run all tests\\nnpm run test-ci    # CI mode\\nnpm run test-cov   # With coverage\\n```\\n\\nCode quality is enforced via linting:\\n\\n```bash\\nnpm run lint       # Check for issues\\nnpm run lint:fix   # Auto-fix issues\\n```\\n\\n## Philosophy\\n\\nExpress is intentionally unopinionated. It provides the essential tools\u2014routing, middleware, request/response helpers\u2014without prescribing how you should structure your application, which template engine to use, or how to handle authentication. This minimalism is why Express works equally well for a simple API, a full-featured web application, or as a foundation for other frameworks.\\n\\n## Contributing\\n\\nThis project follows a [Code of Conduct](https://github.com/expressjs/express/blob/master/Code-of Conduct.md). See the repository's contributing guidelines and security policy for details on submitting pull requests and reporting vulnerabilities.\",\"routing-patterns\":\"# Routing Patterns\\n\\n# Routing Patterns\\n\\nThis module demonstrates several patterns for organizing and structuring routes in Express applications. Each example showcases a different approach to handling common routing scenarios.\\n\\n## Overview\\n\\nThe examples in this module cover:\\n\\n| Pattern | Location | Purpose |\\n|---------|----------|---------|\\n| Multi-Router | `multi-router/` | API versioning with separate routers |\\n| Route Parameters | `params/` | Parameter preprocessing and validation |\\n| Resource Routing | `resource/` | RESTful resource conventions |\\n| Route Mapping | `route-map/` | Declarative route configuration |\\n| Route Middleware | `route-middleware/` | Authentication and authorization chains |\\n| Route Separation | `route-separation/` | Modular route organization |\\n\\n---\\n\\n## Multi-Router Pattern\\n\\nOrganize multiple API versions using separate `Router` instances mounted at different paths.\\n\\n### Structure\\n\\n```\\nmulti-router/\\n\u251c\u2500\u2500 index.js              # Main app, mounts routers\\n\u2514\u2500\u2500 controllers/\\n    \u251c\u2500\u2500 api_v1.js         # API v1 routes\\n    \u2514\u2500\u2500 api_v2.js         # API v2 routes\\n```\\n\\n### Implementation\\n\\n**Main application** (`index.js`):\\n```javascript\\nvar app = express();\\n\\napp.use('/api/v1', require('./controllers/api_v1'));\\napp.use('/api/v2', require('./controllers/api_v2'));\\n```\\n\\n**Router modules** (`controllers/api_v1.js`):\\n```javascript\\nvar apiv1 = express.Router();\\n\\napiv1.get('/', function(req, res) {\\n  res.send('Hello from APIv1 root route.');\\n});\\n\\napiv1.get('/users', function(req, res) {\\n  res.send('List of APIv1 users.');\\n});\\n\\nmodule.exports = apiv1;\\n```\\n\\n### Resulting Routes\\n\\n| Path | Handler |\\n|------|---------|\\n| `/api/v1/` | APIv1 root |\\n| `/api/v1/users` | APIv1 users list |\\n| `/api/v2/` | APIv2 root |\\n| `/api/v2/users` | APIv2 users list |\\n\\n---\\n\\n## Route Parameters Pattern\\n\\nUse `app.param()` to preprocess route parameters before reaching route handlers.\\n\\n### Parameter Callbacks\\n\\nThe `app.param()` method registers middleware that executes when a named parameter appears in any route:\\n\\n```javascript\\n// Convert :to and :from to integers\\napp.param(['to', 'from'], function(req, res, next, num, name){\\n  req.params[name] = parseInt(num, 10);\\n  if( isNaN(req.params[name]) ){\\n    next(createError(400, 'failed to parseInt '+num));\\n  } else {\\n    next();\\n  }\\n});\\n\\n// Load user by id\\napp.param('user', function(req, res, next, id){\\n  req.user = users[id];\\n  if (req.user) {\\n    next();\\n  } else {\\n    next(createError(404, 'failed to find user'));\\n  }\\n});\\n```\\n\\n### Parameter Callback Signature\\n\\n```javascript\\nfunction(req, res, next, value, name)\\n```\\n\\n| Argument | Description |\\n|----------|-------------|\\n| `req` | Request object |\\n| `res` | Response object |\\n| `next` | Callback to continue |\\n| `value` | The parameter value from URL |\\n| `name` | The parameter name |\\n\\n### Routes Using Parameters\\n\\n```javascript\\n// Uses :user param (triggers user loading)\\napp.get('/user/:user', function (req, res) {\\n  res.send('user ' + req.user.name);\\n});\\n\\n// Uses :from and :to params (triggers integer conversion)\\napp.get('/users/:from-:to', function (req, res) {\\n  var from = req.params.from;\\n  var to = req.params.to;\\n  var names = users.map(function(user){ return user.name; });\\n  res.send('users ' + names.slice(from, to + 1).join(', '));\\n});\\n```\\n\\n---\\n\\n## Resource Routing Pattern\\n\\nCreate a custom `app.resource()` method that maps HTTP verbs to controller actions following REST conventions.\\n\\n### Resource Method Implementation\\n\\n```javascript\\napp.resource = function(path, obj) {\\n  this.get(path, obj.index);\\n  this.get(path + '/:a..:b{.:format}', function(req, res){\\n    var a = parseInt(req.params.a, 10);\\n    var b = parseInt(req.params.b, 10);\\n    var format = req.params.format;\\n    obj.range(req, res, a, b, format);\\n  });\\n  this.get(path + '/:id', obj.show);\\n  this.delete(path + '/:id', function(req, res){\\n    var id = parseInt(req.params.id, 10);\\n    obj.destroy(req, res, id);\\n  });\\n};\\n```\\n\\n### Controller Structure\\n\\n```javascript\\nvar User = {\\n  index: function(req, res){\\n    res.send(users);\\n  },\\n  show: function(req, res){\\n    res.send(users[req.params.id] || { error: 'Cannot find user' });\\n  },\\n  destroy: function(req, res, id){\\n    var destroyed = id in users;\\n    delete users[id];\\n    res.send(destroyed ? 'destroyed' : 'Cannot find user');\\n  },\\n  range: function(req, res, a, b, format){\\n    var range = users.slice(a, b + 1);\\n    switch (format) {\\n      case 'json':\\n        res.send(range);\\n        break;\\n      case 'html':\\n      default:\\n        var html = '\n' + range.map(function(user){\\n          return '\n' + user.name + '&lt;\\/li&gt;';\\n        }).join('\\\\n') + '&lt;\\/ul&gt;';\\n        res.send(html);\\n        break;\\n    }\\n  }\\n};\\n```\\n\\n### Generated Routes\\n\\n| HTTP Method | Path | Action |\\n|-------------|------|--------|\\n| GET | `/users` | `index` |\\n| GET | `/users/:id` | `show` |\\n| GET | `/users/:a..:b` | `range` |\\n| GET | `/users/:a..:b.json` | `range` (JSON format) |\\n| DELETE | `/users/:id` | `destroy` |\\n\\n---\\n\\n## Route Mapping Pattern\\n\\nDefine routes declaratively using nested objects that map to handler functions.\\n\\n### Map Implementation\\n\\n```javascript\\napp.map = function(a, route){\\n  route = route || '';\\n  for (var key in a) {\\n    switch (typeof a[key]) {\\n      // { '/path': { ... }}\\n      case 'object':\\n        app.map(a[key], route + key);\\n        break;\\n      // get: function(){ ... }\\n      case 'function':\\n        if (verbose) console.log('%s %s', key, route);\\n        app[key](route, a[key]);\\n        break;\\n    }\\n  }\\n};\\n```\\n\\n### Declarative Route Definition\\n\\n```javascript\\napp.map({\\n  '/users': {\\n    get: users.list,\\n    delete: users.delete,\\n    '/:uid': {\\n      get: users.get,\\n      '/pets': {\\n        get: pets.list,\\n        '/:pid': {\\n          delete: pets.delete\\n        }\\n      }\\n    }\\n  }\\n});\\n```\\n\\n### Generated Routes\\n\\n| HTTP Method | Path | Handler |\\n|-------------|------|---------|\\n| GET | `/users` | `users.list` |\\n| DELETE | `/users` | `users.delete` |\\n| GET | `/users/:uid` | `users.get` |\\n| GET | `/users/:uid/pets` | `pets.list` |\\n| DELETE | `/users/:uid/pets/:pid` | `pets.delete` |\\n\\n---\\n\\n## Route Middleware Pattern\\n\\nChain middleware functions for authentication, authorization, and data loading.\\n\\n### Middleware Functions\\n\\n```javascript\\n// Load user from database\\nfunction loadUser(req, res, next) {\\n  var user = users[req.params.id];\\n  if (user) {\\n    req.user = user;\\n    next();\\n  } else {\\n    next(new Error('Failed to load user ' + req.params.id));\\n  }\\n}\\n\\n// Restrict to the authenticated user\\nfunction andRestrictToSelf(req, res, next) {\\n  if (req.authenticatedUser.id === req.user.id) {\\n    next();\\n  } else {\\n    next(new Error('Unauthorized'));\\n  }\\n}\\n\\n// Restrict to specific role (factory function)\\nfunction andRestrictTo(role) {\\n  return function(req, res, next) {\\n    if (req.authenticatedUser.role === role) {\\n      next();\\n    } else {\\n      next(new Error('Unauthorized'));\\n    }\\n  }\\n}\\n```\\n\\n### Middleware Chains in Routes\\n\\n```javascript\\n// Chain: load user \u2192 render\\napp.get('/user/:id', loadUser, function(req, res){\\n  res.send('Viewing user ' + req.user.name);\\n});\\n\\n// Chain: load user \u2192 check self \u2192 render\\napp.get('/user/:id/edit', loadUser, andRestrictToSelf, function(req, res){\\n  res.send('Editing user ' + req.user.name);\\n});\\n\\n// Chain: load user \u2192 check role \u2192 render\\napp.delete('/user/:id', loadUser, andRestrictTo('admin'), function(req, res){\\n  res.send('Deleted user ' + req.user.name);\\n});\\n```\\n\\n### Request Flow\\n\\n```mermaid\\nflowchart LR\\n    A[Request] --&gt; B[Auth Middleware]\\n    B --&gt; C[loadUser]\\n    C --&gt; D{Authorization}\\n    D --&gt;|Authorized| E[Route Handler]\\n    D --&gt;|Denied| F[Error]\\n```\\n\\n---\\n\\n## Route Separation Pattern\\n\\nOrganize routes into separate modules by domain (users, posts, etc.) with shared configuration.\\n\\n### Directory Structure\\n\\n```\\nroute-separation/\\n\u251c\u2500\u2500 index.js          # Main app with route mounting\\n\u251c\u2500\u2500 site.js           # Site-level routes\\n\u251c\u2500\u2500 user.js           # User routes and handlers\\n\u251c\u2500\u2500 post.js           # Post routes and handlers\\n\u251c\u2500\u2500 public/\\n\u2502   \u2514\u2500\u2500 style.css     # Static assets\\n\u2514\u2500\u2500 views/\\n    \u251c\u2500\u2500 header.ejs\\n    \u251c\u2500\u2500 footer.ejs\\n    \u251c\u2500\u2500 index.ejs\\n    \u251c\u2500\u2500 posts/\\n    \u2502   \u2514\u2500\u2500 index.ejs\\n    \u2514\u2500\u2500 users/\\n        \u251c\u2500\u2500 index.ejs\\n        \u251c\u2500\u2500 view.ejs\\n        \u2514\u2500\u2500 edit.ejs\\n```\\n\\n### Main Application (`index.js`)\\n\\n```javascript\\nvar app = express();\\n\\n// Configuration\\napp.set('view engine', 'ejs');\\napp.set('views', path.join(__dirname, 'views'));\\n\\n// Middleware\\napp.use(methodOverride('_method'));\\napp.use(cookieParser());\\napp.use(express.urlencoded({ extended: true }));\\napp.use(express.static(path.join(__dirname, 'public')));\\n\\n// Routes organized by domain\\napp.get('/', site.index);\\napp.get('/users', user.list);\\napp.all('/user/:id{/:op}', user.load);\\napp.get('/user/:id', user.view);\\napp.get('/user/:id/view', user.view);\\napp.get('/user/:id/edit', user.edit);\\napp.put('/user/:id/edit', user.update);\\napp.get('/posts', post.list);\\n```\\n\\n### Module Exports Pattern (`user.js`)\\n\\n```javascript\\nvar users = [\\n  { name: 'TJ', email: 'tj@vision-media.ca' },\\n  { name: 'Tobi', email: 'tobi@vision-media.ca' }\\n];\\n\\nexports.list = function(req, res){\\n  res.render('users', { title: 'Users', users: users });\\n};\\n\\nexports.load = function(req, res, next){\\n  var id = req.params.id;\\n  req.user = users[id];\\n  if (req.user) {\\n    next();\\n  } else {\\n    var err = new Error('cannot find user ' + id);\\n    err.status = 404;\\n    next(err);\\n  }\\n};\\n\\nexports.view = function(req, res){\\n  res.render('users/view', {\\n    title: 'Viewing user ' + req.user.name,\\n    user: req.user\\n  });\\n};\\n```\\n\\n### Shared Middleware with `app.all()`\\n\\nThe `app.all('/user/:id{/:op}', user.load)` pattern runs `user.load` for all HTTP methods matching the path, enabling shared data loading across multiple routes.\\n\\n---\\n\\n## Pattern Selection Guide\\n\\n| Scenario | Recommended Pattern |\\n|----------|---------------------|\\n| API versioning | Multi-Router |\\n| Parameter validation | Route Parameters |\\n| RESTful resources | Resource Routing |\\n| Configuration-heavy apps | Route Mapping |\\n| Auth/permission chains | Route Middleware |\\n| Large applications | Route Separation |\\n\\n## Common Patterns Across Examples\\n\\n### Error Handling in Middleware\\n\\n```javascript\\n// Pass errors to Express error handler\\nif (condition) {\\n  next();\\n} else {\\n  next(new Error('Description'));\\n  // or with status\\n  var err = new Error('Not found');\\n  err.status = 404;\\n  next(err);\\n}\\n```\\n\\n### Optional Route Segments\\n\\n```javascript\\n// Optional :op parameter\\napp.all('/user/:id{/:op}', user.load);\\n```\\n\\n### Range Parameters\\n\\n```javascript\\n// Custom range syntax\\napp.get('/users/:from-:to', handler);\\napp.get('/users/:a..:b{.:format}', handler);\\n```\",\"static-files-downloads\":\"# Static Files &amp; Downloads\\n\\n# Static Files &amp; Downloads Module\\n\\nThis module provides example implementations demonstrating two approaches to file handling in Express: serving static assets and triggering file downloads.\\n\\n## Overview\\n\\nThe module consists of two independent example applications:\\n\\n| Application | Purpose | Key Method |\\n|-------------|---------|------------|\\n| `static-files` | Serve static assets (CSS, JS, images) | `express.static()` |\\n| `downloads` | Trigger file downloads with error handling | `res.download()` |\\n\\n---\\n\\n## Static Files Server\\n\\n**Location:** `examples/static-files/index.js`\\n\\n### How It Works\\n\\nThe static files server demonstrates three patterns for serving static assets using Express's built-in middleware.\\n\\n```javascript\\napp.use(express.static(path.join(__dirname, 'public')));\\n```\\n\\nThis middleware intercepts requests and checks if a file matching `req.path` exists in the specified directory. If found, it streams the file as the response.\\n\\n### Serving Patterns\\n\\n**1. Basic Static Serving**\\n```javascript\\napp.use(express.static(path.join(__dirname, 'public')));\\n```\\nServes files directly from `./public`. A request for `/js/app.js` resolves to `./public/js/app.js`.\\n\\n**2. Mounted Path Prefix**\\n```javascript\\napp.use('/static', express.static(path.join(__dirname, 'public')));\\n```\\nAdds a URL prefix. A request for `/static/js/app.js` serves `./public/js/app.js` \u2014 the `/static` prefix is stripped before resolving.\\n\\n**3. Multiple Directories**\\n```javascript\\napp.use(express.static(path.join(__dirname, 'public', 'css')));\\n```\\nServes files from a nested directory at the root path. A request for `/style.css` serves `./public/css/style.css`.\\n\\n### File Structure\\n\\n```\\nstatic-files/\\n\u251c\u2500\u2500 index.js\\n\u2514\u2500\u2500 public/\\n    \u251c\u2500\u2500 hello.txt\\n    \u251c\u2500\u2500 css/\\n    \u2502   \u2514\u2500\u2500 style.css\\n    \u2514\u2500\u2500 js/\\n        \u2514\u2500\u2500 app.js\\n```\\n\\n### Endpoints\\n\\n| URL | File Served |\\n|-----|-------------|\\n| `GET /hello.txt` | `public/hello.txt` |\\n| `GET /js/app.js` | `public/js/app.js` |\\n| `GET /css/style.css` | `public/css/style.css` |\\n| `GET /static/hello.txt` | `public/hello.txt` (via mounted path) |\\n\\n---\\n\\n## File Downloads Server\\n\\n**Location:** `examples/downloads/index.js`\\n\\n### How It Works\\n\\nThe downloads server uses `res.download()` to prompt browsers to save files rather than display them.\\n\\n```javascript\\napp.get('/files/*file', function (req, res, next) {\\n  res.download(req.params.file.join('/'), { root: FILES_DIR }, function (err) {\\n    if (!err) return;\\n    if (err.status !== 404) return next(err);\\n    res.statusCode = 404;\\n    res.send('Cant find that file, sorry!');\\n  });\\n});\\n```\\n\\n### Route Pattern Breakdown\\n\\nThe route `/files/*file` uses a wildcard parameter:\\n- `*file` captures all path segments after `/files/`\\n- `req.params.file` is an array of path segments\\n- `req.params.file.join('/')` reconstructs the file path\\n\\n**Example:** Request to `/files/notes/groceries.txt` produces:\\n- `req.params.file = ['notes', 'groceries.txt']`\\n- Resolved path: `FILES_DIR/notes/groceries.txt`\\n\\n### Error Handling\\n\\nThe callback to `res.download()` handles three scenarios:\\n\\n| Condition | Behavior |\\n|-----------|----------|\\n| No error | File sent successfully, return early |\\n| Non-404 error | Pass to `next(err)` for Express error handling |\\n| 404 error | Send custom \\\"file not found\\\" message |\\n\\n### File Structure\\n\\n```\\ndownloads/\\n\u251c\u2500\u2500 index.js\\n\u2514\u2500\u2500 files/\\n    \u251c\u2500\u2500 amazing.txt\\n    \u251c\u2500\u2500 CCTV\u5927\u8d5b\u4e0a\u6d77\u5206\u8d5b\u533a.txt\\n    \u2514\u2500\u2500 notes/\\n        \u2514\u2500\u2500 groceries.txt\\n```\\n\\n### Endpoints\\n\\n| URL | Result |\\n|-----|--------|\\n| `GET /` | HTML page with download links |\\n| `GET /files/amazing.txt` | Downloads `files/amazing.txt` |\\n| `GET /files/notes/groceries.txt` | Downloads `files/notes/groceries.txt` |\\n| `GET /files/CCTV\u5927\u8d5b\u4e0a\u6d77\u5206\u8d5b\u533a.txt` | Downloads file with Unicode filename |\\n| `GET /files/missing.txt` | Custom 404 response |\\n\\n---\\n\\n## Key Differences\\n\\n```mermaid\\nflowchart LR\\n    subgraph Static[\\\"express.static()\\\"]\\n        A[Request] --&gt; B{File exists?}\\n        B --&gt;|Yes| C[Stream file]\\n        B --&gt;|No| D[Next middleware]\\n    end\\n    \\n    subgraph Download[\\\"res.download()\\\"]\\n        E[Request] --&gt; F{File exists?}\\n        F --&gt;|Yes| G[Set headerstrigger download]\\n        F --&gt;|No| H[Custom error handling]\\n    end\\n```\\n\\n| Aspect | `express.static()` | `res.download()` |\\n|--------|-------------------|------------------|\\n| Use case | Assets (CSS, JS, images) | User downloads |\\n| Browser behavior | Display inline | Save dialog |\\n| Content-Disposition | Not set | `attachment` |\\n| Error handling | Automatic 404 | Manual via callback |\\n| Scope | Middleware (all routes) | Route handler (specific paths) |\\n\\n---\\n\\n## Running the Examples\\n\\n**Static Files:**\\n```bash\\nnode examples/static-files/index.js\\n# Listening on port 3000\\n# Test: GET /hello.txt, GET /js/app.js, GET /css/style.css\\n```\\n\\n**Downloads:**\\n```bash\\nnode examples/downloads/index.js\\n# Express started on port 3000\\n# Navigate to http://localhost:3000 for download links\\n```\\n\\n---\\n\\n## Security Considerations\\n\\nThe downloads example uses `{ root: FILES_DIR }` to prevent directory traversal attacks. Without this option, a malicious path like `/files/../../../etc/passwd` could access files outside the intended directory.\\n\\nWith `root` specified, Express resolves paths relative to `FILES_DIR` and rejects attempts to escape it.\",\"views-templates\":\"# Views &amp; Templates\\n\\n# Views &amp; Templates\\n\\nExpress provides a flexible view system that supports multiple template engines, custom view resolution, and various patterns for passing data to templates. This module demonstrates the core concepts through practical examples.\\n\\n## Core Concepts\\n\\n### Template Engine Registration\\n\\nExpress uses a callback-based system for template engines. Register an engine using `app.engine(ext, callback)`:\\n\\n```javascript\\n// Register EJS to handle .html files\\napp.engine('.html', require('ejs').__express);\\n\\n// Custom markdown engine\\napp.engine('md', function(path, options, fn){\\n  fs.readFile(path, 'utf8', function(err, str){\\n    if (err) return fn(err);\\n    var html = marked.parse(str).replace(/\\\\{([^}]+)\\\\}/g, function(_, name){\\n      return escapeHtml(options[name] || '');\\n    });\\n    fn(null, html);\\n  });\\n});\\n```\\n\\nThe engine callback receives:\\n- `path` - the absolute path to the template file\\n- `options` - data locals passed to the view\\n- `fn` - callback `(err, renderedString)`\\n\\n### View Configuration Settings\\n\\n```javascript\\n// Set views directory (default: process.cwd() + '/views')\\napp.set('views', path.join(__dirname, 'views'));\\n\\n// Set default engine extension (avoids specifying extension in res.render)\\napp.set('view engine', 'html');\\n\\n// Register custom View constructor (advanced)\\napp.set('view', GithubView);\\n```\\n\\n### Rendering Views\\n\\n```javascript\\n// Basic render\\nres.render('users');\\n\\n// With locals\\nres.render('users', { \\n  users: users, \\n  title: \\\"User List\\\" \\n});\\n\\n// With callback for custom handling\\nres.render('template', { title: 'Page' }, function(err, html) {\\n  if (err) return next(err);\\n  // Process html before sending\\n});\\n```\\n\\n## View Resolution Flow\\n\\n```mermaid\\nflowchart TD\\n    A[res.render 'template'] --&gt; B{View engine set?}\\n    B --&gt;|Yes| C[Use default engine]\\n    B --&gt;|No| D{Extension in name?}\\n    D --&gt;|Yes| E[Lookup engine by extension]\\n    D --&gt;|No| F[Throw error]\\n    C --&gt; G[Resolve path in views directory]\\n    E --&gt; G\\n    G --&gt; H[Read template file]\\n    H --&gt; I[Compile with engine]\\n    I --&gt; J[Merge app.locals + res.locals + passed locals]\\n    J --&gt; K[Return rendered HTML]\\n```\\n\\n## Passing Data to Views\\n\\n### Approach 1: Direct Locals in res.render()\\n\\n```javascript\\napp.get('/', function(req, res, next){\\n  User.count(function(err, count){\\n    if (err) return next(err);\\n    User.all(function(err, users){\\n      if (err) return next(err);\\n      res.render('index', {\\n        title: 'Users',\\n        count: count,\\n        users: users.filter(ferrets)\\n      });\\n    });\\n  });\\n});\\n```\\n\\n### Approach 2: Middleware with req Properties\\n\\n```javascript\\nfunction count(req, res, next) {\\n  User.count(function(err, count){\\n    if (err) return next(err);\\n    req.count = count;\\n    next();\\n  });\\n}\\n\\nfunction users(req, res, next) {\\n  User.all(function(err, users){\\n    if (err) return next(err);\\n    req.users = users;\\n    next();\\n  });\\n}\\n\\napp.get('/middleware', count, users, function (req, res) {\\n  res.render('index', {\\n    title: 'Users',\\n    count: req.count,\\n    users: req.users.filter(ferrets)\\n  });\\n});\\n```\\n\\n### Approach 3: Middleware with res.locals\\n\\n`res.locals` is automatically merged into the view context:\\n\\n```javascript\\nfunction count(req, res, next) {\\n  User.count(function(err, count){\\n    if (err) return next(err);\\n    res.locals.count = count;\\n    next();\\n  });\\n}\\n\\nfunction users(req, res, next) {\\n  User.all(function(err, users){\\n    if (err) return next(err);\\n    res.locals.users = users.filter(ferrets);\\n    next();\\n  });\\n}\\n\\napp.get('/middleware-locals', count, users, function (req, res) {\\n  // Only need to pass title - count and users already in res.locals\\n  res.render('index', { title: 'Users' });\\n});\\n```\\n\\n### Global Locals via Middleware\\n\\n```javascript\\n// Make data available to all views\\napp.use(function(req, res, next){\\n  res.locals.user = req.user;\\n  res.locals.sess = req.session;\\n  next();\\n});\\n\\n// Or scoped to specific paths\\napp.use('/api', function(req, res, next){\\n  res.locals.user = req.user;\\n  next();\\n});\\n```\\n\\n## Custom View Constructor\\n\\nFor advanced use cases like loading templates from a database or remote source, implement a custom View class:\\n\\n```javascript\\nfunction GithubView(name, options){\\n  this.name = name;\\n  options = options || {};\\n  this.engine = options.engines[path.extname(name)];\\n  // options.root is the app.set('views') setting\\n  this.path = '/' + options.root + '/master/' + name;\\n}\\n\\nGithubView.prototype.render = function(options, fn){\\n  var self = this;\\n  https.get({\\n    host: 'raw.githubusercontent.com',\\n    path: this.path\\n  }, function(res) {\\n    var buf = '';\\n    res.setEncoding('utf8');\\n    res.on('data', function(str){ buf += str });\\n    res.on('end', function(){\\n      self.engine(buf, options, fn);\\n    });\\n  });\\n};\\n\\n// Register the custom view\\napp.set('view', GithubView);\\napp.set('views', 'expressjs/express');\\n```\\n\\nThe View constructor receives:\\n- `name` - the template name passed to `res.render()`\\n- `options` - contains `engines` (map of registered engines) and `root` (views directory)\\n\\nThe `render(options, fn)` method must call `fn(err, html)` with the rendered output.\\n\\n## MVC Pattern with Per-Controller Views\\n\\nThe MVC example demonstrates organizing views by controller:\\n\\n```\\ncontrollers/\\n\u251c\u2500\u2500 user/\\n\u2502   \u251c\u2500\u2500 index.js      # Controller logic\\n\u2502   \u2514\u2500\u2500 views/\\n\u2502       \u251c\u2500\u2500 list.hbs\\n\u2502       \u251c\u2500\u2500 show.hbs\\n\u2502       \u2514\u2500\u2500 edit.hbs\\n\u251c\u2500\u2500 pet/\\n\u2502   \u251c\u2500\u2500 index.js\\n\u2502   \u2514\u2500\u2500 views/\\n\u2502       \u251c\u2500\u2500 show.ejs\\n\u2502       \u2514\u2500\u2500 edit.ejs\\n```\\n\\nEach controller configures its own view engine:\\n\\n```javascript\\n// controllers/user/index.js\\nexports.engine = 'hbs';  // Use Handlebars for this controller\\n\\n// In the boot loader:\\nif (obj.engine) app.set('view engine', obj.engine);\\napp.set('views', path.join(__dirname, '..', 'controllers', name, 'views'));\\n```\\n\\n### Route Generation from Controller Exports\\n\\nControllers export methods that map to conventional routes:\\n\\n| Export | Method | Generated Route |\\n|--------|--------|-----------------|\\n| `index` | GET | `/` |\\n| `list` | GET | `/:name+s` |\\n| `show` | GET | `/:name/:name_id` |\\n| `edit` | GET | `/:name/:name_id/edit` |\\n| `update` | PUT | `/:name/:name_id` |\\n| `create` | POST | `/:name` |\\n\\n```javascript\\n// controllers/pet/index.js\\nexports.before = function(req, res, next){\\n  var pet = db.pets[req.params.pet_id];\\n  if (!pet) return next('route');\\n  req.pet = pet;\\n  next();\\n};\\n\\nexports.show = function(req, res, next){\\n  res.render('show', { pet: req.pet });\\n};\\n```\\n\\nThe `before` middleware runs before the handler, useful for loading resources.\\n\\n## Template Examples\\n\\n### EJS with Partials\\n\\n```html\\n&lt;%- include('header.html') -%&gt;\\n\\n\nUsers&lt;\\/h1&gt;\\n\n\\n  &lt;% users.forEach(function(user){ %&gt;\\n    \n&lt;%= user.name %&gt; &lt;&lt;%= user.email %&gt;&gt;&lt;\\/li&gt;\\n  &lt;% }) %&gt;\\n&lt;\\/ul&gt;\\n\\n&lt;%- include('footer.html') -%&gt;\\n```\\n\\n### Handlebars Conditionals\\n\\n```html\\n{{#if user.pets.length}}\\n  \n\\n    {{#each user.pets}}\\n      \n{{name}}&lt;\\/a&gt;&lt;\\/li&gt;\\n    {{/each}}\\n  &lt;\\/ul&gt;\\n{{else}}\\n  \nNo pets!&lt;\\/p&gt;\\n{{/if}}\\n```\\n\\n### Markdown with Variable Substitution\\n\\n```markdown\\n# {title}\\n\\nJust an example view rendered with _markdown_.\\n```\\n\\nVariables are replaced via regex: `/\\\\{([^}]+)\\\\}/g`\\n\\n## Flash Messages Pattern\\n\\nStore messages in the session and expose to views via middleware:\\n\\n```javascript\\n// Custom response method\\napp.response.message = function(msg){\\n  var sess = this.req.session;\\n  sess.messages = sess.messages || [];\\n  sess.messages.push(msg);\\n  return this;\\n};\\n\\n// Expose to views\\napp.use(function(req, res, next){\\n  var msgs = req.session.messages || [];\\n  res.locals.messages = msgs;\\n  res.locals.hasMessages = !!msgs.length;\\n  next();\\n  req.session.messages = [];  // Clear after exposing\\n});\\n```\\n\\nIn the template:\\n\\n```html\\n{{#if hasMessages}}\\n  \n\\n    {{#each messages}}\\n      \n{{this}}&lt;\\/li&gt;\\n    {{/each}}\\n  &lt;\\/ul&gt;\\n{{/if}}\\n```\\n\\n## Error Views\\n\\n```javascript\\n// 500 error handler\\napp.use(function(err, req, res, next){\\n  console.error(err.stack);\\n  res.status(500).render('5xx');\\n});\\n\\n// 404 handler (must be last)\\napp.use(function(req, res, next){\\n  res.status(404).render('404', { url: req.originalUrl });\\n});\\n```\",\"web-services-apis\":\"# Web Services &amp; APIs\\n\\n# Web Services &amp; APIs Module\\n\\nThis module demonstrates production-ready patterns for building RESTful web services and APIs with Express.js, covering content negotiation, virtual hosting, API key validation, and error handling.\\n\\n## Overview\\n\\nThe module contains three interconnected examples that showcase different aspects of API development:\\n\\n| Example | Purpose |\\n|---------|---------|\\n| `content-negotiation` | Multi-format response handling (HTML, JSON, text) |\\n| `web-service` | REST API with authentication middleware and error handling |\\n| `vhost` | Virtual hosting for multi-tenant applications |\\n\\n## Content Negotiation\\n\\nThe content negotiation example demonstrates how to serve the same data in multiple formats based on the client's `Accept` header.\\n\\n### Architecture\\n\\n```\\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\\n\u2502                     Client Request                          \u2502\\n\u2502                  Accept: text/html                          \u2502\\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\\n                          \u2502\\n                          \u25bc\\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\\n\u2502                    res.format()                             \u2502\\n\u2502         Inspects Accept header and routes                   \u2502\\n\u2502         to appropriate handler                              \u2502\\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\\n           \u2502          \u2502             \u2502\\n     html()\u2502    text()\u2502       json()\u2502\\n           \u25bc          \u25bc             \u25bc\\n      HTML list   Plain text    JSON array\\n```\\n\\n### Two Implementation Patterns\\n\\n**Pattern 1: Inline Handlers** (`/` endpoint)\\n\\n```javascript\\napp.get('/', function(req, res){\\n  res.format({\\n    html: function(){ /* render HTML */ },\\n    text: function(){ /* render plain text */ },\\n    json: function(){ res.json(users); }\\n  });\\n});\\n```\\n\\n**Pattern 2: Declarative Middleware** (`/users` endpoint)\\n\\nThe `format()` helper function abstracts handler definitions into a separate module:\\n\\n```javascript\\nfunction format(path) {\\n  var obj = require(path);\\n  return function(req, res){\\n    res.format(obj);\\n  };\\n}\\n\\napp.get('/users', format('./users'));\\n```\\n\\nThe `users.js` module exports format handlers as separate functions:\\n\\n```javascript\\nexports.html = function(req, res){ /* ... */ };\\nexports.text = function(req, res){ /* ... */ };\\nexports.json = function(req, res){ res.json(users); };\\n```\\n\\n### Data Layer\\n\\nThe `db.js` module provides a simple in-memory data store:\\n\\n```javascript\\nvar users = [];\\nusers.push({ name: 'Tobi' });\\nusers.push({ name: 'Loki' });\\nusers.push({ name: 'Jane' });\\nmodule.exports = users;\\n```\\n\\n## Web Service API\\n\\nThe `web-service` example demonstrates a complete REST API with middleware-based authentication and structured error handling.\\n\\n### Request Flow\\n\\n```mermaid\\nflowchart TD\\n    A[Request] --&gt; B{API Key Present?}\\n    B --&gt;|No| C[400: api key required]\\n    B --&gt;|Yes| D{Valid Key?}\\n    D --&gt;|No| E[401: invalid api key]\\n    D --&gt;|Yes| F[Route Handler]\\n    F --&gt; G{Data Found?}\\n    G --&gt;|Yes| H[200: JSON Response]\\n    G --&gt;|No| I[404: Not Found]\\n    \\n    C --&gt; J[Error Handler]\\n    E --&gt; J\\n    I --&gt; K[404 Middleware]\\n```\\n\\n### API Key Validation Middleware\\n\\nThe middleware is mounted at `/api`, ensuring all API routes require authentication:\\n\\n```javascript\\napp.use('/api', function(req, res, next){\\n  var key = req.query['api-key'];\\n  \\n  if (!key) return next(error(400, 'api key required'));\\n  if (apiKeys.indexOf(key) === -1) return next(error(401, 'invalid api key'));\\n  \\n  req.key = key;  // Store for route access\\n  next();\\n});\\n```\\n\\n**Valid API Keys**: `foo`, `bar`, `baz`\\n\\n### Available Endpoints\\n\\n| Endpoint | Description | Example |\\n|----------|-------------|---------|\\n| `GET /api/users` | List all users | `/api/users/?api-key=foo` |\\n| `GET /api/repos` | List all repositories | `/api/repos/?api-key=foo` |\\n| `GET /api/user/:name/repos` | Get user's repositories | `/api/user/tobi/repos/?api-key=foo` |\\n\\n### Data Models\\n\\n```javascript\\n// Repositories\\nvar repos = [\\n  { name: 'express', url: 'https://github.com/expressjs/express' },\\n  { name: 'stylus', url: 'https://github.com/learnboost/stylus' },\\n  { name: 'cluster', url: 'https://github.com/learnboost/cluster' }\\n];\\n\\n// Users\\nvar users = [\\n  { name: 'tobi' },\\n  { name: 'loki' },\\n  { name: 'jane' }\\n];\\n\\n// User-Repository mapping\\nvar userRepos = {\\n  tobi: [repos[0], repos[1]],\\n  loki: [repos[1]],\\n  jane: [repos[2]]\\n};\\n```\\n\\n### Error Handling\\n\\n**Custom Error Factory**\\n\\n```javascript\\nfunction error(status, msg) {\\n  var err = new Error(msg);\\n  err.status = status;\\n  return err;\\n}\\n```\\n\\n**Error Handler Middleware** (4-arity function)\\n\\n```javascript\\napp.use(function(err, req, res, next){\\n  res.status(err.status || 500);\\n  res.send({ error: err.message });\\n});\\n```\\n\\n**404 Fallback Middleware**\\n\\n```javascript\\napp.use(function(req, res){\\n  res.status(404);\\n  res.send({ error: \\\"Sorry, can't find that\\\" });\\n});\\n```\\n\\n## Virtual Hosting\\n\\nThe `vhost` example demonstrates routing requests to different applications based on the hostname.\\n\\n### Host Configuration\\n\\nAdd to `/etc/hosts`:\\n```\\n127.0.0.1       foo.example.com\\n127.0.0.1       bar.example.com\\n127.0.0.1       example.com\\n```\\n\\n### Architecture\\n\\n```mermaid\\nflowchart LR\\n    A[Request] --&gt; B{vhost router}\\n    B --&gt;|*.example.com| C[Redirect App]\\n    B --&gt;|example.com| D[Main App]\\n    C --&gt; E[Redirect to /:subdomain]\\n    D --&gt; F[Serve main content]\\n```\\n\\n### Application Structure\\n\\n**Main Application** (`main`)\\n\\n```javascript\\nvar main = express();\\nmain.get('/', function(req, res){\\n  res.send('Hello from main app!');\\n});\\nmain.get('/:sub', function(req, res){\\n  res.send('requested ' + req.params.sub);\\n});\\n```\\n\\n**Redirect Application** (`redirect`)\\n\\n```javascript\\nvar redirect = express();\\nredirect.use(function(req, res){\\n  res.redirect('http://example.com:3000/' + req.vhost[0]);\\n});\\n```\\n\\n**Vhost Router** (`app`)\\n\\n```javascript\\nvar app = express();\\napp.use(vhost('*.example.com', redirect));\\napp.use(vhost('example.com', main));\\n```\\n\\n### Request Routing Examples\\n\\n| Request URL | Routed To | Response |\\n|-------------|-----------|----------|\\n| `http://example.com:3000/` | Main app | \\\"Hello from main app!\\\" |\\n| `http://example.com:3000/test` | Main app | \\\"requested test\\\" |\\n| `http://foo.example.com:3000/` | Redirect app | Redirect to `/foo` |\\n| `http://bar.example.com:3000/` | Redirect app | Redirect to `/bar` |\\n\\n## Running the Examples\\n\\nEach example runs independently on port 3000:\\n\\n```bash\\n# Content negotiation\\nnode examples/content-negotiation/index.js\\n\\n# Web service API\\nnode examples/web-service/index.js\\n\\n# Virtual hosting\\nnode examples/vhost/index.js\\n```\\n\\n## Key Patterns Summary\\n\\n1. **Content Negotiation**: Use `res.format()` to serve multiple content types from a single endpoint\\n2. **Middleware Authentication**: Mount validation middleware at a path prefix to protect all sub-routes\\n3. **Error Propagation**: Use `next(err)` with custom error objects and handle with 4-arity middleware\\n4. **Virtual Hosting**: Use `vhost()` middleware to route by hostname to different Express applications\"};\nvar TREE = [{\"name\":\"Core Framework\",\"slug\":\"core-framework\",\"files\":[\"index.js\",\"lib/application.js\",\"lib/express.js\",\"lib/request.js\",\"lib/response.js\",\"lib/utils.js\",\"lib/view.js\"]},{\"name\":\"Authentication &amp; Sessions\",\"slug\":\"authentication-sessions\",\"files\":[\"examples/auth/index.js\",\"examples/auth/views/foot.ejs\",\"examples/auth/views/head.ejs\",\"examples/auth/views/login.ejs\",\"examples/cookie-sessions/index.js\",\"examples/cookies/index.js\",\"examples/online/index.js\",\"examples/session/index.js\",\"examples/session/redis.js\"]},{\"name\":\"Routing Patterns\",\"slug\":\"routing-patterns\",\"files\":[\"examples/multi-router/controllers/api_v1.js\",\"examples/multi-router/controllers/api_v2.js\",\"examples/multi-router/index.js\",\"examples/params/index.js\",\"examples/resource/index.js\",\"examples/route-map/index.js\",\"examples/route-middleware/index.js\",\"examples/route-separation/index.js\",\"examples/route-separation/post.js\",\"examples/route-separation/public/style.css\",\"examples/route-separation/site.js\",\"examples/route-separation/user.js\",\"examples/route-separation/views/footer.ejs\",\"examples/route-separation/views/header.ejs\",\"examples/route-separation/views/index.ejs\",\"examples/route-separation/views/posts/index.ejs\",\"examples/route-separation/views/users/edit.ejs\",\"examples/route-separation/views/users/index.ejs\",\"examples/route-separation/views/users/view.ejs\"]},{\"name\":\"Views &amp; Templates\",\"slug\":\"views-templates\",\"files\":[\"examples/ejs/index.js\",\"examples/ejs/public/stylesheets/style.css\",\"examples/ejs/views/footer.html\",\"examples/ejs/views/header.html\",\"examples/ejs/views/users.html\",\"examples/markdown/index.js\",\"examples/markdown/views/index.md\",\"examples/mvc/controllers/main/index.js\",\"examples/mvc/controllers/pet/index.js\",\"examples/mvc/controllers/pet/views/edit.ejs\",\"examples/mvc/controllers/pet/views/show.ejs\",\"examples/mvc/controllers/user-pet/index.js\",\"examples/mvc/controllers/user/index.js\",\"examples/mvc/controllers/user/views/edit.hbs\",\"examples/mvc/controllers/user/views/list.hbs\",\"examples/mvc/controllers/user/views/show.hbs\",\"examples/mvc/db.js\",\"examples/mvc/index.js\",\"examples/mvc/lib/boot.js\",\"examples/mvc/public/style.css\",\"examples/mvc/views/404.ejs\",\"examples/mvc/views/5xx.ejs\",\"examples/view-constructor/github-view.js\",\"examples/view-constructor/index.js\",\"examples/view-locals/index.js\",\"examples/view-locals/user.js\",\"examples/view-locals/views/index.ejs\"]},{\"name\":\"Static Files &amp; Downloads\",\"slug\":\"static-files-downloads\",\"files\":[\"examples/downloads/files/CCTV\u5927\u8d5b\u4e0a\u6d77\u5206\u8d5b\u533a.txt\",\"examples/downloads/files/amazing.txt\",\"examples/downloads/files/notes/groceries.txt\",\"examples/downloads/index.js\",\"examples/static-files/index.js\",\"examples/static-files/public/css/style.css\",\"examples/static-files/public/hello.txt\",\"examples/static-files/public/js/app.js\"]},{\"name\":\"Error Handling\",\"slug\":\"error-handling\",\"files\":[\"examples/error-pages/index.js\",\"examples/error-pages/views/404.ejs\",\"examples/error-pages/views/500.ejs\",\"examples/error-pages/views/error_header.ejs\",\"examples/error-pages/views/footer.ejs\",\"examples/error-pages/views/index.ejs\",\"examples/error/index.js\"]},{\"name\":\"Web Services &amp; APIs\",\"slug\":\"web-services-apis\",\"files\":[\"examples/content-negotiation/db.js\",\"examples/content-negotiation/index.js\",\"examples/content-negotiation/users.js\",\"examples/vhost/index.js\",\"examples/web-service/index.js\"]},{\"name\":\"Basic Usage\",\"slug\":\"basic-usage\",\"files\":[\"examples/hello-world/index.js\",\"examples/search/index.js\",\"examples/search/public/client.js\",\"examples/search/public/index.html\"]},{\"name\":\"Other\",\"slug\":\"other\",\"files\":[],\"children\":[{\"name\":\"Other \u2014 History.md\",\"slug\":\"other-history-md\",\"files\":[\"History.md\"]},{\"name\":\"Other \u2014 Readme.md\",\"slug\":\"other-readme-md\",\"files\":[\"Readme.md\"]},{\"name\":\"Other \u2014 examples\",\"slug\":\"other-examples\",\"files\":[\"examples/README.md\"]},{\"name\":\"Other \u2014 package.json\",\"slug\":\"other-package-json\",\"files\":[\"package.json\"]},{\"name\":\"Other \u2014 test\",\"slug\":\"other-test\",\"files\":[\"test/Route.js\",\"test/Router.js\",\"test/app.all.js\",\"test/app.engine.js\",\"test/app.head.js\",\"test/app.js\",\"test/app.listen.js\",\"test/app.locals.js\",\"test/app.options.js\",\"test/app.param.js\",\"test/app.render.js\",\"test/app.request.js\",\"test/app.response.js\",\"test/app.route.js\",\"test/app.router.js\",\"test/app.routes.error.js\",\"test/app.use.js\",\"test/config.js\",\"test/exports.js\",\"test/express.json.js\",\"test/express.raw.js\",\"test/express.static.js\",\"test/express.text.js\",\"test/express.urlencoded.js\",\"test/middleware.basic.js\",\"test/regression.js\",\"test/req.accepts.js\",\"test/req.acceptsCharsets.js\",\"test/req.acceptsEncodings.js\",\"test/req.acceptsLanguages.js\",\"test/req.baseUrl.js\",\"test/req.fresh.js\",\"test/req.get.js\",\"test/req.host.js\",\"test/req.hostname.js\",\"test/req.ip.js\",\"test/req.ips.js\",\"test/req.is.js\",\"test/req.path.js\",\"test/req.protocol.js\",\"test/req.query.js\",\"test/req.range.js\",\"test/req.route.js\",\"test/req.secure.js\",\"test/req.signedCookies.js\",\"test/req.stale.js\",\"test/req.subdomains.js\",\"test/req.xhr.js\",\"test/res.append.js\",\"test/res.attachment.js\",\"test/res.clearCookie.js\",\"test/res.cookie.js\",\"test/res.download.js\",\"test/res.format.js\",\"test/res.get.js\",\"test/res.json.js\",\"test/res.jsonp.js\",\"test/res.links.js\",\"test/res.locals.js\",\"test/res.location.js\",\"test/res.redirect.js\",\"test/res.render.js\",\"test/res.send.js\",\"test/res.sendFile.js\",\"test/res.sendStatus.js\",\"test/res.set.js\",\"test/res.status.js\",\"test/res.type.js\",\"test/res.vary.js\",\"test/utils.js\"]},{\"name\":\"Other \u2014 acceptance\",\"slug\":\"other-acceptance\",\"files\":[\"test/acceptance/auth.js\",\"test/acceptance/content-negotiation.js\",\"test/acceptance/cookie-sessions.js\",\"test/acceptance/cookies.js\",\"test/acceptance/downloads.js\",\"test/acceptance/ejs.js\",\"test/acceptance/error-pages.js\",\"test/acceptance/error.js\",\"test/acceptance/hello-world.js\",\"test/acceptance/markdown.js\",\"test/acceptance/multi-router.js\",\"test/acceptance/mvc.js\",\"test/acceptance/params.js\",\"test/acceptance/resource.js\",\"test/acceptance/route-map.js\",\"test/acceptance/route-separation.js\",\"test/acceptance/vhost.js\",\"test/acceptance/web-service.js\"]},{\"name\":\"Other \u2014 support\",\"slug\":\"other-support\",\"files\":[\"test/support/env.js\",\"test/support/tmpl.js\",\"test/support/utils.js\"]}]}];\nvar META = {\"fromCommit\":\"f873ac23124ffcff8c040b4bd257b32c29828d53\",\"generatedAt\":\"2026-05-08T07:35:04.785Z\",\"model\":\"glm-5\",\"moduleFiles\":{\"Core Framework\":[\"index.js\",\"lib/application.js\",\"lib/express.js\",\"lib/request.js\",\"lib/response.js\",\"lib/utils.js\",\"lib/view.js\"],\"Authentication &amp; Sessions\":[\"examples/auth/index.js\",\"examples/auth/views/foot.ejs\",\"examples/auth/views/head.ejs\",\"examples/auth/views/login.ejs\",\"examples/cookie-sessions/index.js\",\"examples/cookies/index.js\",\"examples/online/index.js\",\"examples/session/index.js\",\"examples/session/redis.js\"],\"Routing Patterns\":[\"examples/multi-router/controllers/api_v1.js\",\"examples/multi-router/controllers/api_v2.js\",\"examples/multi-router/index.js\",\"examples/params/index.js\",\"examples/resource/index.js\",\"examples/route-map/index.js\",\"examples/route-middleware/index.js\",\"examples/route-separation/index.js\",\"examples/route-separation/post.js\",\"examples/route-separation/public/style.css\",\"examples/route-separation/site.js\",\"examples/route-separation/user.js\",\"examples/route-separation/views/footer.ejs\",\"examples/route-separation/views/header.ejs\",\"examples/route-separation/views/index.ejs\",\"examples/route-separation/views/posts/index.ejs\",\"examples/route-separation/views/users/edit.ejs\",\"examples/route-separation/views/users/index.ejs\",\"examples/route-separation/views/users/view.ejs\"],\"Views &amp; Templates\":[\"examples/ejs/index.js\",\"examples/ejs/public/stylesheets/style.css\",\"examples/ejs/views/footer.html\",\"examples/ejs/views/header.html\",\"examples/ejs/views/users.html\",\"examples/markdown/index.js\",\"examples/markdown/views/index.md\",\"examples/mvc/controllers/main/index.js\",\"examples/mvc/controllers/pet/index.js\",\"examples/mvc/controllers/pet/views/edit.ejs\",\"examples/mvc/controllers/pet/views/show.ejs\",\"examples/mvc/controllers/user-pet/index.js\",\"examples/mvc/controllers/user/index.js\",\"examples/mvc/controllers/user/views/edit.hbs\",\"examples/mvc/controllers/user/views/list.hbs\",\"examples/mvc/controllers/user/views/show.hbs\",\"examples/mvc/db.js\",\"examples/mvc/index.js\",\"examples/mvc/lib/boot.js\",\"examples/mvc/public/style.css\",\"examples/mvc/views/404.ejs\",\"examples/mvc/views/5xx.ejs\",\"examples/view-constructor/github-view.js\",\"examples/view-constructor/index.js\",\"examples/view-locals/index.js\",\"examples/view-locals/user.js\",\"examples/view-locals/views/index.ejs\"],\"Static Files &amp; Downloads\":[\"examples/downloads/files/CCTV\u5927\u8d5b\u4e0a\u6d77\u5206\u8d5b\u533a.txt\",\"examples/downloads/files/amazing.txt\",\"examples/downloads/files/notes/groceries.txt\",\"examples/downloads/index.js\",\"examples/static-files/index.js\",\"examples/static-files/public/css/style.css\",\"examples/static-files/public/hello.txt\",\"examples/static-files/public/js/app.js\"],\"Error Handling\":[\"examples/error-pages/index.js\",\"examples/error-pages/views/404.ejs\",\"examples/error-pages/views/500.ejs\",\"examples/error-pages/views/error_header.ejs\",\"examples/error-pages/views/footer.ejs\",\"examples/error-pages/views/index.ejs\",\"examples/error/index.js\"],\"Web Services &amp; APIs\":[\"examples/content-negotiation/db.js\",\"examples/content-negotiation/index.js\",\"examples/content-negotiation/users.js\",\"examples/vhost/index.js\",\"examples/web-service/index.js\"],\"Basic Usage\":[\"examples/hello-world/index.js\",\"examples/search/index.js\",\"examples/search/public/client.js\",\"examples/search/public/index.html\"],\"Other\":[\"History.md\",\"Readme.md\",\"examples/README.md\",\"package.json\",\"test/Route.js\",\"test/Router.js\",\"test/app.all.js\",\"test/app.engine.js\",\"test/app.head.js\",\"test/app.js\",\"test/app.listen.js\",\"test/app.locals.js\",\"test/app.options.js\",\"test/app.param.js\",\"test/app.render.js\",\"test/app.request.js\",\"test/app.response.js\",\"test/app.route.js\",\"test/app.router.js\",\"test/app.routes.error.js\",\"test/app.use.js\",\"test/config.js\",\"test/exports.js\",\"test/express.json.js\",\"test/express.raw.js\",\"test/express.static.js\",\"test/express.text.js\",\"test/express.urlencoded.js\",\"test/middleware.basic.js\",\"test/regression.js\",\"test/req.accepts.js\",\"test/req.acceptsCharsets.js\",\"test/req.acceptsEncodings.js\",\"test/req.acceptsLanguages.js\",\"test/req.baseUrl.js\",\"test/req.fresh.js\",\"test/req.get.js\",\"test/req.host.js\",\"test/req.hostname.js\",\"test/req.ip.js\",\"test/req.ips.js\",\"test/req.is.js\",\"test/req.path.js\",\"test/req.protocol.js\",\"test/req.query.js\",\"test/req.range.js\",\"test/req.route.js\",\"test/req.secure.js\",\"test/req.signedCookies.js\",\"test/req.stale.js\",\"test/req.subdomains.js\",\"test/req.xhr.js\",\"test/res.append.js\",\"test/res.attachment.js\",\"test/res.clearCookie.js\",\"test/res.cookie.js\",\"test/res.download.js\",\"test/res.format.js\",\"test/res.get.js\",\"test/res.json.js\",\"test/res.jsonp.js\",\"test/res.links.js\",\"test/res.locals.js\",\"test/res.location.js\",\"test/res.redirect.js\",\"test/res.render.js\",\"test/res.send.js\",\"test/res.sendFile.js\",\"test/res.sendStatus.js\",\"test/res.set.js\",\"test/res.status.js\",\"test/res.type.js\",\"test/res.vary.js\",\"test/utils.js\",\"test/acceptance/auth.js\",\"test/acceptance/content-negotiation.js\",\"test/acceptance/cookie-sessions.js\",\"test/acceptance/cookies.js\",\"test/acceptance/downloads.js\",\"test/acceptance/ejs.js\",\"test/acceptance/error-pages.js\",\"test/acceptance/error.js\",\"test/acceptance/hello-world.js\",\"test/acceptance/markdown.js\",\"test/acceptance/multi-router.js\",\"test/acceptance/mvc.js\",\"test/acceptance/params.js\",\"test/acceptance/resource.js\",\"test/acceptance/route-map.js\",\"test/acceptance/route-separation.js\",\"test/acceptance/vhost.js\",\"test/acceptance/web-service.js\",\"test/support/env.js\",\"test/support/tmpl.js\",\"test/support/utils.js\"],\"Other \u2014 History.md\":[\"History.md\"],\"Other \u2014 Readme.md\":[\"Readme.md\"],\"Other \u2014 examples\":[\"examples/README.md\"],\"Other \u2014 package.json\":[\"package.json\"],\"Other \u2014 test\":[\"test/Route.js\",\"test/Router.js\",\"test/app.all.js\",\"test/app.engine.js\",\"test/app.head.js\",\"test/app.js\",\"test/app.listen.js\",\"test/app.locals.js\",\"test/app.options.js\",\"test/app.param.js\",\"test/app.render.js\",\"test/app.request.js\",\"test/app.response.js\",\"test/app.route.js\",\"test/app.router.js\",\"test/app.routes.error.js\",\"test/app.use.js\",\"test/config.js\",\"test/exports.js\",\"test/express.json.js\",\"test/express.raw.js\",\"test/express.static.js\",\"test/express.text.js\",\"test/express.urlencoded.js\",\"test/middleware.basic.js\",\"test/regression.js\",\"test/req.accepts.js\",\"test/req.acceptsCharsets.js\",\"test/req.acceptsEncodings.js\",\"test/req.acceptsLanguages.js\",\"test/req.baseUrl.js\",\"test/req.fresh.js\",\"test/req.get.js\",\"test/req.host.js\",\"test/req.hostname.js\",\"test/req.ip.js\",\"test/req.ips.js\",\"test/req.is.js\",\"test/req.path.js\",\"test/req.protocol.js\",\"test/req.query.js\",\"test/req.range.js\",\"test/req.route.js\",\"test/req.secure.js\",\"test/req.signedCookies.js\",\"test/req.stale.js\",\"test/req.subdomains.js\",\"test/req.xhr.js\",\"test/res.append.js\",\"test/res.attachment.js\",\"test/res.clearCookie.js\",\"test/res.cookie.js\",\"test/res.download.js\",\"test/res.format.js\",\"test/res.get.js\",\"test/res.json.js\",\"test/res.jsonp.js\",\"test/res.links.js\",\"test/res.locals.js\",\"test/res.location.js\",\"test/res.redirect.js\",\"test/res.render.js\",\"test/res.send.js\",\"test/res.sendFile.js\",\"test/res.sendStatus.js\",\"test/res.set.js\",\"test/res.status.js\",\"test/res.type.js\",\"test/res.vary.js\",\"test/utils.js\"],\"Other \u2014 acceptance\":[\"test/acceptance/auth.js\",\"test/acceptance/content-negotiation.js\",\"test/acceptance/cookie-sessions.js\",\"test/acceptance/cookies.js\",\"test/acceptance/downloads.js\",\"test/acceptance/ejs.js\",\"test/acceptance/error-pages.js\",\"test/acceptance/error.js\",\"test/acceptance/hello-world.js\",\"test/acceptance/markdown.js\",\"test/acceptance/multi-router.js\",\"test/acceptance/mvc.js\",\"test/acceptance/params.js\",\"test/acceptance/resource.js\",\"test/acceptance/route-map.js\",\"test/acceptance/route-separation.js\",\"test/acceptance/vhost.js\",\"test/acceptance/web-service.js\"],\"Other \u2014 support\":[\"test/support/env.js\",\"test/support/tmpl.js\",\"test/support/utils.js\"]},\"moduleTree\":[{\"name\":\"Core Framework\",\"slug\":\"core-framework\",\"files\":[\"index.js\",\"lib/application.js\",\"lib/express.js\",\"lib/request.js\",\"lib/response.js\",\"lib/utils.js\",\"lib/view.js\"]},{\"name\":\"Authentication &amp; Sessions\",\"slug\":\"authentication-sessions\",\"files\":[\"examples/auth/index.js\",\"examples/auth/views/foot.ejs\",\"examples/auth/views/head.ejs\",\"examples/auth/views/login.ejs\",\"examples/cookie-sessions/index.js\",\"examples/cookies/index.js\",\"examples/online/index.js\",\"examples/session/index.js\",\"examples/session/redis.js\"]},{\"name\":\"Routing Patterns\",\"slug\":\"routing-patterns\",\"files\":[\"examples/multi-router/controllers/api_v1.js\",\"examples/multi-router/controllers/api_v2.js\",\"examples/multi-router/index.js\",\"examples/params/index.js\",\"examples/resource/index.js\",\"examples/route-map/index.js\",\"examples/route-middleware/index.js\",\"examples/route-separation/index.js\",\"examples/route-separation/post.js\",\"examples/route-separation/public/style.css\",\"examples/route-separation/site.js\",\"examples/route-separation/user.js\",\"examples/route-separation/views/footer.ejs\",\"examples/route-separation/views/header.ejs\",\"examples/route-separation/views/index.ejs\",\"examples/route-separation/views/posts/index.ejs\",\"examples/route-separation/views/users/edit.ejs\",\"examples/route-separation/views/users/index.ejs\",\"examples/route-separation/views/users/view.ejs\"]},{\"name\":\"Views &amp; Templates\",\"slug\":\"views-templates\",\"files\":[\"examples/ejs/index.js\",\"examples/ejs/public/stylesheets/style.css\",\"examples/ejs/views/footer.html\",\"examples/ejs/views/header.html\",\"examples/ejs/views/users.html\",\"examples/markdown/index.js\",\"examples/markdown/views/index.md\",\"examples/mvc/controllers/main/index.js\",\"examples/mvc/controllers/pet/index.js\",\"examples/mvc/controllers/pet/views/edit.ejs\",\"examples/mvc/controllers/pet/views/show.ejs\",\"examples/mvc/controllers/user-pet/index.js\",\"examples/mvc/controllers/user/index.js\",\"examples/mvc/controllers/user/views/edit.hbs\",\"examples/mvc/controllers/user/views/list.hbs\",\"examples/mvc/controllers/user/views/show.hbs\",\"examples/mvc/db.js\",\"examples/mvc/index.js\",\"examples/mvc/lib/boot.js\",\"examples/mvc/public/style.css\",\"examples/mvc/views/404.ejs\",\"examples/mvc/views/5xx.ejs\",\"examples/view-constructor/github-view.js\",\"examples/view-constructor/index.js\",\"examples/view-locals/index.js\",\"examples/view-locals/user.js\",\"examples/view-locals/views/index.ejs\"]},{\"name\":\"Static Files &amp; Downloads\",\"slug\":\"static-files-downloads\",\"files\":[\"examples/downloads/files/CCTV\u5927\u8d5b\u4e0a\u6d77\u5206\u8d5b\u533a.txt\",\"examples/downloads/files/amazing.txt\",\"examples/downloads/files/notes/groceries.txt\",\"examples/downloads/index.js\",\"examples/static-files/index.js\",\"examples/static-files/public/css/style.css\",\"examples/static-files/public/hello.txt\",\"examples/static-files/public/js/app.js\"]},{\"name\":\"Error Handling\",\"slug\":\"error-handling\",\"files\":[\"examples/error-pages/index.js\",\"examples/error-pages/views/404.ejs\",\"examples/error-pages/views/500.ejs\",\"examples/error-pages/views/error_header.ejs\",\"examples/error-pages/views/footer.ejs\",\"examples/error-pages/views/index.ejs\",\"examples/error/index.js\"]},{\"name\":\"Web Services &amp; APIs\",\"slug\":\"web-services-apis\",\"files\":[\"examples/content-negotiation/db.js\",\"examples/content-negotiation/index.js\",\"examples/content-negotiation/users.js\",\"examples/vhost/index.js\",\"examples/web-service/index.js\"]},{\"name\":\"Basic Usage\",\"slug\":\"basic-usage\",\"files\":[\"examples/hello-world/index.js\",\"examples/search/index.js\",\"examples/search/public/client.js\",\"examples/search/public/index.html\"]},{\"name\":\"Other\",\"slug\":\"other\",\"files\":[],\"children\":[{\"name\":\"Other \u2014 History.md\",\"slug\":\"other-history-md\",\"files\":[\"History.md\"]},{\"name\":\"Other \u2014 Readme.md\",\"slug\":\"other-readme-md\",\"files\":[\"Readme.md\"]},{\"name\":\"Other \u2014 examples\",\"slug\":\"other-examples\",\"files\":[\"examples/README.md\"]},{\"name\":\"Other \u2014 package.json\",\"slug\":\"other-package-json\",\"files\":[\"package.json\"]},{\"name\":\"Other \u2014 test\",\"slug\":\"other-test\",\"files\":[\"test/Route.js\",\"test/Router.js\",\"test/app.all.js\",\"test/app.engine.js\",\"test/app.head.js\",\"test/app.js\",\"test/app.listen.js\",\"test/app.locals.js\",\"test/app.options.js\",\"test/app.param.js\",\"test/app.render.js\",\"test/app.request.js\",\"test/app.response.js\",\"test/app.route.js\",\"test/app.router.js\",\"test/app.routes.error.js\",\"test/app.use.js\",\"test/config.js\",\"test/exports.js\",\"test/express.json.js\",\"test/express.raw.js\",\"test/express.static.js\",\"test/express.text.js\",\"test/express.urlencoded.js\",\"test/middleware.basic.js\",\"test/regression.js\",\"test/req.accepts.js\",\"test/req.acceptsCharsets.js\",\"test/req.acceptsEncodings.js\",\"test/req.acceptsLanguages.js\",\"test/req.baseUrl.js\",\"test/req.fresh.js\",\"test/req.get.js\",\"test/req.host.js\",\"test/req.hostname.js\",\"test/req.ip.js\",\"test/req.ips.js\",\"test/req.is.js\",\"test/req.path.js\",\"test/req.protocol.js\",\"test/req.query.js\",\"test/req.range.js\",\"test/req.route.js\",\"test/req.secure.js\",\"test/req.signedCookies.js\",\"test/req.stale.js\",\"test/req.subdomains.js\",\"test/req.xhr.js\",\"test/res.append.js\",\"test/res.attachment.js\",\"test/res.clearCookie.js\",\"test/res.cookie.js\",\"test/res.download.js\",\"test/res.format.js\",\"test/res.get.js\",\"test/res.json.js\",\"test/res.jsonp.js\",\"test/res.links.js\",\"test/res.locals.js\",\"test/res.location.js\",\"test/res.redirect.js\",\"test/res.render.js\",\"test/res.send.js\",\"test/res.sendFile.js\",\"test/res.sendStatus.js\",\"test/res.set.js\",\"test/res.status.js\",\"test/res.type.js\",\"test/res.vary.js\",\"test/utils.js\"]},{\"name\":\"Other \u2014 acceptance\",\"slug\":\"other-acceptance\",\"files\":[\"test/acceptance/auth.js\",\"test/acceptance/content-negotiation.js\",\"test/acceptance/cookie-sessions.js\",\"test/acceptance/cookies.js\",\"test/acceptance/downloads.js\",\"test/acceptance/ejs.js\",\"test/acceptance/error-pages.js\",\"test/acceptance/error.js\",\"test/acceptance/hello-world.js\",\"test/acceptance/markdown.js\",\"test/acceptance/multi-router.js\",\"test/acceptance/mvc.js\",\"test/acceptance/params.js\",\"test/acceptance/resource.js\",\"test/acceptance/route-map.js\",\"test/acceptance/route-separation.js\",\"test/acceptance/vhost.js\",\"test/acceptance/web-service.js\"]},{\"name\":\"Other \u2014 support\",\"slug\":\"other-support\",\"files\":[\"test/support/env.js\",\"test/support/tmpl.js\",\"test/support/utils.js\"]}]}]};\n\n(function() {\n  var activePage = 'overview';\n\n  document.addEventListener('DOMContentLoaded', function() {\n    mermaid.initialize({ startOnLoad: false, theme: 'neutral', securityLevel: 'loose' });\n    renderMeta();\n    renderNav();\n    document.getElementById('menu-toggle').addEventListener('click', function() {\n      document.getElementById('sidebar').classList.toggle('open');\n    });\n    if (location.hash &amp;&amp; location.hash.length &gt; 1) {\n      activePage = decodeURIComponent(location.hash.slice(1));\n    }\n    navigateTo(activePage);\n  });\n\n  function renderMeta() {\n    if (!META) return;\n    var el = document.getElementById('meta-info');\n    var parts = [];\n    if (META.generatedAt) {\n      parts.push(new Date(META.generatedAt).toLocaleDateString());\n    }\n    if (META.model) parts.push(META.model);\n    if (META.fromCommit) parts.push(META.fromCommit.slice(0, 8));\n    el.textContent = parts.join(' \\u00b7 ');\n  }\n\n  function renderNav() {\n    var container = document.getElementById('nav-tree');\n    var html = '\n';\n    html += 'Overview';\n    html += '';\n    if (TREE.length &gt; 0) {\n      html += '\nModules';\n      html += buildNavTree(TREE);\n    }\n    container.innerHTML = html;\n    container.addEventListener('click', function(e) {\n      var target = e.target;\n      while (target &amp;&amp; !target.dataset.page) { target = target.parentElement; }\n      if (target &amp;&amp; target.dataset.page) {\n        e.preventDefault();\n        navigateTo(target.dataset.page);\n      }\n    });\n  }\n\n  function buildNavTree(nodes) {\n    var html = '';\n    for (var i = 0; i &lt; nodes.length; i++) {\n      var node = nodes[i];\n      html += '\n';\n      html += '' + escH(node.name) + '';\n      if (node.children &amp;&amp; node.children.length &gt; 0) {\n        html += '\n' + buildNavTree(node.children) + '';\n      }\n      html += '';\n    }\n    return html;\n  }\n\n  function escH(s) {\n    var d = document.createElement('div');\n    d.textContent = s;\n    return d.innerHTML;\n  }\n\n  function navigateTo(page) {\n    activePage = page;\n    location.hash = encodeURIComponent(page);\n\n    var items = document.querySelectorAll('.nav-item');\n    for (var i = 0; i &lt; items.length; i++) {\n      if (items[i].dataset.page === page) {\n        items[i].classList.add('active');\n      } else {\n        items[i].classList.remove('active');\n      }\n    }\n\n    var contentEl = document.getElementById('content');\n    var md = PAGES[page];\n\n    if (!md) {\n      contentEl.innerHTML = '\n\nPage not found\n' + escH(page) + '.md does not exist.';\n      return;\n    }\n\n    contentEl.innerHTML = marked.parse(md);\n\n    // Rewrite .md links to hash navigation\n    var links = contentEl.querySelectorAll('a[href]');\n    for (var i = 0; i &lt; links.length; i++) {\n      var href = links[i].getAttribute('href');\n      if (href &amp;&amp; href.endsWith('.md') &amp;&amp; href.indexOf('://') === -1) {\n        var slug = href.replace(/\\.md$/, '');\n        links[i].setAttribute('href', '#' + encodeURIComponent(slug));\n        (function(s) {\n          links[i].addEventListener('click', function(e) {\n            e.preventDefault();\n            navigateTo(s);\n          });\n        })(slug);\n      }\n    }\n\n    // Convert mermaid code blocks into mermaid divs\n    var mermaidBlocks = contentEl.querySelectorAll('pre code.language-mermaid');\n    for (var i = 0; i &lt; mermaidBlocks.length; i++) {\n      var pre = mermaidBlocks[i].parentElement;\n      var div = document.createElement('div');\n      div.className = 'mermaid';\n      div.textContent = mermaidBlocks[i].textContent;\n      pre.parentNode.replaceChild(div, pre);\n    }\n    try { mermaid.run({ querySelector: '.mermaid' }); } catch(e) {}\n\n    window.scrollTo(0, 0);\n    document.getElementById('sidebar').classList.remove('open');\n  }\n})();\n\n\n\n", "creation_timestamp": "2026-05-08T07:36:05.000000Z"}