-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtoc-1909b282.js
More file actions
455 lines (416 loc) · 53.5 KB
/
Copy pathtoc-1909b282.js
File metadata and controls
455 lines (416 loc) · 53.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
// Populate the sidebar
//
// This is a script, and not included directly in the page, to control the total size of the book.
// The TOC contains an entry for each page, so if each page includes a copy of the TOC,
// the total size of the page becomes O(n**2).
class MDBookSidebarScrollbox extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.innerHTML = '<ol class="chapter"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="architecture.html"><strong aria-hidden="true">2.</strong> Architecture</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design.html"><strong aria-hidden="true">3.</strong> Design</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/light-4j.html"><strong aria-hidden="true">3.1.</strong> light-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/light-4j/pbkdf2-upgrade.html"><strong aria-hidden="true">3.1.1.</strong> PBKDF2-Upgrade</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/light-genai-4j.html"><strong aria-hidden="true">3.2.</strong> light-genai-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/light-genai-4j/memory-embedding.html"><strong aria-hidden="true">3.2.1.</strong> Memory Embedding</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/light-genai-4j/agent-skill-tool.html"><strong aria-hidden="true">3.2.2.</strong> Agent Skill Tool</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/light-genai-4j/event-driven-agent.html"><strong aria-hidden="true">3.2.3.</strong> Event Driven Agent</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/light-hybrid-4j.html"><strong aria-hidden="true">3.3.</strong> light-hybrid-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/light-hybrid-4j/json-rpc.html"><strong aria-hidden="true">3.3.1.</strong> JSON RPC 2.0</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/light-bot.html"><strong aria-hidden="true">3.4.</strong> light-bot</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/light-bot/sync-github.html"><strong aria-hidden="true">3.4.1.</strong> Sync GitHub</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/mcp-router.html"><strong aria-hidden="true">3.5.</strong> MCP Rotuer</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/sse-support.html"><strong aria-hidden="true">3.6.</strong> SSE Support</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/config-reload.html"><strong aria-hidden="true">3.7.</strong> Config Reload</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/module-registry.html"><strong aria-hidden="true">3.8.</strong> Module Registry</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/httpclient-retry.html"><strong aria-hidden="true">3.9.</strong> HttpClient Retry</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/genai-client.html"><strong aria-hidden="true">3.10.</strong> GenAI Client</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/ccac-exchange.html"><strong aria-hidden="true">3.11.</strong> CCAC Token Exchange</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/client-simplepool.html"><strong aria-hidden="true">3.12.</strong> Client Simple Pool</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/remove-simplejwtverify.html"><strong aria-hidden="true">3.13.</strong> Remove AbsSimJwt</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="design/fine-grained-auth.html"><strong aria-hidden="true">3.14.</strong> Fine-Grained Authorization</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="cross-cutting-concerns.html"><strong aria-hidden="true">4.</strong> Cross-Cutting-Concerns</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-4j.html"><strong aria-hidden="true">4.1.</strong> Light-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/http-handler.html"><strong aria-hidden="true">4.1.1.</strong> Http Handler</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/handler/path-resource.html"><strong aria-hidden="true">4.1.1.1.</strong> Path Resource</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/handler/virtual-host.html"><strong aria-hidden="true">4.1.1.2.</strong> Virtual Host</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/handler/router-handler.html"><strong aria-hidden="true">4.1.1.3.</strong> Router Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/handler/oauth-server.html"><strong aria-hidden="true">4.1.1.4.</strong> OAuth Server</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/handler/proxy-handler.html"><strong aria-hidden="true">4.1.1.5.</strong> Proxy Handler</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware-handler.html"><strong aria-hidden="true">4.1.2.</strong> Middleware Handler</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/apm-metrics.html"><strong aria-hidden="true">4.1.2.1.</strong> APM Metrics</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/api-key.html"><strong aria-hidden="true">4.1.2.2.</strong> API Key</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/audit-handler.html"><strong aria-hidden="true">4.1.2.3.</strong> Audit Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/basic-auth.html"><strong aria-hidden="true">4.1.2.4.</strong> Basic Auth</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/body-handler.html"><strong aria-hidden="true">4.1.2.5.</strong> Body Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/content-handler.html"><strong aria-hidden="true">4.1.2.6.</strong> Content Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/correlation-handler.html"><strong aria-hidden="true">4.1.2.7.</strong> Correlation Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/cors-handler.html"><strong aria-hidden="true">4.1.2.8.</strong> Cors Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/deref-token.html"><strong aria-hidden="true">4.1.2.9.</strong> DeRef Token</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/dump-handler.html"><strong aria-hidden="true">4.1.2.10.</strong> Dump Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/encode-decode.html"><strong aria-hidden="true">4.1.2.11.</strong> Encode Decode</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/exception-handler.html"><strong aria-hidden="true">4.1.2.12.</strong> Exception Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/expect100-continue.html"><strong aria-hidden="true">4.1.2.13.</strong> Expect100 Continue</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/external-handler.html"><strong aria-hidden="true">4.1.2.14.</strong> External Service</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/header-handler.html"><strong aria-hidden="true">4.1.2.15.</strong> Header Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/ip-whitelist.html"><strong aria-hidden="true">4.1.2.16.</strong> IP Whitelist</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/path-prefix.html"><strong aria-hidden="true">4.1.2.17.</strong> Path Prefix</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/path-service.html"><strong aria-hidden="true">4.1.2.18.</strong> Path Service</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/rate-limit.html"><strong aria-hidden="true">4.1.2.19.</strong> Rate Limit</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/request-injection.html"><strong aria-hidden="true">4.1.2.20.</strong> Request Injection</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/response-injection.html"><strong aria-hidden="true">4.1.2.21.</strong> Response Injection</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/prometheus-metrics.html"><strong aria-hidden="true">4.1.2.22.</strong> Prometheus Metrics</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/sanitizer-handler.html"><strong aria-hidden="true">4.1.2.23.</strong> Sanitizer Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/security-handler.html"><strong aria-hidden="true">4.1.2.24.</strong> Security Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/unified-security.html"><strong aria-hidden="true">4.1.2.25.</strong> Unified Security</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/sidecar-handler.html"><strong aria-hidden="true">4.1.2.26.</strong> Sidecar Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/saml-token.html"><strong aria-hidden="true">4.1.2.27.</strong> SAML Token</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/token-handler.html"><strong aria-hidden="true">4.1.2.28.</strong> Token Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/sse-handler.html"><strong aria-hidden="true">4.1.2.29.</strong> SSE Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/service-dict.html"><strong aria-hidden="true">4.1.2.30.</strong> Service Dict</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/mcp-router.html"><strong aria-hidden="true">4.1.2.31.</strong> MCP Router</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/mcp-audit.html"><strong aria-hidden="true">4.1.2.32.</strong> MCP Audit</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/middleware/token-exchange.html"><strong aria-hidden="true">4.1.2.33.</strong> Token Exchange</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/interceptor.html"><strong aria-hidden="true">4.1.3.</strong> Interceptor</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/interceptor/request-transformer.html"><strong aria-hidden="true">4.1.3.1.</strong> Request Transformer</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/interceptor/response-transformer.html"><strong aria-hidden="true">4.1.3.2.</strong> Response Transformer</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/admin-endpoint.html"><strong aria-hidden="true">4.1.4.</strong> Admin Endpoint</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/admin/cache-explorer.html"><strong aria-hidden="true">4.1.4.1.</strong> Cache Explorer</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/admin/config-reload.html"><strong aria-hidden="true">4.1.4.2.</strong> Config Reload</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/admin/health.html"><strong aria-hidden="true">4.1.4.3.</strong> Health Check</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/admin/server-info.html"><strong aria-hidden="true">4.1.4.4.</strong> Server Info</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/admin/logger-handler.html"><strong aria-hidden="true">4.1.4.5.</strong> Logger Handler</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/utility/utility.html"><strong aria-hidden="true">4.1.5.</strong> Utility</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/utility/ldap-util.html"><strong aria-hidden="true">4.1.5.1.</strong> Ldap Utility</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/module.html"><strong aria-hidden="true">4.1.6.</strong> Module</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/load-balance.html"><strong aria-hidden="true">4.1.6.1.</strong> Load Balance</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/cluster.html"><strong aria-hidden="true">4.1.6.2.</strong> Cluster</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/switch.html"><strong aria-hidden="true">4.1.6.3.</strong> Switch</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/consul-registry.html"><strong aria-hidden="true">4.1.6.4.</strong> Consul Registry</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/common.html"><strong aria-hidden="true">4.1.6.5.</strong> Common</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/config.html"><strong aria-hidden="true">4.1.6.6.</strong> Config</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/startup.html"><strong aria-hidden="true">4.1.6.7.</strong> Startup</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/value-injection.html"><strong aria-hidden="true">4.1.6.8.</strong> Value Injection</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/cache-manager.html"><strong aria-hidden="true">4.1.6.9.</strong> Cache Manager</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/data-source.html"><strong aria-hidden="true">4.1.6.10.</strong> Data Source</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/db-provider.html"><strong aria-hidden="true">4.1.6.11.</strong> DB Provider</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/decryptor.html"><strong aria-hidden="true">4.1.6.12.</strong> Decryptor</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/email-sender.html"><strong aria-hidden="true">4.1.6.13.</strong> Email Sender</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/handler.html"><strong aria-hidden="true">4.1.6.14.</strong> Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/http2-client.html"><strong aria-hidden="true">4.1.6.15.</strong> Http2 Client</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/simplepool-migration.html"><strong aria-hidden="true">4.1.6.16.</strong> SimplePool Migration</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/monard-result.html"><strong aria-hidden="true">4.1.6.17.</strong> Monard Result</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/jsonpath-vs-jsonpointer.html"><strong aria-hidden="true">4.1.6.18.</strong> JSONPath vs JSON Pointer</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/other-masking-method.html"><strong aria-hidden="true">4.1.6.19.</strong> Other Masking Method</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/token-client.html"><strong aria-hidden="true">4.1.6.20.</strong> Token Client</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/data-mask.html"><strong aria-hidden="true">4.1.6.21.</strong> Data Mask</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/portal-registry.html"><strong aria-hidden="true">4.1.6.22.</strong> Portal Registry</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/direct-registry.html"><strong aria-hidden="true">4.1.6.23.</strong> Direct Registry</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/rule-loader.html"><strong aria-hidden="true">4.1.6.24.</strong> Rule Loader</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/module/http-server.html"><strong aria-hidden="true">4.1.6.25.</strong> Http Server</a></span></li></ol></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-rest-4j.html"><strong aria-hidden="true">4.2.</strong> Light-rest-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-rest-4j/access-control.html"><strong aria-hidden="true">4.2.1.</strong> Access Control</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-rest-4j/openapi-meta.html"><strong aria-hidden="true">4.2.2.</strong> OpenAPI Meta</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-rest-4j/openapi-security.html"><strong aria-hidden="true">4.2.3.</strong> OpenAPI Security</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-rest-4j/openapi-validator.html"><strong aria-hidden="true">4.2.4.</strong> OpenAPI Validator</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-rest-4j/specification.html"><strong aria-hidden="true">4.2.5.</strong> Specification</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-hybrid-4j.html"><strong aria-hidden="true">4.3.</strong> Light-hybrid-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-hybrid-4j/rpc-router.html"><strong aria-hidden="true">4.3.1.</strong> Rpc-Router</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-hybrid-4j/rpc-security.html"><strong aria-hidden="true">4.3.2.</strong> Rpc-Security</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-graphql-4j.html"><strong aria-hidden="true">4.4.</strong> Light-Graphql-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-grahpql-4j/graphql-commmon.html"><strong aria-hidden="true">4.4.1.</strong> Graphql Common</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-grahpql-4j/graphql-validator.html"><strong aria-hidden="true">4.4.2.</strong> Graphql Validator</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-grahpql-4j/graphql-security.html"><strong aria-hidden="true">4.4.3.</strong> Graphql Security</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-grahpql-4j/graphql-router.html"><strong aria-hidden="true">4.4.4.</strong> Graphql Router</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-kafka.html"><strong aria-hidden="true">4.5.</strong> Light-Kafka</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-kafka/kafka-common.html"><strong aria-hidden="true">4.5.1.</strong> Kafka Common</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-kafka/kafka-consumer.html"><strong aria-hidden="true">4.5.2.</strong> Kafka Consumer</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-kafka/kafka-producer.html"><strong aria-hidden="true">4.5.3.</strong> Kafka Producer</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-kafka/kafka-streams.html"><strong aria-hidden="true">4.5.4.</strong> Kafka Streams</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/kafka-sidecar/kafka-sidecar.html"><strong aria-hidden="true">4.6.</strong> Kafka-Sidecar</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/kafka-sidecar/streams-health.html"><strong aria-hidden="true">4.6.1.</strong> Streams Health</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-spa-4j.html"><strong aria-hidden="true">4.7.</strong> Light-spa-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-spa-4j/msal-exchange.html"><strong aria-hidden="true">4.7.1.</strong> Msal Exchange</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-spa-4j/stateless-auth.html"><strong aria-hidden="true">4.7.2.</strong> Stateless Auth</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-spa-4j/websocket-security.html"><strong aria-hidden="true">4.7.3.</strong> WebSocket Security</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-chaos-monkey.html"><strong aria-hidden="true">4.8.</strong> Light-chaos-monkey</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-chaos-monkey/chaos-monkey.html"><strong aria-hidden="true">4.8.1.</strong> Chaos Monkey</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-chaos-monkey/exception-assault.html"><strong aria-hidden="true">4.8.2.</strong> Exception Assault</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-chaos-monkey/killapp-assault.html"><strong aria-hidden="true">4.8.3.</strong> Killapp Assault</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-chaos-monkey/latency-assault.html"><strong aria-hidden="true">4.8.4.</strong> Latency Assault</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-chaos-monkey/memory-assault.html"><strong aria-hidden="true">4.8.5.</strong> Memory Assault</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-aws-lambda.html"><strong aria-hidden="true">4.9.</strong> Light-sws-lambda</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-aws-lambda/lambda-invoker.html"><strong aria-hidden="true">4.9.1.</strong> Lambda Invoker</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-aws-lambda/sts-support.html"><strong aria-hidden="true">4.9.2.</strong> STS Support</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-websocket-4j.html"><strong aria-hidden="true">4.10.</strong> Light-websocket-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-websocket-4j/websocket-client.html"><strong aria-hidden="true">4.10.1.</strong> WebSocket Client</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-websocket-4j/websocket-router.html"><strong aria-hidden="true">4.10.2.</strong> WebSocket Router</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-websocket-4j/websocket-handler.html"><strong aria-hidden="true">4.10.3.</strong> WebSocket Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-websocket-4j/websocket-rendezvous.html"><strong aria-hidden="true">4.10.4.</strong> WebSocket Rendezvous</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-genai-4j.html"><strong aria-hidden="true">4.11.</strong> Light-genai-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-genai-4j/ollama-client.html"><strong aria-hidden="true">4.11.1.</strong> Ollama Client</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-genai-4j/openai-client.html"><strong aria-hidden="true">4.11.2.</strong> OpenAI Client</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-genai-4j/gemini-client.html"><strong aria-hidden="true">4.11.3.</strong> Gemini Client</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-genai-4j/bedrock-client.html"><strong aria-hidden="true">4.11.4.</strong> Bedrock Client</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-genai-4j/genai-websocket-handler.html"><strong aria-hidden="true">4.11.5.</strong> Genai WebSocket Handler</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-genai-4j/code-executor.html"><strong aria-hidden="true">4.11.6.</strong> Code Executor</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-controller.html"><strong aria-hidden="true">4.12.</strong> Light-controller</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-controller/rest-websocket.html"><strong aria-hidden="true">4.12.1.</strong> Rest vs WebSocket</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-controller/websocket-recovery.html"><strong aria-hidden="true">4.12.2.</strong> WebSocket Recovery</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-controller/two-stage-startup.html"><strong aria-hidden="true">4.12.3.</strong> Two Stage Startup</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-controller/direct-connection.html"><strong aria-hidden="true">4.12.4.</strong> Direct Connection</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-controller/mcp-architecture.html"><strong aria-hidden="true">4.12.5.</strong> MCP Architecture</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="concern/light-controller/unified-microservice-channel.html"><strong aria-hidden="true">4.12.6.</strong> Unified Channel</a></span></li></ol></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product.html"><strong aria-hidden="true">5.</strong> Product</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/mcp-gateway.html"><strong aria-hidden="true">5.1.</strong> MCP Gateway</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/mcp-gateway/intelligent-routing.html"><strong aria-hidden="true">5.1.1.</strong> Intelligent Routing</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/mcp-gateway/mcp-execution-via-code.html"><strong aria-hidden="true">5.1.2.</strong> Mcp Execution via Code</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/mcp-gateway/observability-audit-logging.html"><strong aria-hidden="true">5.1.3.</strong> Observability & Audit Logging</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/mcp-gateway/privacy-data-masking.html"><strong aria-hidden="true">5.1.4.</strong> Privacy & Data Masking</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/mcp-gateway/tokenization.html"><strong aria-hidden="true">5.1.5.</strong> Tokenization</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/mcp-gateway/protocol-transport-translation.html"><strong aria-hidden="true">5.1.6.</strong> Protocol & Transport Translation</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/mcp-gateway/session-management.html"><strong aria-hidden="true">5.1.7.</strong> Session Management</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/mcp-gateway/tool-filtering-throttling.html"><strong aria-hidden="true">5.1.8.</strong> Tool Filtering & Throttling</a></span></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/light-gateway.html"><strong aria-hidden="true">5.2.</strong> Light Gateway</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="product/light-gateway/sse-passthrough.html"><strong aria-hidden="true">5.2.1.</strong> SSE Passthrough</a></span></li></ol></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="example.html"><strong aria-hidden="true">6.</strong> Example</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="example/light-websocket-4j.html"><strong aria-hidden="true">6.1.</strong> Light-websocket-4j</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="example/light-websocket-4j/llmchat-server.html"><strong aria-hidden="true">6.1.1.</strong> llmchat-server</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="example/light-websocket-4j/llmchat-gateway.html"><strong aria-hidden="true">6.1.2.</strong> llmchat-gateway</a></span></li></ol></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="tutorial.html"><strong aria-hidden="true">7.</strong> Tutorial</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="tutorial/common.html"><strong aria-hidden="true">7.1.</strong> common</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="tutorial/common/docker-remote-debugging.html"><strong aria-hidden="true">7.1.1.</strong> docker-remote-debugging</a></span></li></ol></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="support.html"><strong aria-hidden="true">8.</strong> Support</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="support/github.html"><strong aria-hidden="true">8.1.</strong> GitHub</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="support/github/light-bot.html"><strong aria-hidden="true">8.1.1.</strong> Light Bot</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="support/github/internal-tools.html"><strong aria-hidden="true">8.1.2.</strong> Internal Tools</a></span></li></ol></li></ol><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="security.html"><strong aria-hidden="true">9.</strong> Security</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="security/known-vulnerabilities.html"><strong aria-hidden="true">9.1.</strong> Known Vulnerabilities</a></span><ol class="section"><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="security/known-vulnerabilities/CVE-2026-28367.html"><strong aria-hidden="true">9.1.1.</strong> CVE-2026-28367</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="security/known-vulnerabilities/CVE-2026-28368.html"><strong aria-hidden="true">9.1.2.</strong> CVE-2026-28368</a></span></li><li class="chapter-item expanded "><span class="chapter-link-wrapper"><a href="security/known-vulnerabilities/CVE-2026-28369.html"><strong aria-hidden="true">9.1.3.</strong> CVE-2026-28369</a></span></li></ol></li></ol></li></ol>';
// Set the current, active page, and reveal it if it's hidden
let current_page = document.location.href.toString().split('#')[0].split('?')[0];
if (current_page.endsWith('/')) {
current_page += 'index.html';
}
const links = Array.prototype.slice.call(this.querySelectorAll('a'));
const l = links.length;
for (let i = 0; i < l; ++i) {
const link = links[i];
const href = link.getAttribute('href');
if (href && !href.startsWith('#') && !/^(?:[a-z+]+:)?\/\//.test(href)) {
link.href = path_to_root + href;
}
// The 'index' page is supposed to alias the first chapter in the book.
// Check both with and without the '.html' suffix to be robust against pretty URLs
if (link.href.replace(/\.html$/, '') === current_page.replace(/\.html$/, '')
|| i === 0
&& path_to_root === ''
&& current_page.endsWith('/index.html')) {
link.classList.add('active');
let parent = link.parentElement;
while (parent) {
if (parent.tagName === 'LI' && parent.classList.contains('chapter-item')) {
parent.classList.add('expanded');
}
parent = parent.parentElement;
}
}
}
// Track and set sidebar scroll position
this.addEventListener('click', e => {
if (e.target.tagName === 'A') {
const clientRect = e.target.getBoundingClientRect();
const sidebarRect = this.getBoundingClientRect();
sessionStorage.setItem('sidebar-scroll-offset', clientRect.top - sidebarRect.top);
}
}, { passive: true });
const sidebarScrollOffset = sessionStorage.getItem('sidebar-scroll-offset');
sessionStorage.removeItem('sidebar-scroll-offset');
if (sidebarScrollOffset !== null) {
// preserve sidebar scroll position when navigating via links within sidebar
const activeSection = this.querySelector('.active');
if (activeSection) {
const clientRect = activeSection.getBoundingClientRect();
const sidebarRect = this.getBoundingClientRect();
const currentOffset = clientRect.top - sidebarRect.top;
this.scrollTop += currentOffset - parseFloat(sidebarScrollOffset);
}
} else {
// scroll sidebar to current active section when navigating via
// 'next/previous chapter' buttons
const activeSection = document.querySelector('#mdbook-sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
// Toggle buttons
const sidebarAnchorToggles = document.querySelectorAll('.chapter-fold-toggle');
function toggleSection(ev) {
ev.currentTarget.parentElement.parentElement.classList.toggle('expanded');
}
Array.from(sidebarAnchorToggles).forEach(el => {
el.addEventListener('click', toggleSection);
});
}
}
window.customElements.define('mdbook-sidebar-scrollbox', MDBookSidebarScrollbox);
// ---------------------------------------------------------------------------
// Support for dynamically adding headers to the sidebar.
(function() {
// This is used to detect which direction the page has scrolled since the
// last scroll event.
let lastKnownScrollPosition = 0;
// This is the threshold in px from the top of the screen where it will
// consider a header the "current" header when scrolling down.
const defaultDownThreshold = 150;
// Same as defaultDownThreshold, except when scrolling up.
const defaultUpThreshold = 300;
// The threshold is a virtual horizontal line on the screen where it
// considers the "current" header to be above the line. The threshold is
// modified dynamically to handle headers that are near the bottom of the
// screen, and to slightly offset the behavior when scrolling up vs down.
let threshold = defaultDownThreshold;
// This is used to disable updates while scrolling. This is needed when
// clicking the header in the sidebar, which triggers a scroll event. It
// is somewhat finicky to detect when the scroll has finished, so this
// uses a relatively dumb system of disabling scroll updates for a short
// time after the click.
let disableScroll = false;
// Array of header elements on the page.
let headers;
// Array of li elements that are initially collapsed headers in the sidebar.
// I'm not sure why eslint seems to have a false positive here.
// eslint-disable-next-line prefer-const
let headerToggles = [];
// This is a debugging tool for the threshold which you can enable in the console.
let thresholdDebug = false;
// Updates the threshold based on the scroll position.
function updateThreshold() {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const windowHeight = window.innerHeight;
const documentHeight = document.documentElement.scrollHeight;
// The number of pixels below the viewport, at most documentHeight.
// This is used to push the threshold down to the bottom of the page
// as the user scrolls towards the bottom.
const pixelsBelow = Math.max(0, documentHeight - (scrollTop + windowHeight));
// The number of pixels above the viewport, at least defaultDownThreshold.
// Similar to pixelsBelow, this is used to push the threshold back towards
// the top when reaching the top of the page.
const pixelsAbove = Math.max(0, defaultDownThreshold - scrollTop);
// How much the threshold should be offset once it gets close to the
// bottom of the page.
const bottomAdd = Math.max(0, windowHeight - pixelsBelow - defaultDownThreshold);
let adjustedBottomAdd = bottomAdd;
// Adjusts bottomAdd for a small document. The calculation above
// assumes the document is at least twice the windowheight in size. If
// it is less than that, then bottomAdd needs to be shrunk
// proportional to the difference in size.
if (documentHeight < windowHeight * 2) {
const maxPixelsBelow = documentHeight - windowHeight;
const t = 1 - pixelsBelow / Math.max(1, maxPixelsBelow);
const clamp = Math.max(0, Math.min(1, t));
adjustedBottomAdd *= clamp;
}
let scrollingDown = true;
if (scrollTop < lastKnownScrollPosition) {
scrollingDown = false;
}
if (scrollingDown) {
// When scrolling down, move the threshold up towards the default
// downwards threshold position. If near the bottom of the page,
// adjustedBottomAdd will offset the threshold towards the bottom
// of the page.
const amountScrolledDown = scrollTop - lastKnownScrollPosition;
const adjustedDefault = defaultDownThreshold + adjustedBottomAdd;
threshold = Math.max(adjustedDefault, threshold - amountScrolledDown);
} else {
// When scrolling up, move the threshold down towards the default
// upwards threshold position. If near the bottom of the page,
// quickly transition the threshold back up where it normally
// belongs.
const amountScrolledUp = lastKnownScrollPosition - scrollTop;
const adjustedDefault = defaultUpThreshold - pixelsAbove
+ Math.max(0, adjustedBottomAdd - defaultDownThreshold);
threshold = Math.min(adjustedDefault, threshold + amountScrolledUp);
}
if (documentHeight <= windowHeight) {
threshold = 0;
}
if (thresholdDebug) {
const id = 'mdbook-threshold-debug-data';
let data = document.getElementById(id);
if (data === null) {
data = document.createElement('div');
data.id = id;
data.style.cssText = `
position: fixed;
top: 50px;
right: 10px;
background-color: 0xeeeeee;
z-index: 9999;
pointer-events: none;
`;
document.body.appendChild(data);
}
data.innerHTML = `
<table>
<tr><td>documentHeight</td><td>${documentHeight.toFixed(1)}</td></tr>
<tr><td>windowHeight</td><td>${windowHeight.toFixed(1)}</td></tr>
<tr><td>scrollTop</td><td>${scrollTop.toFixed(1)}</td></tr>
<tr><td>pixelsAbove</td><td>${pixelsAbove.toFixed(1)}</td></tr>
<tr><td>pixelsBelow</td><td>${pixelsBelow.toFixed(1)}</td></tr>
<tr><td>bottomAdd</td><td>${bottomAdd.toFixed(1)}</td></tr>
<tr><td>adjustedBottomAdd</td><td>${adjustedBottomAdd.toFixed(1)}</td></tr>
<tr><td>scrollingDown</td><td>${scrollingDown}</td></tr>
<tr><td>threshold</td><td>${threshold.toFixed(1)}</td></tr>
</table>
`;
drawDebugLine();
}
lastKnownScrollPosition = scrollTop;
}
function drawDebugLine() {
if (!document.body) {
return;
}
const id = 'mdbook-threshold-debug-line';
const existingLine = document.getElementById(id);
if (existingLine) {
existingLine.remove();
}
const line = document.createElement('div');
line.id = id;
line.style.cssText = `
position: fixed;
top: ${threshold}px;
left: 0;
width: 100vw;
height: 2px;
background-color: red;
z-index: 9999;
pointer-events: none;
`;
document.body.appendChild(line);
}
function mdbookEnableThresholdDebug() {
thresholdDebug = true;
updateThreshold();
drawDebugLine();
}
window.mdbookEnableThresholdDebug = mdbookEnableThresholdDebug;
// Updates which headers in the sidebar should be expanded. If the current
// header is inside a collapsed group, then it, and all its parents should
// be expanded.
function updateHeaderExpanded(currentA) {
// Add expanded to all header-item li ancestors.
let current = currentA.parentElement;
while (current) {
if (current.tagName === 'LI' && current.classList.contains('header-item')) {
current.classList.add('expanded');
}
current = current.parentElement;
}
}
// Updates which header is marked as the "current" header in the sidebar.
// This is done with a virtual Y threshold, where headers at or below
// that line will be considered the current one.
function updateCurrentHeader() {
if (!headers || !headers.length) {
return;
}
// Reset the classes, which will be rebuilt below.
const els = document.getElementsByClassName('current-header');
for (const el of els) {
el.classList.remove('current-header');
}
for (const toggle of headerToggles) {
toggle.classList.remove('expanded');
}
// Find the last header that is above the threshold.
let lastHeader = null;
for (const header of headers) {
const rect = header.getBoundingClientRect();
if (rect.top <= threshold) {
lastHeader = header;
} else {
break;
}
}
if (lastHeader === null) {
lastHeader = headers[0];
const rect = lastHeader.getBoundingClientRect();
const windowHeight = window.innerHeight;
if (rect.top >= windowHeight) {
return;
}
}
// Get the anchor in the summary.
const href = '#' + lastHeader.id;
const a = [...document.querySelectorAll('.header-in-summary')]
.find(element => element.getAttribute('href') === href);
if (!a) {
return;
}
a.classList.add('current-header');
updateHeaderExpanded(a);
}
// Updates which header is "current" based on the threshold line.
function reloadCurrentHeader() {
if (disableScroll) {
return;
}
updateThreshold();
updateCurrentHeader();
}
// When clicking on a header in the sidebar, this adjusts the threshold so
// that it is located next to the header. This is so that header becomes
// "current".
function headerThresholdClick(event) {
// See disableScroll description why this is done.
disableScroll = true;
setTimeout(() => {
disableScroll = false;
}, 100);
// requestAnimationFrame is used to delay the update of the "current"
// header until after the scroll is done, and the header is in the new
// position.
requestAnimationFrame(() => {
requestAnimationFrame(() => {
// Closest is needed because if it has child elements like <code>.
const a = event.target.closest('a');
const href = a.getAttribute('href');
const targetId = href.substring(1);
const targetElement = document.getElementById(targetId);
if (targetElement) {
threshold = targetElement.getBoundingClientRect().bottom;
updateCurrentHeader();
}
});
});
}
// Takes the nodes from the given head and copies them over to the
// destination, along with some filtering.
function filterHeader(source, dest) {
const clone = source.cloneNode(true);
clone.querySelectorAll('mark').forEach(mark => {
mark.replaceWith(...mark.childNodes);
});
dest.append(...clone.childNodes);
}
// Scans page for headers and adds them to the sidebar.
document.addEventListener('DOMContentLoaded', function() {
const activeSection = document.querySelector('#mdbook-sidebar .active');
if (activeSection === null) {
return;
}
const main = document.getElementsByTagName('main')[0];
headers = Array.from(main.querySelectorAll('h2, h3, h4, h5, h6'))
.filter(h => h.id !== '' && h.children.length && h.children[0].tagName === 'A');
if (headers.length === 0) {
return;
}
// Build a tree of headers in the sidebar.
const stack = [];
const firstLevel = parseInt(headers[0].tagName.charAt(1));
for (let i = 1; i < firstLevel; i++) {
const ol = document.createElement('ol');
ol.classList.add('section');
if (stack.length > 0) {
stack[stack.length - 1].ol.appendChild(ol);
}
stack.push({level: i + 1, ol: ol});
}
// The level where it will start folding deeply nested headers.
const foldLevel = 3;
for (let i = 0; i < headers.length; i++) {
const header = headers[i];
const level = parseInt(header.tagName.charAt(1));
const currentLevel = stack[stack.length - 1].level;
if (level > currentLevel) {
// Begin nesting to this level.
for (let nextLevel = currentLevel + 1; nextLevel <= level; nextLevel++) {
const ol = document.createElement('ol');
ol.classList.add('section');
const last = stack[stack.length - 1];
const lastChild = last.ol.lastChild;
// Handle the case where jumping more than one nesting
// level, which doesn't have a list item to place this new
// list inside of.
if (lastChild) {
lastChild.appendChild(ol);
} else {
last.ol.appendChild(ol);
}
stack.push({level: nextLevel, ol: ol});
}
} else if (level < currentLevel) {
while (stack.length > 1 && stack[stack.length - 1].level > level) {
stack.pop();
}
}
const li = document.createElement('li');
li.classList.add('header-item');
li.classList.add('expanded');
if (level < foldLevel) {
li.classList.add('expanded');
}
const span = document.createElement('span');
span.classList.add('chapter-link-wrapper');
const a = document.createElement('a');
span.appendChild(a);
a.href = '#' + header.id;
a.classList.add('header-in-summary');
filterHeader(header.children[0], a);
a.addEventListener('click', headerThresholdClick);
const nextHeader = headers[i + 1];
if (nextHeader !== undefined) {
const nextLevel = parseInt(nextHeader.tagName.charAt(1));
if (nextLevel > level && level >= foldLevel) {
const toggle = document.createElement('a');
toggle.classList.add('chapter-fold-toggle');
toggle.classList.add('header-toggle');
toggle.addEventListener('click', () => {
li.classList.toggle('expanded');
});
const toggleDiv = document.createElement('div');
toggleDiv.textContent = '❱';
toggle.appendChild(toggleDiv);
span.appendChild(toggle);
headerToggles.push(li);
}
}
li.appendChild(span);
const currentParent = stack[stack.length - 1];
currentParent.ol.appendChild(li);
}
const onThisPage = document.createElement('div');
onThisPage.classList.add('on-this-page');
onThisPage.append(stack[0].ol);
const activeItemSpan = activeSection.parentElement;
activeItemSpan.after(onThisPage);
});
document.addEventListener('DOMContentLoaded', reloadCurrentHeader);
document.addEventListener('scroll', reloadCurrentHeader, { passive: true });
})();