@h3ravel/router 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/index.cjs.map +1 -1
- package/package.json +5 -5
- package/src/index.ts +0 -5
- package/src/Decorators/ApiResource.ts +0 -1
- package/src/Decorators/Controller.ts +0 -1
- package/src/Decorators/Get.ts +0 -1
- package/src/Decorators/Middleware.ts +0 -1
- package/src/Decorators/Post.ts +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<p align="center"><a href="https://h3ravel.toneflix.net" target="_blank"><img src="https://raw.githubusercontent.com/h3ravel/assets/refs/heads/main/logo-full.svg" width="400" alt="H3ravel Logo"></a></p>
|
|
2
|
+
|
|
3
|
+
[![Framework][ix]][lx]
|
|
4
|
+
[![Router Package Version][i1]][l1]
|
|
5
|
+
|
|
6
|
+
# About H3ravel/router
|
|
7
|
+
|
|
8
|
+
This is the route mangement and resolution system for the [H3ravel](https://h3ravel.toneflix.net) framework.
|
|
9
|
+
|
|
10
|
+
## Contributing
|
|
11
|
+
|
|
12
|
+
Thank you for considering contributing to the H3ravel framework! The contribution guide can be found in the [H3ravel documentation](#!).
|
|
13
|
+
|
|
14
|
+
## Code of Conduct
|
|
15
|
+
|
|
16
|
+
In order to ensure that the H3ravel community is welcoming to all, please review and abide by the [Code of Conduct](#).
|
|
17
|
+
|
|
18
|
+
## Security Vulnerabilities
|
|
19
|
+
|
|
20
|
+
If you discover a security vulnerability within H3ravel, please send an e-mail to Legacy via hamzas.legacy@toneflix.ng. All security vulnerabilities will be promptly addressed.
|
|
21
|
+
|
|
22
|
+
## License
|
|
23
|
+
|
|
24
|
+
The H3ravel framework is open-sourced software licensed under the [MIT license](LICENSE).
|
|
25
|
+
|
|
26
|
+
[ix]: https://img.shields.io/npm/v/%40h3ravel%2Fcore?style=flat-square&label=Framework&color=%230970ce
|
|
27
|
+
[lx]: https://www.npmjs.com/package/@h3ravel/core
|
|
28
|
+
[i1]: https://img.shields.io/npm/v/%40h3ravel%2Frouter?style=flat-square&label=@h3ravel/router&color=%230970ce
|
|
29
|
+
[l1]: https://www.npmjs.com/package/@h3ravel/router
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/Route.ts","../src/Providers/AssetsServiceProvider.ts","../src/Providers/RouteServiceProvider.ts"],"sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from './Controller';\nexport * from './Route';\nexport * from './Decorators/ApiResource';\nexport * from './Decorators/Controller';\nexport * from './Decorators/Get';\nexport * from './Decorators/Middleware';\nexport * from './Decorators/Post';\nexport * from './Providers/AssetsServiceProvider';\nexport * from './Providers/RouteServiceProvider';\n","import { H3Event, Middleware, MiddlewareOptions, type H3 } from 'h3'\nimport { Request, Response } from '@h3ravel/http'\nimport { Application, Controller, Kernel } from '@h3ravel/core'\nimport { afterLast } from '@h3ravel/support'\nimport { EventHandler, IController, IMiddleware } from '@h3ravel/shared'\n\ninterface RouteDefinition {\n method: string\n path: string\n name?: string\n handler: EventHandler\n}\n\nexport class Router {\n private routes: RouteDefinition[] = []\n private groupPrefix = ''\n private groupMiddleware: EventHandler[] = []\n\n constructor(protected h3App: H3, private app: Application) { }\n\n /**\n * Route Resolver\n * \n * @param handler \n * @param middleware \n * @returns \n */\n private resolveHandler (handler: EventHandler, middleware: IMiddleware[] = []) {\n return async (event: H3Event) => {\n const kernel = new Kernel(() => ({\n request: new Request(event),\n response: new Response(event)\n }), middleware)\n\n return kernel.handle(event, (ctx) => Promise.resolve(handler(ctx)))\n }\n }\n\n /**\n * Add a route to the stack\n * \n * @param method \n * @param path \n * @param handler \n * @param name \n * @param middleware \n */\n private addRoute (\n method: string,\n path: string,\n handler: EventHandler,\n name?: string,\n middleware: IMiddleware[] = []\n ) {\n const fullPath = `${this.groupPrefix}${path}`.replace(/\\/+/g, '/')\n this.routes.push({ method, path: fullPath, name, handler })\n this.h3App[method as 'get'](fullPath, this.resolveHandler(handler, middleware))\n }\n\n private resolveControllerOrHandler (\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string\n ): EventHandler {\n if (typeof handler === 'function' && (handler as any).prototype instanceof Controller) {\n return (ctx) => {\n const controller = new (handler as new (...args: any[]) => IController)(this.app)\n const action = (methodName || 'index') as keyof IController\n\n if (typeof controller[action] !== 'function') {\n throw new Error(`Method \"${String(action)}\" not found on controller ${handler.name}`)\n }\n\n return controller[action](ctx)\n }\n }\n\n return handler as EventHandler\n }\n\n\n get (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('get', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n post (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('post', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n put (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('put', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n delete (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('delete', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n /**\n * API Resource support \n * \n * @param path \n * @param controller \n */\n apiResource (\n path: string,\n Controller: new (app: Application) => IController,\n middleware: IMiddleware[] = []\n ) {\n path = path.replace(/\\//g, '/')\n\n const name = afterLast(path, '/')\n const basePath = `/${path}`.replace(/\\/+/g, '/')\n\n const controller = new Controller(this.app)\n\n this.addRoute('get', basePath, controller.index.bind(controller), `${name}.index`, middleware)\n this.addRoute('post', basePath, controller.store.bind(controller), `${name}.store`, middleware)\n this.addRoute('get', `${basePath}/:id`, controller.show.bind(controller), `${name}.show`, middleware)\n this.addRoute('put', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('patch', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('delete', `${basePath}/:id`, controller.destroy.bind(controller), `${name}.destroy`, middleware)\n }\n\n /**\n * Named route URL generator\n * \n * @param name \n * @param params \n * @returns \n */\n route (name: string, params: Record<string, string> = {}): string | undefined {\n const found = this.routes.find(r => r.name === name)\n if (!found) return undefined\n\n let url = found.path\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`:${key}`, value)\n }\n return url\n }\n\n /**\n * Grouping\n * \n * @param options \n * @param callback \n */\n group (options: { prefix?: string; middleware?: EventHandler[] }, callback: () => void) {\n const prevPrefix = this.groupPrefix\n const prevMiddleware = [...this.groupMiddleware]\n\n this.groupPrefix += options.prefix || ''\n this.groupMiddleware.push(...(options.middleware || []))\n\n callback()\n\n /**\n * Restore state after group\n */\n this.groupPrefix = prevPrefix\n this.groupMiddleware = prevMiddleware\n }\n\n middleware (path: string, handler: Middleware, opts?: MiddlewareOptions) {\n this.h3App.use(path, handler, opts)\n }\n}\n","import { readFile, stat } from 'node:fs/promises'\n\nimport { ServiceProvider } from '@h3ravel/core'\nimport { before } from '@h3ravel/support'\nimport { join } from 'node:path'\nimport { serveStatic } from 'h3'\nimport { statSync } from 'node:fs'\n\n/**\n * Handles public assets loading\n * \n * Auto-Registered\n */\nexport class AssetsServiceProvider extends ServiceProvider {\n public static priority = 996;\n\n register () {\n const app = this.app.make('router')\n const config = this.app.make('config')\n const fsconfig = config.get('filesystem')\n const publicPath = this.app.getPath('public')\n\n app.middleware(`/${fsconfig.public_mask}/**`, (event) => {\n return serveStatic(event, {\n indexNames: ['/index.html'],\n getContents: (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n return readFile(join(before(publicPath, newId), newId))\n },\n getMeta: async (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n const stats = await stat(join(before(publicPath, newId), newId)).catch(() => { })\n if (stats?.isFile()) {\n return {\n size: stats.size,\n mtime: stats.mtimeMs,\n }\n }\n },\n })\n })\n\n this.app.singleton('asset', () => {\n return (key: string, def = '') => {\n try {\n statSync(join(before(publicPath, key), key))\n } catch {\n key = def\n }\n\n return join(fsconfig.public_mask, key)\n }\n })\n }\n}\n","import { Router } from '../Route'\nimport { ServiceProvider } from '@h3ravel/core'\nimport path from 'node:path'\nimport { readdir } from 'node:fs/promises'\n\n/**\n * Handles routing registration\n * \n * Load route files (web.ts, api.ts).\n * Map controllers to routes.\n * Register route-related middleware.\n * \n * Auto-Registered\n */\nexport class RouteServiceProvider extends ServiceProvider {\n public static priority = 997;\n\n register () {\n this.app.singleton('router', () => {\n const h3App = this.app.make('http.app')\n return new Router(h3App, this.app)\n })\n }\n\n /**\n * Load routes from src/routes\n */\n async boot () {\n try {\n const routePath = this.app.getPath('routes')\n\n const files = await readdir(routePath)\n\n for (let i = 0; i < files.length; i++) {\n const routesModule = await import(path.join(routePath, files[i]))\n\n if (typeof routesModule.default === 'function') {\n const router = this.app.make('router')\n routesModule.default(router)\n }\n }\n } catch (e) {\n console.warn('No web routes found or failed to load:', e)\n }\n }\n}\n"],"mappings":"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","names":["Router","routes","groupPrefix","groupMiddleware","h3App","app","resolveHandler","handler","middleware","event","kernel","Kernel","request","Request","response","Response","handle","ctx","Promise","resolve","addRoute","method","path","name","fullPath","replace","push","resolveControllerOrHandler","methodName","prototype","Controller","controller","action","Error","String","get","post","put","delete","apiResource","afterLast","basePath","index","bind","store","show","update","destroy","route","params","found","find","r","undefined","url","key","value","Object","entries","group","options","callback","prevPrefix","prevMiddleware","prefix","opts","use","import_core","import_support","AssetsServiceProvider","ServiceProvider","priority","register","app","make","config","fsconfig","get","publicPath","getPath","middleware","public_mask","event","serveStatic","indexNames","getContents","id","newId","replace","readFile","join","before","getMeta","stats","stat","catch","isFile","size","mtime","mtimeMs","singleton","key","def","statSync","import_core","import_node_path","import_promises","RouteServiceProvider","ServiceProvider","priority","register","app","singleton","h3App","make","Router","boot","routePath","getPath","files","readdir","i","length","routesModule","path","join","default","router","e","console","warn"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/Route.ts","../src/Providers/AssetsServiceProvider.ts","../src/Providers/RouteServiceProvider.ts"],"sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from './Controller';\nexport * from './Route';\nexport * from './Providers/AssetsServiceProvider';\nexport * from './Providers/RouteServiceProvider';\n","import { H3Event, Middleware, MiddlewareOptions, type H3 } from 'h3'\nimport { Request, Response } from '@h3ravel/http'\nimport { Application, Controller, Kernel } from '@h3ravel/core'\nimport { afterLast } from '@h3ravel/support'\nimport { EventHandler, IController, IMiddleware } from '@h3ravel/shared'\n\ninterface RouteDefinition {\n method: string\n path: string\n name?: string\n handler: EventHandler\n}\n\nexport class Router {\n private routes: RouteDefinition[] = []\n private groupPrefix = ''\n private groupMiddleware: EventHandler[] = []\n\n constructor(protected h3App: H3, private app: Application) { }\n\n /**\n * Route Resolver\n * \n * @param handler \n * @param middleware \n * @returns \n */\n private resolveHandler (handler: EventHandler, middleware: IMiddleware[] = []) {\n return async (event: H3Event) => {\n const kernel = new Kernel(() => ({\n request: new Request(event),\n response: new Response(event)\n }), middleware)\n\n return kernel.handle(event, (ctx) => Promise.resolve(handler(ctx)))\n }\n }\n\n /**\n * Add a route to the stack\n * \n * @param method \n * @param path \n * @param handler \n * @param name \n * @param middleware \n */\n private addRoute (\n method: string,\n path: string,\n handler: EventHandler,\n name?: string,\n middleware: IMiddleware[] = []\n ) {\n const fullPath = `${this.groupPrefix}${path}`.replace(/\\/+/g, '/')\n this.routes.push({ method, path: fullPath, name, handler })\n this.h3App[method as 'get'](fullPath, this.resolveHandler(handler, middleware))\n }\n\n private resolveControllerOrHandler (\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string\n ): EventHandler {\n if (typeof handler === 'function' && (handler as any).prototype instanceof Controller) {\n return (ctx) => {\n const controller = new (handler as new (...args: any[]) => IController)(this.app)\n const action = (methodName || 'index') as keyof IController\n\n if (typeof controller[action] !== 'function') {\n throw new Error(`Method \"${String(action)}\" not found on controller ${handler.name}`)\n }\n\n return controller[action](ctx)\n }\n }\n\n return handler as EventHandler\n }\n\n\n get (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('get', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n post (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('post', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n put (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('put', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n delete (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('delete', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n /**\n * API Resource support \n * \n * @param path \n * @param controller \n */\n apiResource (\n path: string,\n Controller: new (app: Application) => IController,\n middleware: IMiddleware[] = []\n ) {\n path = path.replace(/\\//g, '/')\n\n const name = afterLast(path, '/')\n const basePath = `/${path}`.replace(/\\/+/g, '/')\n\n const controller = new Controller(this.app)\n\n this.addRoute('get', basePath, controller.index.bind(controller), `${name}.index`, middleware)\n this.addRoute('post', basePath, controller.store.bind(controller), `${name}.store`, middleware)\n this.addRoute('get', `${basePath}/:id`, controller.show.bind(controller), `${name}.show`, middleware)\n this.addRoute('put', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('patch', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('delete', `${basePath}/:id`, controller.destroy.bind(controller), `${name}.destroy`, middleware)\n }\n\n /**\n * Named route URL generator\n * \n * @param name \n * @param params \n * @returns \n */\n route (name: string, params: Record<string, string> = {}): string | undefined {\n const found = this.routes.find(r => r.name === name)\n if (!found) return undefined\n\n let url = found.path\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`:${key}`, value)\n }\n return url\n }\n\n /**\n * Grouping\n * \n * @param options \n * @param callback \n */\n group (options: { prefix?: string; middleware?: EventHandler[] }, callback: () => void) {\n const prevPrefix = this.groupPrefix\n const prevMiddleware = [...this.groupMiddleware]\n\n this.groupPrefix += options.prefix || ''\n this.groupMiddleware.push(...(options.middleware || []))\n\n callback()\n\n /**\n * Restore state after group\n */\n this.groupPrefix = prevPrefix\n this.groupMiddleware = prevMiddleware\n }\n\n middleware (path: string, handler: Middleware, opts?: MiddlewareOptions) {\n this.h3App.use(path, handler, opts)\n }\n}\n","import { readFile, stat } from 'node:fs/promises'\n\nimport { ServiceProvider } from '@h3ravel/core'\nimport { before } from '@h3ravel/support'\nimport { join } from 'node:path'\nimport { serveStatic } from 'h3'\nimport { statSync } from 'node:fs'\n\n/**\n * Handles public assets loading\n * \n * Auto-Registered\n */\nexport class AssetsServiceProvider extends ServiceProvider {\n public static priority = 996;\n\n register () {\n const app = this.app.make('router')\n const config = this.app.make('config')\n const fsconfig = config.get('filesystem')\n const publicPath = this.app.getPath('public')\n\n app.middleware(`/${fsconfig.public_mask}/**`, (event) => {\n return serveStatic(event, {\n indexNames: ['/index.html'],\n getContents: (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n return readFile(join(before(publicPath, newId), newId))\n },\n getMeta: async (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n const stats = await stat(join(before(publicPath, newId), newId)).catch(() => { })\n if (stats?.isFile()) {\n return {\n size: stats.size,\n mtime: stats.mtimeMs,\n }\n }\n },\n })\n })\n\n this.app.singleton('asset', () => {\n return (key: string, def = '') => {\n try {\n statSync(join(before(publicPath, key), key))\n } catch {\n key = def\n }\n\n return join(fsconfig.public_mask, key)\n }\n })\n }\n}\n","import { Router } from '../Route'\nimport { ServiceProvider } from '@h3ravel/core'\nimport path from 'node:path'\nimport { readdir } from 'node:fs/promises'\n\n/**\n * Handles routing registration\n * \n * Load route files (web.ts, api.ts).\n * Map controllers to routes.\n * Register route-related middleware.\n * \n * Auto-Registered\n */\nexport class RouteServiceProvider extends ServiceProvider {\n public static priority = 997;\n\n register () {\n this.app.singleton('router', () => {\n const h3App = this.app.make('http.app')\n return new Router(h3App, this.app)\n })\n }\n\n /**\n * Load routes from src/routes\n */\n async boot () {\n try {\n const routePath = this.app.getPath('routes')\n\n const files = await readdir(routePath)\n\n for (let i = 0; i < files.length; i++) {\n const routesModule = await import(path.join(routePath, files[i]))\n\n if (typeof routesModule.default === 'function') {\n const router = this.app.make('router')\n routesModule.default(router)\n }\n }\n } catch (e) {\n console.warn('No web routes found or failed to load:', e)\n }\n }\n}\n"],"mappings":"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","names":["Router","routes","groupPrefix","groupMiddleware","h3App","app","resolveHandler","handler","middleware","event","kernel","Kernel","request","Request","response","Response","handle","ctx","Promise","resolve","addRoute","method","path","name","fullPath","replace","push","resolveControllerOrHandler","methodName","prototype","Controller","controller","action","Error","String","get","post","put","delete","apiResource","afterLast","basePath","index","bind","store","show","update","destroy","route","params","found","find","r","undefined","url","key","value","Object","entries","group","options","callback","prevPrefix","prevMiddleware","prefix","opts","use","import_core","import_support","AssetsServiceProvider","ServiceProvider","priority","register","app","make","config","fsconfig","get","publicPath","getPath","middleware","public_mask","event","serveStatic","indexNames","getContents","id","newId","replace","readFile","join","before","getMeta","stats","stat","catch","isFile","size","mtime","mtimeMs","singleton","key","def","statSync","import_core","import_node_path","import_promises","RouteServiceProvider","ServiceProvider","priority","register","app","singleton","h3App","make","Router","boot","routePath","getPath","files","readdir","i","length","routesModule","path","join","default","router","e","console","warn"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h3ravel/router",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Route facade, decorators and controller system for H3ravel.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"h3": "^2.0.0-beta.1",
|
|
13
|
-
"@h3ravel/http": "4.0.
|
|
14
|
-
"@h3ravel/
|
|
15
|
-
"@h3ravel/
|
|
16
|
-
"@h3ravel/support": "0.6.
|
|
13
|
+
"@h3ravel/http": "4.0.1",
|
|
14
|
+
"@h3ravel/core": "1.0.1",
|
|
15
|
+
"@h3ravel/shared": "0.6.1",
|
|
16
|
+
"@h3ravel/support": "0.6.1"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
19
|
"barrel": "barrelsby --directory src --delete --singleQuotes",
|
package/src/index.ts
CHANGED
|
@@ -4,10 +4,5 @@
|
|
|
4
4
|
|
|
5
5
|
export * from './Controller';
|
|
6
6
|
export * from './Route';
|
|
7
|
-
export * from './Decorators/ApiResource';
|
|
8
|
-
export * from './Decorators/Controller';
|
|
9
|
-
export * from './Decorators/Get';
|
|
10
|
-
export * from './Decorators/Middleware';
|
|
11
|
-
export * from './Decorators/Post';
|
|
12
7
|
export * from './Providers/AssetsServiceProvider';
|
|
13
8
|
export * from './Providers/RouteServiceProvider';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default class { }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default class { }
|
package/src/Decorators/Get.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default class { }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default class { }
|
package/src/Decorators/Post.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default class { }
|