kempo-server 2.1.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CONFIG.md +295 -187
  2. package/README.md +31 -4
  3. package/SPA.md +14 -14
  4. package/UTILS.md +39 -0
  5. package/dist/defaultConfig.js +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/render.js +2 -0
  8. package/dist/rescan.js +1 -0
  9. package/dist/router.js +1 -1
  10. package/dist/serveFile.js +1 -1
  11. package/dist/templating/index.js +1 -0
  12. package/dist/templating/parse.js +1 -0
  13. package/docs/dist/caching.html +324 -0
  14. package/docs/dist/cli-utils.html +175 -0
  15. package/docs/dist/configuration.html +414 -0
  16. package/docs/dist/examples.html +296 -0
  17. package/docs/dist/fs-utils.html +206 -0
  18. package/docs/dist/getting-started.html +167 -0
  19. package/docs/dist/index.html +183 -0
  20. package/docs/dist/middleware.html +237 -0
  21. package/docs/dist/request-response.html +200 -0
  22. package/docs/dist/routing.html +177 -0
  23. package/docs/dist/templating.html +292 -0
  24. package/docs/{theme.css → dist/theme.css} +1 -3
  25. package/docs/src/.config.js +11 -0
  26. package/docs/{caching.html → src/caching.page.html} +4 -19
  27. package/docs/{cli-utils.html → src/cli-utils.page.html} +4 -20
  28. package/docs/{configuration.html → src/configuration.page.html} +4 -18
  29. package/docs/src/default.template.html +35 -0
  30. package/docs/{examples.html → src/examples.page.html} +9 -18
  31. package/docs/{fs-utils.html → src/fs-utils.page.html} +4 -20
  32. package/docs/{getting-started.html → src/getting-started.page.html} +4 -18
  33. package/docs/src/index.page.html +79 -0
  34. package/docs/{middleware.html → src/middleware.page.html} +4 -18
  35. package/docs/src/nav.fragment.html +73 -0
  36. package/docs/{request-response.html → src/request-response.page.html} +4 -18
  37. package/docs/{routing.html → src/routing.page.html} +4 -18
  38. package/docs/src/templating.page.html +188 -0
  39. package/{llm.txt → llms.txt} +100 -30
  40. package/package.json +7 -3
  41. package/scripts/build.js +19 -11
  42. package/scripts/render.js +58 -0
  43. package/src/defaultConfig.js +14 -2
  44. package/src/index.js +1 -1
  45. package/src/rescan.js +14 -0
  46. package/src/router.js +82 -11
  47. package/src/serveFile.js +27 -0
  48. package/src/templating/index.js +132 -0
  49. package/src/templating/parse.js +285 -0
  50. package/tests/cacheConfig.node-test.js +2 -2
  51. package/tests/config-flag.node-test.js +61 -25
  52. package/tests/customRoute-outside-root.node-test.js +1 -1
  53. package/tests/rescan.node-test.js +69 -0
  54. package/tests/router-wildcard.node-test.js +47 -2
  55. package/tests/templating-parse.node-test.js +243 -0
  56. package/tests/templating-render.node-test.js +188 -0
  57. package/tests/utils/test-scenario.js +4 -4
  58. package/docs/.config.json.example +0 -29
  59. package/docs/api/_admin/cache/DELETE.js +0 -28
  60. package/docs/api/_admin/cache/GET.js +0 -53
  61. package/docs/api/user/[id]/GET.js +0 -15
  62. package/docs/api/user/[id]/[info]/DELETE.js +0 -12
  63. package/docs/api/user/[id]/[info]/GET.js +0 -17
  64. package/docs/api/user/[id]/[info]/POST.js +0 -18
  65. package/docs/api/user/[id]/[info]/PUT.js +0 -19
  66. package/docs/index.html +0 -88
  67. package/docs/init.js +0 -0
  68. package/docs/kempo.min.css +0 -1
  69. package/docs/nav.inc.html +0 -41
  70. package/docs/nav.inc.js +0 -16
  71. /package/docs/{manifest.json → dist/manifest.json} +0 -0
  72. /package/docs/{media → dist/media}/hexagon.svg +0 -0
  73. /package/docs/{media → dist/media}/icon-maskable.png +0 -0
  74. /package/docs/{media → dist/media}/icon.svg +0 -0
  75. /package/docs/{media → dist/media}/icon128.png +0 -0
  76. /package/docs/{media → dist/media}/icon144.png +0 -0
  77. /package/docs/{media → dist/media}/icon152.png +0 -0
  78. /package/docs/{media → dist/media}/icon16-48.svg +0 -0
  79. /package/docs/{media → dist/media}/icon16.png +0 -0
  80. /package/docs/{media → dist/media}/icon192.png +0 -0
  81. /package/docs/{media → dist/media}/icon256.png +0 -0
  82. /package/docs/{media → dist/media}/icon32.png +0 -0
  83. /package/docs/{media → dist/media}/icon384.png +0 -0
  84. /package/docs/{media → dist/media}/icon48.png +0 -0
  85. /package/docs/{media → dist/media}/icon512.png +0 -0
  86. /package/docs/{media → dist/media}/icon64.png +0 -0
  87. /package/docs/{media → dist/media}/icon72.png +0 -0
  88. /package/docs/{media → dist/media}/icon96.png +0 -0
  89. /package/docs/{media → dist/media}/kempo-fist.svg +0 -0
@@ -0,0 +1,188 @@
1
+ import { renderPage, renderDir } from '../src/templating/index.js';
2
+ import { writeFile, mkdir, readFile } from 'fs/promises';
3
+ import path from 'path';
4
+ import { withTempDir } from './utils/temp-dir.js';
5
+
6
+ const setupFiles = async (dir, files) => {
7
+ for(const [rel, content] of Object.entries(files)){
8
+ const full = path.join(dir, rel);
9
+ await mkdir(path.dirname(full), {recursive: true});
10
+ await writeFile(full, content, 'utf8');
11
+ }
12
+ };
13
+
14
+ export default {
15
+ 'renderPage basic template + page': async ({pass, fail}) => {
16
+ await withTempDir(async dir => {
17
+ await setupFiles(dir, {
18
+ 'default.template.html': '<html><body><location name="main" /></body></html>',
19
+ 'index.page.html': '<page template="default"><content location="main"><h1>Hello</h1></content></page>'
20
+ });
21
+ const html = await renderPage(path.join(dir, 'index.page.html'), dir);
22
+ if(!html.includes('<h1>Hello</h1>')) return fail(`missing content: ${html}`);
23
+ if(!html.includes('<html>')) return fail(`missing template wrapper: ${html}`);
24
+ pass();
25
+ });
26
+ },
27
+ 'renderPage resolves variables': async ({pass, fail}) => {
28
+ await withTempDir(async dir => {
29
+ await setupFiles(dir, {
30
+ 'default.template.html': '<title>{{title}}</title><location name="main" />',
31
+ 'index.page.html': '<page template="default" title="My Page"><content location="main">body</content></page>'
32
+ });
33
+ const html = await renderPage(path.join(dir, 'index.page.html'), dir);
34
+ if(!html.includes('<title>My Page</title>')) return fail(`title not resolved: ${html}`);
35
+ pass();
36
+ });
37
+ },
38
+ 'renderPage resolves globals': async ({pass, fail}) => {
39
+ await withTempDir(async dir => {
40
+ await setupFiles(dir, {
41
+ 'default.template.html': '{{siteName}}<location name="main" />',
42
+ 'index.page.html': '<page template="default"><content location="main">x</content></page>'
43
+ });
44
+ const html = await renderPage(path.join(dir, 'index.page.html'), dir, {siteName: 'MySite'});
45
+ if(!html.includes('MySite')) return fail(`global not resolved: ${html}`);
46
+ pass();
47
+ });
48
+ },
49
+ 'renderPage resolves state': async ({pass, fail}) => {
50
+ await withTempDir(async dir => {
51
+ await setupFiles(dir, {
52
+ 'default.template.html': '{{greeting}}<location name="main" />',
53
+ 'index.page.html': '<page template="default"><content location="main">x</content></page>'
54
+ });
55
+ const html = await renderPage(path.join(dir, 'index.page.html'), dir, {}, {greeting: 'Hi'});
56
+ if(!html.includes('Hi')) return fail(`state not resolved: ${html}`);
57
+ pass();
58
+ });
59
+ },
60
+ 'renderPage resolves fragments': async ({pass, fail}) => {
61
+ await withTempDir(async dir => {
62
+ await setupFiles(dir, {
63
+ 'default.template.html': '<fragment name="header" /><location name="main" />',
64
+ 'header.fragment.html': '<header>Site Header</header>',
65
+ 'index.page.html': '<page template="default"><content location="main">body</content></page>'
66
+ });
67
+ const html = await renderPage(path.join(dir, 'index.page.html'), dir);
68
+ if(!html.includes('<header>Site Header</header>')) return fail(`fragment not resolved: ${html}`);
69
+ pass();
70
+ });
71
+ },
72
+ 'renderPage resolves if blocks': async ({pass, fail}) => {
73
+ await withTempDir(async dir => {
74
+ await setupFiles(dir, {
75
+ 'default.template.html': '<location name="main" />',
76
+ 'index.page.html': '<page template="default"><content location="main"><if condition="show">visible</if></content></page>'
77
+ });
78
+ const shown = await renderPage(path.join(dir, 'index.page.html'), dir, {show: true});
79
+ if(!shown.includes('visible')) return fail('should show when true');
80
+ const hidden = await renderPage(path.join(dir, 'index.page.html'), dir, {show: false});
81
+ if(hidden.includes('visible')) return fail('should hide when false');
82
+ pass();
83
+ });
84
+ },
85
+ 'renderPage resolves foreach blocks': async ({pass, fail}) => {
86
+ await withTempDir(async dir => {
87
+ await setupFiles(dir, {
88
+ 'default.template.html': '<location name="main" />',
89
+ 'index.page.html': '<page template="default"><content location="main"><foreach in="items" as="item"><li>{{item}}</li></foreach></content></page>'
90
+ });
91
+ const html = await renderPage(path.join(dir, 'index.page.html'), dir, {items: ['a', 'b']});
92
+ if(!html.includes('<li>a</li>')) return fail(`missing a: ${html}`);
93
+ if(!html.includes('<li>b</li>')) return fail(`missing b: ${html}`);
94
+ pass();
95
+ });
96
+ },
97
+ 'renderPage calculates pathToRoot': async ({pass, fail}) => {
98
+ await withTempDir(async dir => {
99
+ await setupFiles(dir, {
100
+ 'default.template.html': '{{pathToRoot}}<location name="main" />',
101
+ 'sub/deep/index.page.html': '<page template="default"><content location="main">x</content></page>'
102
+ });
103
+ const html = await renderPage(path.join(dir, 'sub', 'deep', 'index.page.html'), dir);
104
+ if(!html.includes('../../')) return fail(`pathToRoot wrong: ${html}`);
105
+ pass();
106
+ });
107
+ },
108
+ 'renderPage location fallback when content block not provided': async ({pass, fail}) => {
109
+ await withTempDir(async dir => {
110
+ await setupFiles(dir, {
111
+ 'default.template.html': '<location name="main">default content</location>',
112
+ 'index.page.html': '<page template="default"></page>'
113
+ });
114
+ const html = await renderPage(path.join(dir, 'index.page.html'), dir);
115
+ if(!html.includes('default content')) return fail(`fallback not used: ${html}`);
116
+ pass();
117
+ });
118
+ },
119
+ 'renderPage throws on missing template': async ({pass, fail}) => {
120
+ await withTempDir(async dir => {
121
+ await setupFiles(dir, {
122
+ 'index.page.html': '<page template="missing"><content location="main">x</content></page>'
123
+ });
124
+ try {
125
+ await renderPage(path.join(dir, 'index.page.html'), dir);
126
+ fail('should have thrown');
127
+ } catch(e){
128
+ if(!e.message.includes('Template not found')) return fail(`wrong error: ${e.message}`);
129
+ pass();
130
+ }
131
+ });
132
+ },
133
+ 'renderPage function globals are called': async ({pass, fail}) => {
134
+ await withTempDir(async dir => {
135
+ await setupFiles(dir, {
136
+ 'default.template.html': '{{fn}}<location name="main" />',
137
+ 'index.page.html': '<page template="default"><content location="main">x</content></page>'
138
+ });
139
+ const html = await renderPage(path.join(dir, 'index.page.html'), dir, {fn: () => 'called'});
140
+ if(!html.includes('called')) return fail(`function not called: ${html}`);
141
+ pass();
142
+ });
143
+ },
144
+ 'renderDir renders all page files and returns count': async ({pass, fail}) => {
145
+ await withTempDir(async dir => {
146
+ await setupFiles(dir, {
147
+ 'default.template.html': '<location name="main" />',
148
+ 'index.page.html': '<page template="default"><content location="main">home</content></page>',
149
+ 'about.page.html': '<page template="default"><content location="main">about</content></page>',
150
+ 'sub/index.page.html': '<page template="default"><content location="main">sub</content></page>'
151
+ });
152
+ const outDir = path.join(dir, 'out');
153
+ const count = await renderDir(dir, outDir);
154
+ if(count !== 3) return fail(`expected 3, got ${count}`);
155
+ const home = await readFile(path.join(outDir, 'index.html'), 'utf8');
156
+ if(!home.includes('home')) return fail(`home content wrong: ${home}`);
157
+ const about = await readFile(path.join(outDir, 'about.html'), 'utf8');
158
+ if(!about.includes('about')) return fail(`about content wrong: ${about}`);
159
+ const sub = await readFile(path.join(outDir, 'sub', 'index.html'), 'utf8');
160
+ if(!sub.includes('sub')) return fail(`sub content wrong: ${sub}`);
161
+ pass();
162
+ });
163
+ },
164
+ 'renderDir with same input and output overwrites in place': async ({pass, fail}) => {
165
+ await withTempDir(async dir => {
166
+ await setupFiles(dir, {
167
+ 'default.template.html': '<location name="main" />',
168
+ 'index.page.html': '<page template="default"><content location="main">content</content></page>'
169
+ });
170
+ const count = await renderDir(dir, dir);
171
+ if(count !== 1) return fail(`expected 1, got ${count}`);
172
+ const html = await readFile(path.join(dir, 'index.html'), 'utf8');
173
+ if(!html.includes('content')) return fail(`content wrong: ${html}`);
174
+ pass();
175
+ });
176
+ },
177
+ 'renderPage includes year built-in': async ({pass, fail}) => {
178
+ await withTempDir(async dir => {
179
+ await setupFiles(dir, {
180
+ 'default.template.html': '{{year}}<location name="main" />',
181
+ 'index.page.html': '<page template="default"><content location="main">x</content></page>'
182
+ });
183
+ const html = await renderPage(path.join(dir, 'index.page.html'), dir);
184
+ if(!html.includes(String(new Date().getFullYear()))) return fail(`year missing: ${html}`);
185
+ pass();
186
+ });
187
+ }
188
+ };
@@ -7,14 +7,14 @@ export const prepareTestScenario = async (dir, scenario) => {
7
7
  // Already has index.html, api/GET.js, etc.
8
8
  break;
9
9
  case 'wildcard-routes':
10
- await write(dir, 'docs/.config.json', JSON.stringify({
10
+ await write(dir, 'docs/.config.js', `export default ${JSON.stringify({
11
11
  customRoutes: { '/src/**': '../src/**' }
12
- }));
12
+ })}`);
13
13
  break;
14
14
  case 'middleware':
15
- await write(dir, '.config.json', JSON.stringify({
15
+ await write(dir, '.config.js', `export default ${JSON.stringify({
16
16
  middleware: { cors: {enabled: true} }
17
- }));
17
+ })}`);
18
18
  break;
19
19
  default:
20
20
  // No special preparation needed
@@ -1,29 +0,0 @@
1
- {
2
- "customRoutes": {
3
- "/vendor/bootstrap.css": "./node_modules/bootstrap/dist/css/bootstrap.min.css",
4
- "/vendor/bootstrap.js": "./node_modules/bootstrap/dist/js/bootstrap.min.js",
5
- "/vendor/jquery.js": "./node_modules/jquery/dist/jquery.min.js"
6
- },
7
- "allowedMimes": {
8
- "woff": "font/woff",
9
- "woff2": "font/woff2"
10
- },
11
- "disallowedRegex": [
12
- "private/",
13
- "\\.env$"
14
- ],
15
- "noRescanPaths": [
16
- "/vendor/"
17
- ],
18
- "maxRescanAttempts": 3,
19
- "cache": {
20
- "enabled": true,
21
- "maxSize": 150,
22
- "maxMemoryMB": 75,
23
- "ttlMs": 600000,
24
- "maxHeapUsagePercent": 75,
25
- "memoryCheckInterval": 20000,
26
- "watchFiles": true,
27
- "enableMemoryMonitoring": true
28
- }
29
- }
@@ -1,28 +0,0 @@
1
- /*
2
- Clear Cache Admin Endpoint
3
- */
4
-
5
- export default async (req, res) => {
6
- // Find the router instance to access moduleCache
7
- const moduleCache = req.moduleCache || req._kempoCache;
8
-
9
- if (!moduleCache) {
10
- res.writeHead(503, { 'Content-Type': 'application/json' });
11
- res.end(JSON.stringify({
12
- error: 'Cache not available',
13
- message: 'Module cache is not enabled or accessible'
14
- }));
15
- return;
16
- }
17
-
18
- // Clear cache
19
- const sizeBefore = moduleCache.cache.size;
20
- moduleCache.clear();
21
-
22
- res.writeHead(200, { 'Content-Type': 'application/json' });
23
- res.end(JSON.stringify({
24
- message: 'Cache cleared successfully',
25
- entriesCleared: sizeBefore,
26
- timestamp: new Date().toISOString()
27
- }));
28
- };
@@ -1,53 +0,0 @@
1
- /*
2
- Cache Administration Endpoint
3
- GET /_admin/cache - Returns cache statistics as JSON
4
- DELETE /_admin/cache - Clears the entire cache
5
- */
6
-
7
- export default async (req, res) => {
8
- // Find the router instance to access moduleCache
9
- // This is a bit of a hack - in practice you'd pass this through middleware
10
- const moduleCache = req.moduleCache || req._kempoCache;
11
-
12
- if (!moduleCache) {
13
- res.writeHead(503, { 'Content-Type': 'application/json' });
14
- res.end(JSON.stringify({
15
- error: 'Cache not available',
16
- message: 'Module cache is not enabled or accessible'
17
- }));
18
- return;
19
- }
20
-
21
- if (req.method === 'GET') {
22
- // Return cache statistics
23
- const stats = moduleCache.getStats();
24
- const cachedFiles = moduleCache.getCachedFiles();
25
-
26
- res.writeHead(200, { 'Content-Type': 'application/json' });
27
- res.end(JSON.stringify({
28
- ...stats,
29
- cachedFiles: cachedFiles.map(file => ({
30
- ...file,
31
- ageSeconds: Math.round(file.age / 1000)
32
- }))
33
- }, null, 2));
34
-
35
- } else if (req.method === 'DELETE') {
36
- // Clear cache
37
- const sizeBefore = moduleCache.cache.size;
38
- moduleCache.clear();
39
-
40
- res.writeHead(200, { 'Content-Type': 'application/json' });
41
- res.end(JSON.stringify({
42
- message: 'Cache cleared successfully',
43
- entriesCleared: sizeBefore
44
- }));
45
-
46
- } else {
47
- res.writeHead(405, { 'Content-Type': 'application/json' });
48
- res.end(JSON.stringify({
49
- error: 'Method not allowed',
50
- allowed: ['GET', 'DELETE']
51
- }));
52
- }
53
- };
@@ -1,15 +0,0 @@
1
- export default async function(request, response) {
2
- const { id } = request.params;
3
-
4
- // Example user data
5
- const userData = {
6
- id: id,
7
- profile: {
8
- name: `${id.charAt(0).toUpperCase()}${id.slice(1)}`,
9
- joinDate: '2024-01-15',
10
- posts: 42
11
- }
12
- };
13
-
14
- response.json(userData);
15
- }
@@ -1,12 +0,0 @@
1
- export default async function(request, response) {
2
- const { id, info } = request.params;
3
-
4
- // Example response for deleting user info
5
- const result = {
6
- id: id,
7
- message: 'User info deleted successfully',
8
- deletedAt: new Date().toISOString()
9
- };
10
-
11
- response.json(result);
12
- }
@@ -1,17 +0,0 @@
1
- export default async function(request, response) {
2
- const { id, info } = request.params;
3
-
4
- // Example detailed user info
5
- const userInfo = {
6
- id: id,
7
- details: {
8
- bio: `This is ${id}'s bio`,
9
- location: 'Earth',
10
- website: `https://${id}.dev`,
11
- followers: 123,
12
- following: 456
13
- }
14
- };
15
-
16
- response.json(userInfo);
17
- }
@@ -1,18 +0,0 @@
1
- export default async function(request, response) {
2
- const { id, info } = request.params;
3
-
4
- try {
5
- const updateData = await request.json();
6
-
7
- // Example response for updating user info
8
- const updatedUser = {
9
- id: id,
10
- message: 'User info updated successfully',
11
- updatedFields: updateData
12
- };
13
-
14
- response.json(updatedUser);
15
- } catch (error) {
16
- response.status(400).json({ error: 'Invalid JSON' });
17
- }
18
- }
@@ -1,19 +0,0 @@
1
- export default async function(request, response) {
2
- const { id, info } = request.params;
3
-
4
- try {
5
- const updateData = await request.json();
6
-
7
- // Example response for replacing user info
8
- const updatedUser = {
9
- id: id,
10
- message: 'User info replaced successfully',
11
- newData: updateData,
12
- updatedAt: new Date().toISOString()
13
- };
14
-
15
- response.json(updatedUser);
16
- } catch (error) {
17
- response.status(400).json({ error: 'Invalid JSON' });
18
- }
19
- }
package/docs/index.html DELETED
@@ -1,88 +0,0 @@
1
- <html lang="en" theme="auto">
2
- <head>
3
- <meta charset='utf-8'>
4
- <meta http-equiv='X-UA-Compatible' content='IE=edge'>
5
- <title>Kempo Server - Documentation</title>
6
- <meta name='viewport' content='width=device-width, initial-scale=1'>
7
- <link rel="icon" type="image/png" sizes="48x48" href="./media/icon48.png">
8
- <link rel="manifest" href="./manifest.json" />
9
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/kempo-css@1.3.2/dist/kempo.min.css" />
10
- <link rel="stylesheet" href="./theme.css" />
11
- <script>window.litDisableBundleWarning = true;</script>
12
- </head>
13
- <body>
14
- <k-import src="./nav.inc.html"></k-import>
15
- <main>
16
- <h1 class="ta-center">Kempo Server</h1>
17
- <div class="ta-center">
18
- <p class="mb0">
19
- <a href="https://github.com/dustinpoissant/kempo-server" class="btn primary mr" target="_blank">GitHub</a>
20
- <a href="https://www.npmjs.com/package/kempo-server" class="btn" target="_blank">NPM</a>
21
- </p>
22
- </div>
23
- <p>A lightweight, zero-dependency, file based routing server.</p>
24
-
25
- <nav class="b r mb p">
26
- <div class="row -mx">
27
- <div class="col m-span-12 d-span-6 px">
28
- <h4 class="mt0">Getting Started</h4>
29
- <ul>
30
- <li><a href="getting-started.html">Getting Started</a></li>
31
- <li><a href="routing.html">Routes & Routing</a></li>
32
- <li><a href="request-response.html">Request & Response</a></li>
33
- </ul>
34
- </div>
35
- <div class="col m-span-12 d-span-6 px">
36
- <h4 class="mt0">Advanced Features</h4>
37
- <ul>
38
- <li><a href="configuration.html">Configuration</a></li>
39
- <li><a href="middleware.html">Middleware</a></li>
40
- <li><a href="caching.html">Module Caching</a></li>
41
- <li><a href="cli-utils.html">CLI Utilities</a></li>
42
- <li><a href="fs-utils.html">File System Utilities</a></li>
43
- <li><a href="examples.html">Examples & Demos</a></li>
44
- </ul>
45
- </div>
46
- </div>
47
- </nav>
48
-
49
- <div class="b r mb p">
50
- <h3 class="mt0">Quick Start</h3>
51
- <p>Install and run Kempo Server in seconds:</p>
52
- <pre><code>npm install kempo-server
53
- npx kempo-server --root public</code></pre>
54
- </div>
55
-
56
- <div class="row -mx mb">
57
- <div class="col m-span-12 d-span-6 px">
58
- <div class="b r p">
59
- <h4 class="mt0">Features</h4>
60
- <ul>
61
- <li><strong>Zero Dependencies</strong> - No external dependencies</li>
62
- <li><strong>File-based Routing</strong> - Directory structure defines routes</li>
63
- <li><strong>Dynamic Routes</strong> - Parameterized routes with [brackets]</li>
64
- <li><strong>Wildcard Routes</strong> - Map directories with * patterns</li>
65
- <li><strong>Middleware System</strong> - Authentication, CORS, logging, and more</li>
66
- <li><strong>Request/Response Objects</strong> - Enhanced request handling</li>
67
- </ul>
68
- </div>
69
- </div>
70
- <div class="col m-span-12 d-span-6 px">
71
- <div class="b r p">
72
- <h4 class="mt0">Built-in Middleware</h4>
73
- <ul>
74
- <li><strong>CORS</strong> - Cross-origin resource sharing</li>
75
- <li><strong>Compression</strong> - Automatic gzip compression</li>
76
- <li><strong>Rate Limiting</strong> - Request throttling</li>
77
- <li><strong>Security Headers</strong> - Security best practices</li>
78
- <li><strong>Request Logging</strong> - Configurable logging</li>
79
- <li><strong>Custom Middleware</strong> - Load your own middleware</li>
80
- </ul>
81
- </div>
82
- </div>
83
- </div>
84
- </main>
85
- <div style="height:25vh"></div>
86
- <script type="module" src="https://cdn.jsdelivr.net/npm/kempo-ui@0.0.42/dist/components/Import.js"></script>
87
- </body>
88
- </html>
package/docs/init.js DELETED
File without changes
@@ -1 +0,0 @@
1
- :root{color-scheme:light;--ff_body:"Helvetica Neue",Helvetica,Arial,sans-serif;--ff_heading:"Helvetica Neue",Helvetica,Arial,sans-serif;--ff_mono:Consolas,monaco,monospace;--fs_base:16px;--fs_small:calc(0.6 * var(--fs_base));--fs_large:calc(1.5 * var(--fs_base));--fs_h6:var(--fs_base);--fs_h5:calc(1.25 * var(--fs_base));--fs_h4:calc(1.5 * var(--fs_base));--fs_h3:calc(1.75 * var(--fs_base));--fs_h2:calc(2 * var(--fs_base));--fs_h1:calc(2.5 * var(--fs_base));--fw_base:400;--fw_bold:700;--spacer:1rem;--spacer_h:calc(0.5 * var(--spacer));--spacer_q:calc(0.25 * var(--spacer));--line-height:1.35em;--container_width:90rem;--animation_ms:256ms;--radius:0.25rem;--link_decoration:underline;--input_padding:var(--spacer_h) var(--spacer);--input_border_width:1px;--btn_padding:var(--spacer_h) var(--spacer);--c_bg:light-dark(rgb(249, 249, 249), rgb(51, 51, 51));--c_bg__inv:light-dark(rgb(51, 51, 51), rgb(249, 249, 249));--c_bg__alt:light-dark(rgb(238, 238, 238), rgb(34, 34, 34));--c_overscroll:light-dark(rgb(255, 255, 255), rgb(0, 0, 0));--c_border:light-dark(rgb(204, 204, 204), rgb(119, 119, 119));--c_border__inv:light-dark(rgb(119, 119, 119), rgb(204, 204, 204));--c_primary:rgb(51, 102, 255);--c_primary__hover:rgb(17, 68, 221);--c_secondary:rgb(153, 51, 255);--c_secondary__hover:rgb(119, 17, 221);--c_success:rgb(0, 136, 0);--c_success__hover:rgb(0, 102, 0);--c_warning:rgb(255, 102, 0);--c_warning__hover:rgb(221, 68, 0);--c_danger:rgb(255, 0, 51);--c_danger__hover:rgb(221, 0, 17);--c_input_accent:rgb(51, 102, 255);--c_input_border:var(--c_border);--c_highlight:light-dark(rgba(41, 100, 210, 0.25), rgba(0, 89, 255, 0.25));--tc:light-dark(rgba(0, 0, 0, 0.93), rgba(255, 255, 255, 0.93));--tc_dark:light-dark(rgba(0, 0, 0, 0.93), rgba(0, 0, 0, 0.93));--tc_light:light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));--tc_inv:light-dark(rgba(255, 255, 255, 0.93), rgba(0, 0, 0, 0.93));--tc_muted:light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.5));--tc_on_primary:light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));--tc_on_secondary:light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));--tc_on_success:light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));--tc_on_warning:light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));--tc_on_danger:light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));--c_overlay:rgba(0, 0, 0, 0.5);--tc_primary:light-dark(#36f, rgb(138, 180, 248));--tc_secondary:light-dark(#93f, rgb(187, 102, 255));--tc_success:light-dark(#080, rgb(102, 187, 102));--tc_warning:light-dark(#f60, rgb(255, 153, 51));--tc_danger:light-dark(#f03, rgb(255, 85, 119));--btn_box_shadow:0 0 0 transparent;--btn_box_shadow__hover:0 0 0 transparent;--btn_border:transparent;--btn_bg:light-dark(rgb(221, 221, 221), rgb(170, 170, 170));--btn_bg__hover:light-dark(rgb(204, 204, 204), rgb(187, 187, 187));--btn_tc:light-dark(rgba(0, 0, 0, 0.93), rgba(0, 0, 0, 0.93));--btn_transparent__hover:light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.05));--tc_link:var(--tc_primary);--tc_link__hover:var(--tc_secondary);--tc_link__inv:var(--tc_primary__inv);--tc_link__inv__hover:var(--tc_secondary__inv);--focus_shadow:0 0 2px 2px var(--c_primary);--focus_shadow_on_primary:0 0 2px 2px var(--tc_on_primary);--input_bg:light-dark(white, var(--c_bg__alt));--input_tc:light-dark(rgba(0, 0, 0, 0.93), var(--tc));--drop_shadow__light:0 0.25rem 0.5rem rgba(0, 0, 0, 0.333);--drop_shadow__dark:0 0.25rem 0.5rem rgba(0, 0, 0, 0.5);--drop_shadow:var(--drop_shadow__light);--date_picker_icon_filter:light-dark(invert(0), invert(1));--elevation_-2_bg:light-dark(rgb(215, 215, 215), rgb(25, 25, 25));--elevation_-1_bg:light-dark(rgb(232, 232, 232), rgb(38, 38, 38));--elevation_0_bg:var(--c_bg);--elevation_1_bg:light-dark(rgb(255, 255, 255), rgb(64, 64, 64));--elevation_2_bg:light-dark(rgb(255, 255, 255), rgb(77, 77, 77));--elevation_3_bg:light-dark(rgb(255, 255, 255), rgb(90, 90, 90));--elevation_-2_shadow__light:inset 0 2px 6px rgba(0, 0, 0, 0.18),inset 0 1px 3px rgba(0, 0, 0, 0.12);--elevation_-1_shadow__light:inset 0 1px 3px rgba(0, 0, 0, 0.1),inset 0 1px 2px rgba(0, 0, 0, 0.06);--elevation_0_shadow:none;--elevation_1_shadow__light:0 1px 3px rgba(0, 0, 0, 0.1),0 1px 2px rgba(0, 0, 0, 0.16);--elevation_2_shadow__light:0 3px 6px rgba(0, 0, 0, 0.12),0 2px 4px rgba(0, 0, 0, 0.1);--elevation_3_shadow__light:0 8px 16px rgba(0, 0, 0, 0.14),0 3px 6px rgba(0, 0, 0, 0.1);--elevation_-2_shadow__dark:inset 0 2px 8px rgba(0, 0, 0, 0.5),inset 0 1px 4px rgba(0, 0, 0, 0.4);--elevation_-1_shadow__dark:inset 0 1px 4px rgba(0, 0, 0, 0.35),inset 0 1px 2px rgba(0, 0, 0, 0.25);--elevation_1_shadow__dark:0 2px 6px rgba(0, 0, 0, 0.5),0 1px 3px rgba(0, 0, 0, 0.4);--elevation_2_shadow__dark:0 4px 12px rgba(0, 0, 0, 0.55),0 2px 4px rgba(0, 0, 0, 0.45);--elevation_3_shadow__dark:0 8px 20px rgba(0, 0, 0, 0.6),0 4px 8px rgba(0, 0, 0, 0.5);--elevation_-2_shadow:var(--elevation_-2_shadow__light);--elevation_-1_shadow:var(--elevation_-1_shadow__light);--elevation_1_shadow:var(--elevation_1_shadow__light);--elevation_2_shadow:var(--elevation_2_shadow__light);--elevation_3_shadow:var(--elevation_3_shadow__light)}[theme=light]{color-scheme:light}[theme=dark]{color-scheme:dark;--drop_shadow:var(--drop_shadow__dark);--elevation_-2_shadow:var(--elevation_-2_shadow__dark);--elevation_-1_shadow:var(--elevation_-1_shadow__dark);--elevation_1_shadow:var(--elevation_1_shadow__dark);--elevation_2_shadow:var(--elevation_2_shadow__dark);--elevation_3_shadow:var(--elevation_3_shadow__dark)}[theme=auto]{color-scheme:light dark}@media (prefers-color-scheme:dark){[theme=auto]{--drop_shadow:var(--drop_shadow__dark);--elevation_-2_shadow:var(--elevation_-2_shadow__dark);--elevation_-1_shadow:var(--elevation_-1_shadow__dark);--elevation_1_shadow:var(--elevation_1_shadow__dark);--elevation_2_shadow:var(--elevation_2_shadow__dark);--elevation_3_shadow:var(--elevation_3_shadow__dark)}}:root{interpolate-size:allow-keywords}*,::after,::before{font-family:inherit;box-sizing:border-box;line-height:var(--line-height)}blockquote,body,code,dd,dl,dt,h1,h2,h3,h4,h5,h6,li,ol,p,pre,ul{margin:0;padding:.1px}html{font-family:var(--ff_body);font-size:var(--fs_base);font-weight:var(--fw_base);color:var(--tc);scrollbar-gutter:stable}::selection{background:var(--c_highlight)}body{min-height:100vh;background-color:var(--c_bg);color:var(--tc);overflow-y:scroll;font-family:var(--ff_body);position:relative}body.no-scroll{overflow:hidden!important}.container,main{max-width:var(--container_width);margin-left:auto;margin-right:auto;padding-top:var(--spacer);padding-left:var(--spacer);padding-right:var(--spacer)}nav>.link,nav>a{display:inline-block;padding:var(--spacer)!important;text-decoration:none}menu{margin:0;padding:0}menu a{display:block;padding:var(--spacer_q);text-decoration:none;color:inherit}summary{cursor:pointer;margin-bottom:var(--sapcer);outline:0;box-shadow:0 0 0 transparent;transition:box-shadow var(--animation_ms);border-radius:var(--radius)}summary:focus{box-shadow:var(--focus_shadow)}.d-b{display:block!important}.d-ib{display:inline-block!important}.d-g{display:grid!important}.d-i{display:inline!important}.d-n{display:none!important}.d-f{display:flex!important;flex-wrap:wrap}.d-if{display:inline-flex!important;flex-wrap:wrap}@media (min-width:1024px){.d-d-b{display:block!important}.d-d-ib{display:inline-block!important}.d-d-g{display:grid!important}.d-d-i{display:inline!important}.d-d-n{display:none!important}.d-d-f{display:flex!important;flex-wrap:wrap}.d-d-if{display:inline-flex!important;flex-wrap:wrap}}@media (min-width:769px) and (max-width:1023px){.t-d-b{display:block!important}.t-d-ib{display:inline-block!important}.t-d-g{display:grid!important}.t-d-i{display:inline!important}.t-d-n{display:none!important}.t-d-f{display:flex!important;flex-wrap:wrap}.t-d-if{display:inline-flex!important;flex-wrap:wrap}}@media (max-width:768px){.m-d-b{display:block!important}.m-d-ib{display:inline-block!important}.m-d-g{display:grid!important}.m-d-i{display:inline!important}.m-d-n{display:none!important}.m-d-f{display:flex!important;flex-wrap:wrap}.m-d-if{display:inline-flex!important;flex-wrap:wrap}}.flex,.flex-1{flex:1 1 auto}.flex-0{flex:0 0}.flex-2{flex:2 2 auto}.flex-3{flex:3 3 auto}.flex-4{flex:4 4 auto}.flex-5{flex:5 5 auto}.flex-6{flex:6 6 auto}.flex-7{flex:7 7 auto}.flex-8{flex:8 8 auto}.flex-9{flex:9 9 auto}.flex-10{flex:10 10 auto}@media (min-width:1024px){.d-d-b{display:block!important}.d-d-ib{display:inline-block!important}.d-d-g{display:grid!important}.d-d-i{display:inline!important}.d-d-n{display:none!important}.d-d-if{display:inline-flex!important;flex-wrap:wrap}.d-d-f{display:flex!important;flex-wrap:wrap}.d-flex,.d-flex-1{flex:1 1 auto}.d-flex-0{flex:0 0}.d-flex-2{flex:2 2 auto}.d-flex-3{flex:3 3 auto}.d-flex-4{flex:4 4 auto}.d-flex-5{flex:5 5 auto}.d-flex-6{flex:6 6 auto}.d-flex-7{flex:7 7 auto}.d-flex-8{flex:8 8 auto}.d-flex-9{flex:9 9 auto}.d-flex-10{flex:10 10 auto}}@media (min-width:769px) and (max-width:1023px){.t-d-b{display:block!important}.t-d-ib{display:inline-block!important}.t-d-g{display:grid!important}.t-d-i{display:inline!important}.t-d-n{display:none!important}.t-d-if{display:inline-flex!important;flex-wrap:wrap}.t-d-f{display:flex!important;flex-wrap:wrap}.t-flex,.t-flex-1{flex:1 1 auto}.t-flex-0{flex:0 0}.t-flex-2{flex:2 2 auto}.t-flex-3{flex:3 3 auto}.t-flex-4{flex:4 4 auto}.t-flex-5{flex:5 5 auto}.t-flex-6{flex:6 6 auto}.t-flex-7{flex:7 7 auto}.t-flex-8{flex:8 8 auto}.t-flex-9{flex:9 9 auto}.t-flex-10{flex:10 10 auto}}@media (max-width:768px){.m-d-b{display:block!important}.m-d-ib{display:inline-block!important}.m-d-g{display:grid!important}.m-d-i{display:inline!important}.m-d-n{display:none!important}.m-d-if{display:inline-flex!important;flex-wrap:wrap}.m-d-f{display:flex!important;flex-wrap:wrap}.m-flex,.m-flex-1{flex:1 1 auto}.m-flex-0{flex:0 0}.m-flex-2{flex:2 2 auto}.m-flex-3{flex:3 3 auto}.m-flex-4{flex:4 4 auto}.m-flex-5{flex:5 5 auto}.m-flex-6{flex:6 6 auto}.m-flex-7{flex:7 7 auto}.m-flex-8{flex:8 8 auto}.m-flex-9{flex:9 9 auto}.m-flex-10{flex:10 10 auto}}.fixed{position:fixed;top:0;width:100%;z-index:99;box-shadow:none;transition:box-shadow var(--animation_ms)}.fixed.scrolled{box-shadow:var(--elevation_2_shadow)}.small,small{font-size:var(--fs_small)!important}.large{font-size:var(--fs_large)!important}.h1,.h2,.h3,.h4,.h5,.h6,b,h1,h2,h3,h4,h5,h6,strong{font-weight:var(--fw_bold)}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:var(--ff_heading)}.h1,h1{font-size:var(--fs_h1)}.h2,h2{font-size:var(--fs_h2)}.h3,h3{font-size:var(--fs_h3)}.h4,h4{font-size:var(--fs_h4)}.h5,h5{font-size:var(--fs_h5)}.h6,h6{font-size:var(--fs_h6)}blockquote,dd,dl,h1,h2,h3,h4,h5,h6,hr,ol,p,pre,ul{margin-bottom:var(--spacer)}dl,ol,ul{padding-left:calc(1.5 * var(--spacer))}blockquote{border-left:2px solid var(--c_border);padding:var(--spacer)}mark{background-color:var(--c_highlight);color:inherit}.ff-mono,code,pre{font-family:var(--ff_mono)}code{background-color:var(--c_bg__alt);border-radius:var(--radius);word-break:break-word;padding:calc(.125 * var(--spacer)) var(--spacer_q)}pre code{display:block;padding:var(--spacer);word-break:normal;overflow:auto;white-space:pre-wrap}output{display:block;border:1px solid var(--c_border);border-radius:var(--radius);padding:var(--spacer) var(--spacer) 0 var(--spacer)}.ta-left{text-align:left}.ta-center{text-align:center}.ta-right{text-align:right}.link,a{color:var(--tc_link);box-shadow:0 0 0 transparent;transition:color var(--animation_ms),box-shadow var(--animation_ms);outline:0;border-radius:var(--radius);text-decoration:var(--link_decoration)}.link:hover,a:hover{color:var(--tc_link__hover)}.link:focus-visible,a:focus{box-shadow:var(--focus_shadow)}.no-link,.no-link:hover{text-decoration:none;color:inherit}hr{border:none;border-top:1px solid var(--c_border)}small{font-size:.75em}dl{padding:0;margin:0}dd,dt{padding-left:var(--spacer);border-left:2px solid var(--c_border)}dt{padding-top:var(--spacer_h)}dd{padding-bottom:var(--spacer_h)}dd+dd{margin-top:calc(-1 * var(--spacer));padding-top:0}li ul{margin-bottom:0}.td-n{text-decoration:none}.p,.pt,.py{padding-top:var(--spacer)!important}.p,.pr,.px{padding-right:var(--spacer)!important}.p,.pb,.py{padding-bottom:var(--spacer)!important}.p,.pl,.px{padding-left:var(--spacer)!important}.ph,.pth,.pyh{padding-top:var(--spacer_h)!important}.ph,.prh,.pxh{padding-right:var(--spacer_h)!important}.pbh,.ph,.pyh{padding-bottom:var(--spacer_h)!important}.ph,.plh,.pxh{padding-left:var(--spacer_h)!important}.pq,.ptq,.pyq{padding-top:var(--spacer_q)!important}.pq,.prq,.pxq{padding-right:var(--spacer_q)!important}.pbq,.pq,.pyq{padding-bottom:var(--spacer_q)!important}.plq,.pq,.pxq{padding-left:var(--spacer_q)!important}.p0,.pt0,.py0{padding-top:.1px!important}.p0,.pr0,.px0{padding-right:.1px!important}.p0,.pb0,.py0{padding-bottom:.1px!important}.p0,.pl0,.px0{padding-left:.1px!important}.m,.mt,.my{margin-top:var(--spacer)!important}.m,.mr,.mx{margin-right:var(--spacer)!important}.m,.mb,.my{margin-bottom:var(--spacer)!important}.m,.ml,.mx{margin-left:var(--spacer)!important}.mh,.mth,.myh{margin-top:var(--spacer_h)!important}.mh,.mrh,.mxh{margin-right:var(--spacer_h)!important}.mbh,.mh,.myh{margin-bottom:var(--spacer_h)!important}.mh,.mlh,.mxh{margin-left:var(--spacer_h)!important}.mq,.mtq,.myq{margin-top:var(--spacer_q)!important}.mq,.mrq,.mxq{margin-right:var(--spacer_q)!important}.mbq,.mq,.myq{margin-bottom:var(--spacer_q)!important}.mlq,.mq,.mxq{margin-left:var(--spacer_q)!important}.m0,.mt0,.my0{margin-top:0!important}.m0,.mr0,.mx0{margin-right:0!important}.m0,.mb0,.my0{margin-bottom:0!important}.m0,.ml0,.mx0{margin-left:0!important}.-m,.-mt,.-my{margin-top:calc(-1 * var(--spacer))!important}.-m,.-mr,.-mx{margin-right:calc(-1 * var(--spacer))!important}.-m,.-mb,.-my{margin-bottom:calc(-1 * var(--spacer))!important}.-m,.-ml,.-mx{margin-left:calc(-1 * var(--spacer))!important}.b,.bt,.by{border-top:1px solid var(--c_border)!important}.b,.br,.bx{border-right:1px solid var(--c_border)!important}.b,.bb,.by{border-bottom:1px solid var(--c_border)!important}.b,.bl,.bx{border-left:1px solid var(--c_border)!important}.b0,.bt0,.by0{border-top:none!important}.b0,.br0,.bx0{border-right:none!important}.b0,.bb0,.by0{border-bottom:none!important}.b0,.bl0,.bx0{border-left:none!important}.r,.rl,.rt,.rtl{border-top-left-radius:var(--radius)!important}.r,.rr,.rt,.rtr{border-top-right-radius:var(--radius)!important}.r,.rb,.rbr,.rr{border-bottom-right-radius:var(--radius)!important}.r,.rb,.rbl,.rl{border-bottom-left-radius:var(--radius)!important}.r0,.rl0,.rt0,.rtl0{border-top-left-radius:0!important}.r0,.rr0,.rt0,.rtr0{border-top-right-radius:0!important}.r0,.rb0,.rbr0,.rr0{border-bottom-right-radius:0!important}.r0,.rb0,.rbl0,.rl0{border-bottom-left-radius:0!important}.round{border-radius:9999rem!important}.row{display:flex;flex-wrap:wrap}.col{flex:1 1}.span-1{min-width:8.333%;flex-basis:8.333%}.span-2{min-width:16.666%;flex-basis:16.666%}.span-3{min-width:25%;flex-basis:25%}.span-4{min-width:33.333%;flex-basis:33.333%}.span-5{min-width:41.666%;flex-basis:41.666%}.span-6{min-width:50%;flex-basis:50%}.span-7{min-width:58.333%;flex-basis:58.333%}.span-8{min-width:66.666%;flex-basis:66.666%}.span-9{min-width:75%;flex-basis:75%}.span-10{min-width:83.333%;flex-basis:83.333%}.span-11{min-width:91.333%;flex-basis:91.333%}.span-12{min-width:100%;flex-basis:100%}@media (min-width:1024px){.d-span-1{min-width:8.333%;flex-basis:8.333%}.d-span-2{min-width:16.666%;flex-basis:16.666%}.d-span-3{min-width:25%;flex-basis:25%}.d-span-4{min-width:33.333%;flex-basis:33.333%}.d-span-5{min-width:41.666%;flex-basis:41.666%}.d-span-6{min-width:50%;flex-basis:50%}.d-span-7{min-width:58.333%;flex-basis:58.333%}.d-span-8{min-width:66.666%;flex-basis:66.666%}.d-span-9{min-width:75%;flex-basis:75%}.d-span-10{min-width:83.333%;flex-basis:83.333%}.d-span-11{min-width:91.333%;flex-basis:91.333%}.d-span-12{min-width:100%;flex-basis:100%}}@media (min-width:769px) and (max-width:1023px){.t-span-1{min-width:8.333%;flex-basis:8.333%}.t-span-2{min-width:16.666%;flex-basis:16.666%}.t-span-3{min-width:25%;flex-basis:25%}.t-span-4{min-width:33.333%;flex-basis:33.333%}.t-span-5{min-width:41.666%;flex-basis:41.666%}.t-span-6{min-width:50%;flex-basis:50%}.t-span-7{min-width:58.333%;flex-basis:58.333%}.t-span-8{min-width:66.666%;flex-basis:66.666%}.t-span-9{min-width:75%;flex-basis:75%}.t-span-10{min-width:83.333%;flex-basis:83.333%}.t-span-11{min-width:91.333%;flex-basis:91.333%}.t-span-12{min-width:100%;flex-basis:100%}}@media (max-width:768px){.m-span-1{min-width:8.333%;flex-basis:8.333%}.m-span-2{min-width:16.666%;flex-basis:16.666%}.m-span-3{min-width:25%;flex-basis:25%}.m-span-4{min-width:33.333%;flex-basis:33.333%}.m-span-5{min-width:41.666%;flex-basis:41.666%}.m-span-6{min-width:50%;flex-basis:50%}.m-span-7{min-width:58.333%;flex-basis:58.333%}.m-span-8{min-width:66.666%;flex-basis:66.666%}.m-span-9{min-width:75%;flex-basis:75%}.m-span-10{min-width:83.333%;flex-basis:83.333%}.m-span-11{min-width:91.333%;flex-basis:91.333%}.m-span-12{min-width:100%;flex-basis:100%}}.cols-2{grid-template-columns:repeat(2,1fr)}.cols-3{grid-template-columns:repeat(3,1fr)}.cols-4{grid-template-columns:repeat(4,1fr)}.cols-5{grid-template-columns:repeat(5,1fr)}.cols-6{grid-template-columns:repeat(6,1fr)}.cols-7{grid-template-columns:repeat(7,1fr)}.cols-8{grid-template-columns:repeat(8,1fr)}.cols-9{grid-template-columns:repeat(9,1fr)}.cols-10{grid-template-columns:repeat(10,1fr)}@media (min-width:1024px){.d-cols-2{grid-template-columns:repeat(2,1fr)}.d-cols-3{grid-template-columns:repeat(3,1fr)}.d-cols-4{grid-template-columns:repeat(4,1fr)}.d-cols-5{grid-template-columns:repeat(5,1fr)}.d-cols-6{grid-template-columns:repeat(6,1fr)}.d-cols-7{grid-template-columns:repeat(7,1fr)}.d-cols-8{grid-template-columns:repeat(8,1fr)}.d-cols-9{grid-template-columns:repeat(9,1fr)}.d-cols-10{grid-template-columns:repeat(10,1fr)}}@media (min-width:769px) and (max-width:1023px){.t-cols-2{grid-template-columns:repeat(2,1fr)}.t-cols-3{grid-template-columns:repeat(3,1fr)}.t-cols-4{grid-template-columns:repeat(4,1fr)}.t-cols-5{grid-template-columns:repeat(5,1fr)}.t-cols-6{grid-template-columns:repeat(6,1fr)}.t-cols-7{grid-template-columns:repeat(7,1fr)}.t-cols-8{grid-template-columns:repeat(8,1fr)}.t-cols-9{grid-template-columns:repeat(9,1fr)}.t-cols-10{grid-template-columns:repeat(10,1fr)}}@media (max-width:768px){.m-cols-2{grid-template-columns:repeat(2,1fr)}.m-cols-3{grid-template-columns:repeat(3,1fr)}.m-cols-4{grid-template-columns:repeat(4,1fr)}.m-cols-5{grid-template-columns:repeat(5,1fr)}.m-cols-6{grid-template-columns:repeat(6,1fr)}.m-cols-7{grid-template-columns:repeat(7,1fr)}.m-cols-8{grid-template-columns:repeat(8,1fr)}.m-cols-9{grid-template-columns:repeat(9,1fr)}.m-cols-10{grid-template-columns:repeat(10,1fr)}}.btn,button:not(.no-btn):not(.no-style),input[type=button],input[type=reset],input[type=submit]{display:inline-block;padding:var(--btn_padding);background-color:var(--btn_bg);border:1px solid var(--btn_border);cursor:pointer;outline:0;border-radius:var(--radius);color:var(--btn_tc);transition:background-color var(--animation_ms),box-shadow var(--animation_ms);text-decoration:none;box-shadow:var(--btn_box_shadow);font-size:inherit;vertical-align:middle}.btn:hover,button:not(.no-btn):not(.no-style):hover,input[type=button]:hover,input[type=reset]:hover,input[type=submit]:hover{background-color:var(--btn_bg__hover);color:var(--btn_tc);box-shadow:var(--btn_box_shadow__hover)}.btn:focus,button:not(.no-btn):not(.no-style):focus,input[type=button]:focus,input[type=reset]:focus,input[type=submit]:focus{box-shadow:var(--btn_box_shadow__hover),var(--focus_shadow);z-index:1}.btn[disabled],button:not(.no-btn):not(.no-style):disabled,input[type=button]:disabled,input[type=reset]:disabled,input[type=submit]:disabled{opacity:.6}.btn.primary,button:not(.no-btn).primary,input[type=button].primary,input[type=reset].primary,input[type=submit].primary{background-color:var(--c_primary)!important;--btn_tc:var(--tc_on_primary)}.btn.primary:hover,button:not(.no-btn).primary:hover,input[type=button].primary:hover,input[type=reset].primary:hover,input[type=submit].primary:hover{background-color:var(--c_primary__hover)!important}.btn.secondary,button:not(.no-btn).secondary,input[type=button].secondary,input[type=reset].secondary,input[type=submit].secondary{background-color:var(--c_secondary)!important;--btn_tc:var(--tc_on_secondary)}.btn.secondary:hover,button:not(.no-btn).secondary:hover,input[type=button].secondary:hover,input[type=reset].secondary:hover,input[type=submit].secondary:hover{background-color:var(--c_secondary__hover)!important}.btn.success,button:not(.no-btn).success,input[type=button].success,input[type=reset].success,input[type=submit].success{background-color:var(--c_success)!important;--btn_tc:var(--tc_on_success)}.btn.success:hover,button:not(.no-btn).success:hover,input[type=button].success:hover,input[type=reset].success:hover,input[type=submit].success:hover{background-color:var(--c_success__hover)!important}.btn.warning,button:not(.no-btn).warning,input[type=button].warning,input[type=reset].warning,input[type=submit].warning{background-color:var(--c_warning)!important;--btn_tc:var(--tc_on_warning)}.btn.warning:hover,button:not(.no-btn).warning:hover,input[type=button].warning:hover,input[type=reset].warning:hover,input[type=submit].warning:hover{background-color:var(--c_warning__hover)!important}.btn.danger,button:not(.no-btn).danger,input[type=button].danger,input[type=reset].danger,input[type=submit].danger{background-color:var(--c_danger)!important;--btn_tc:var(--tc_on_danger)}.btn.danger:hover,button:not(.no-btn).danger:hover,input[type=button].danger:hover,input[type=reset].danger:hover,input[type=submit].danger:hover{background-color:var(--c_danger__hover)!important}.btn.link,button:not(.no-btn):not(.no-style).link,input[type=button].link,input[type=reset].link,input[type=submit].link{background-color:transparent;color:inherit;box-shadow:0 0 0 transparent;border:none;padding:.1px;font-size:inherit}.btn-grp{display:inline-flex}.btn-grp .btn:not(:first-child),.btn-grp button:not(.no-btn):not(:first-child),.btn-grp input[type=button]:not(:first-child),.btn-grp input[type=reset]:not(:first-child),.btn-grp input[type=submit]:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0;border-left:1px solid rgba(0,0,0,.25)}.btn-grp .btn:not(:last-child),.btn-grp button:not(.no-btn):not(:last-child),.btn-grp input[type=button]:not(:last-child),.btn-grp input[type=reset]:not(:last-child),.btn-grp input[type=submit]:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.no-btn{display:inline;border:none;background-color:transparent;padding:0;font-size:inherit;font-family:inherit;cursor:pointer;outline:0;box-shadow:0 0 0 transparent;transition:box-shadow var(--animation_ms);border-radius:0;text-align:left;color:inherit}.no-btn:focus{box-shadow:var(--focus_shadow)}.full{display:block;width:100%}input:not([type=button]):not([type=submit]):not([type=reset]):not([type=radio]):not([type=checkbox]),select,textarea{display:block;width:100%;background-color:var(--input_bg);color:var(--input_tc);border:var(--input_border_width) solid var(--c_input_border);padding:var(--input_padding);border-radius:var(--radius);outline:0;transition:box-shadow var(--animation_ms)}input:not([type=button]):not([type=submit]):not([type=reset]):not([type=radio]):not([type=checkbox]):focus,input[type=checkbox]:focus,input[type=radio]:focus,select:focus,textarea:focus{box-shadow:var(--focus_shadow)}input:not([type=button]):not([type=submit]):not([type=reset]):not([type=radio]):not([type=checkbox]):disabled,input[type=checkbox]:disabled,input[type=radio]:disabled,select:disabled,textarea:disabled{opacity:.6}select[multiple],textarea{resize:vertical;max-height:75vh;height:6rem;min-height:4rem}select[multiple]{height:8rem}select{cursor:pointer}label{display:block;cursor:pointer;padding-bottom:var(--spacer_h)}label.checkbox,label.radio{display:inline-block;vertical-align:middle;width:calc(100% - 2em - (2 * var(--spacer_h)) - 6px)}input[type=checkbox],input[type=radio]{display:inline-block;width:1em;height:1em;cursor:pointer;vertical-align:middle;accent-color:var(--c_input_accent);margin:var(--spacer_q) var(--spacer_h);transition:background-color var(--animation_ms),color var(--animation_ms),box-shadow var(--animation_ms)}input[type=checkbox]{width:1.75em;height:1.75em;appearance:none;-webkit-appearance:none;background-color:transparent;border:2px solid var(--c_border);border-radius:var(--radius);vertical-align:-.5em;position:relative}input[type=checkbox]::before{content:"";position:absolute;inset:0;border-radius:calc(var(--radius) - 2px);background-color:transparent;mask-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="200 -760 560 560"><path d="m424-312 282-282-56-56-226 226-114-114-56 56 170 170Z"/></svg>');-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="200 -760 560 560"><path d="m424-312 282-282-56-56-226 226-114-114-56 56 170 170Z"/></svg>');mask-size:contain;-webkit-mask-size:contain;mask-position:center;-webkit-mask-position:center;mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;transition:background-color var(--animation_ms)}input[type=checkbox]:focus{box-shadow:var(--focus_shadow);outline:0}input[type=checkbox]:checked{background-color:var(--c_primary);border-color:var(--c_primary)}input[type=checkbox]:checked::before{background-color:var(--tc_on_primary)}input[type=radio]{width:1.75em;height:1.75em;appearance:none;-webkit-appearance:none;background-color:transparent;border:2px solid var(--c_border);border-radius:50%;vertical-align:-.5em}input[type=radio]:focus{box-shadow:var(--focus_shadow);outline:0}input[type=radio]:checked{border-color:var(--c_primary);background:radial-gradient(circle,var(--c_primary) 40%,transparent 45%)}select option{padding:var(--spacer_h) var(--spacer);background-color:var(--input_bg);color:var(--input_tc)}select[multiple]{padding:.1px}select[multiple] option{padding:var(--spacer_h) var(--spacer)}input[type=color]{padding:0!important;height:2.35em}input[type=color]::-webkit-color-swatch-wrapper{padding:0}input[type=color]::-webkit-color-swatch{border-radius:var(--radius,.25rem);cursor:pointer}input[type=date]::-webkit-calendar-picker-indicator,input[type=month]::-webkit-calendar-picker-indicator,input[type=search]::-webkit-search-cancel-button,input[type=time]::-webkit-calendar-picker-indicator,input[type=week]::-webkit-calendar-picker-indicator{filter:var(--date_picker_icon_filter)}.table-wrapper{overflow-x:auto}table{width:100%;border-spacing:0}th{font-weight:var(--fw_bold);text-align:left;background-color:var(--c_bg__alt);border-top:1px solid var(--c_border)}td,th{padding:var(--spacer_h) var(--spacer);border-bottom:1px solid var(--c_border);border-left:1px solid var(--c_border)}td:last-child,th:last-child{border-right:1px solid var(--c_border)}th:first-child{border-top-left-radius:var(--radius)}th:last-child{border-top-right-radius:var(--radius)}tr:last-child td:first-child{border-bottom-left-radius:var(--radius)}tr:last-child td:last-child{border-bottom-right-radius:var(--radius)}.bg-default{background-color:var(--c_bg)!important;color:var(--tc)!important}.bg-alt{background-color:var(--c_bg__alt)!important;color:var(--tc)!important}.bg-inv{--c_primary:var(--c_primary__inv);--c_primary__hover:var(--c_primary__inv__hover);--c_secondary:var(--c_secondary__inv);--c_secondary__hover:var(--c_secondary__inv__hover);--c_success:var(--c_success__inv);--c_success__hover:var(--c_success__inv__hover);--c_warning:var(--c_warning__inv);--c_warning__hover:var(--c_warning__inv__hover);--c_danger:var(--c_danger__inv);--c_danger__hover:var(--c_danger__inv__hover);--tc_link:var(--tc_link__inv);--tc_link__hover:var(--tc_link__inv__hover);background-color:var(--c_bg__inv)!important;color:var(--tc_inv)!important}.bg-primary{--tc_link:var(--tc_on_primary);--tc_link__hover:var(--tc_on_primary);--c_border:var(--tc_on_primary);background-color:var(--c_primary)!important;color:var(--tc_on_primary)!important;--focus_shadow:var(--focus_shadow_on_primary)}.bg-secondary{--tc_link:var(--tc_on_secondary);--tc_link__hover:var(--tc_on_secondary);background-color:var(--c_secondary)!important;color:var(--tc_on_secondary)!important}.bg-success{--tc_link:var(--tc_on_success);--tc_link__hover:var(--tc_on_success);background-color:var(--c_success)!important;color:var(--tc_on_success)!important}.bg-warning{--tc_link:var(--tc_on_warning);--tc_link__hover:var(--tc_on_warning);background-color:var(--c_warning)!important;color:var(--tc_on_warning)!important}.bg-danger{--tc_link:var(--tc_on_danger);--tc_link__hover:var(--tc_on_danger);background-color:var(--c_danger)!important;color:var(--tc_on_danger)!important}.tc-default{color:var(--tc)!important}.tc-inv{color:var(--tc__inv)!important}.tc-primary{color:var(--tc_primary)!important}.bg-inv .tc-primary,.is-inv .tc-primary{color:var(--tc_primary__inv)!important}.tc-secondary{color:var(--tc_secondary)!important}.bg-inv .tc-secondary,.is-inv .tc-secondary{color:var(--tc_secondary__inv)!important}.tc-success{color:var(--tc_success)!important}.bg-inv .tc-success,.is-inv .tc-success{color:var(--tc_success__inv)!important}.tc-warning{color:var(--tc_warning)!important}.bg-inv .tc-warning,.is-inv .tc-warning{color:var(--tc_warning__inv)!important}.tc-danger{color:var(--tc_danger)!important}.bg-inv .tc-danger,.is-inv .tc-danger{color:var(--tc_danger__inv)!important}.tc-muted{color:var(--tc_muted)!important}.card{border:1px solid var(--c_border);border-radius:var(--radius);padding-top:var(--spacer);padding-left:var(--spacer);padding-right:var(--spacer);margin-bottom:var(--spacer)}.drop-shadow{box-shadow:var(--drop_shadow)}.elevation--2{background-color:var(--elevation_-2_bg);box-shadow:var(--elevation_-2_shadow)}.elevation--1{background-color:var(--elevation_-1_bg);box-shadow:var(--elevation_-1_shadow)}.elevation-0{background-color:var(--elevation_0_bg);box-shadow:var(--elevation_0_shadow)}.elevation-1{background-color:var(--elevation_1_bg);box-shadow:var(--elevation_1_shadow)}.elevation-2{background-color:var(--elevation_2_bg);box-shadow:var(--elevation_2_shadow)}.elevation-3{background-color:var(--elevation_3_bg);box-shadow:var(--elevation_3_shadow)}.icon{display:inline-block;width:1.35em;vertical-align:top;margin-left:auto;margin-right:auto}iframe{border:none;width:100%}
package/docs/nav.inc.html DELETED
@@ -1,41 +0,0 @@
1
- <nav
2
- class="d-f bg-primary fixed"
3
- >
4
- <button
5
- id="toggleNavSideMenu"
6
- class="link"
7
- >
8
- <k-icon name="menu"></k-icon>
9
- </button>
10
- <a
11
- href="./"
12
- class="d-if ph"
13
- style="align-items: center"
14
- >
15
- <img src="./media/icon32.png" alt="Kempo Server Icon" class="pr" />
16
- Kempo Server
17
- </a>
18
- <div class="flex"></div>
19
- <a href="https://github.com/dustinpoissant/kempo-ui?tab=License-1-ov-file#creative-commons-attribution-noncommercial-sharealike-20" target="_blank"><k-icon name="license"></k-icont></a>
20
- <a href="https://github.com/dustinpoissant/kempo-ui" target="_blank"><k-icon name="github-mark"></k-icont></a>
21
- <k-theme-switcher></k-theme-switcher>
22
- </nav>
23
- <div style="width: 100%; height: 4rem;"></div>
24
- <k-side-menu
25
- id="navSideMenu"
26
- >
27
- <menu>
28
- <a href="./" class="ta-center bb mb r0">
29
- <h1 class="tc-primary">Kempo Server</h1>
30
- <img src="./media/icon128.png" alt="Kempo UI Icon" />
31
- </a>
32
-
33
- <div class="pl mb">
34
- <a href="./">Quick Start</a>
35
- </div>
36
- </menu>
37
- </k-side-menu>
38
- <script src="https://cdn.jsdelivr.net/npm/kempo-ui@0.0.42/dist/components/SideMenu.js" type="module"></script>
39
- <script src="https://cdn.jsdelivr.net/npm/kempo-ui@0.0.42/dist/components/Icon.js" type="module"></script>
40
- <script src="https://cdn.jsdelivr.net/npm/kempo-ui@0.0.42/dist/components/ThemeSwitcher.js" type="module"></script>
41
- <script src="./nav.inc.js" type="module"></script>
package/docs/nav.inc.js DELETED
@@ -1,16 +0,0 @@
1
- document.getElementById('toggleNavSideMenu').addEventListener('click', async () => {
2
- await window.customElements.whenDefined('k-side-menu');
3
- document.getElementById('navSideMenu').toggle();
4
- });
5
- document.addEventListener('click', function(e) {
6
- if (e.target.matches('a[href^="#"]')) {
7
- e.preventDefault();
8
- const targetId = e.target.getAttribute('href').replace('#', '');
9
- const target = document.getElementById(targetId);
10
- if (target) {
11
- target.scrollIntoView({ behavior: 'smooth' });
12
- const url = window.location.pathname + window.location.search + '#' + targetId;
13
- history.replaceState(null, '', url);
14
- }
15
- }
16
- });
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes