cliframe 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/cli.mjs +2 -0
- package/dist/main.cjs +4 -0
- package/dist/main.d.cts +4 -0
- package/dist/main.d.cts.map +1 -0
- package/dist/main.d.mts +5 -0
- package/dist/main.d.mts.map +1 -0
- package/dist/main.mjs +5 -0
- package/dist/main.mjs.map +1 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# CLIFrame
|
|
2
|
+
|
|
3
|
+
A simple CLI framework for building command-line applications in Node.js.
|
|
4
|
+
|
|
5
|
+
## GETTING STARTED
|
|
6
|
+
|
|
7
|
+
1. **<u>Step-1</u>**: Run `npx cliframe init` to generate `cliframe.config.json`, `index.ts` files and a `CLI` folder all in your project folder.
|
|
8
|
+
2. **<u>Step-2</u>**: set `bin` in `package.json`.
|
|
9
|
+
3.
|
|
10
|
+
|
|
11
|
+
## FILE SYSTEM CONVENTIONS
|
|
12
|
+
|
|
13
|
+
### `command.ts`
|
|
14
|
+
|
|
15
|
+
It should export default a method. The method always get access to the `props` property, which is passed when it's called.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
type Props = {
|
|
19
|
+
argument: Record<string, string>;
|
|
20
|
+
option: Record<string, boolean>;
|
|
21
|
+
values: (string | number)[];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const command = (props: Props) => {
|
|
25
|
+
console.log({
|
|
26
|
+
msg: "command.ts|js runs successfully",
|
|
27
|
+
path: import.meta.filename,
|
|
28
|
+
props,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default command;
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Internals of CLIFrame.js
|
|
36
|
+
|
|
37
|
+
Example: when you run `mycli start`, it will call the `default export fn` of `@/CLI/start/command.js|ts`
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import e from"node:fs/promises";import t from"node:fs";import n from"node:path";import r from"node:process";const i=async(t,n)=>{try{let r=await e.stat(a(n,t));return r?r.isDirectory():!1}catch{return!1}},a=(...e)=>n.join(...e),o=(e,n,r)=>{t.writeFileSync(a(n,e),r)},s=async(e,n)=>{await i(e,n)&&t.rmSync(a(n,e),{recursive:!0}),t.mkdirSync(e,{recursive:!0})},c={};c.comment=`This file is auto-generated by CLIFrame using 'npx cliframe init'.`,c.projectPath=r.cwd(),c.cliDirName=`CLI`,c.cliDirPath=a(c.projectPath,c.cliDirName);const l=(e=c,t=`cliframe.config.json`,n=c.projectPath)=>(o(t,n,JSON.stringify(e,null,2)),e),u=async()=>{let e=l();s(e.cliDirName,e.projectPath)};(async()=>{if(r.argv[2]===`init`){await u();return}})();export{};
|
package/dist/main.cjs
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`node:fs/promises`);c=s(c,1);let l=require(`node:path`);l=s(l,1);let u=require(`node:url`),d=require(`node:process`);d=s(d,1);const f=async(e,t)=>{try{let n=await c.default.stat(h(t,e));return n?n.isDirectory():!1}catch{return!1}},p=async(e,t)=>{try{let n=await c.default.stat(h(t,e));return n?n.isFile():!1}catch{return!1}},m=()=>(d.default.env.NODE_ENV??`development`)===`production`?`.js`:`.ts`,h=(...e)=>l.default.join(...e),g=e=>(0,u.pathToFileURL)(e).href;async function _(e){try{return[null,await e()]}catch(e){return[e,null]}}const v=async e=>await p(`command${m()}`,e),y=async e=>{let{default:t}=await import(g(h(e,`command${m()}`)));return t};var b=class extends Error{constructor(e){super(e),this.name=`CliError`}};const x=`cliframe.config.json`,S={};S.comment=`This file is auto-generated by CLIFrame using 'npx cliframe init'.`,S.projectPath=d.default.cwd(),S.cliDirName=`CLI`,S.cliDirPath=h(S.projectPath,S.cliDirName);const C=async()=>{let[e,t]=await _(async()=>(await import(g(h(S.projectPath,x)),{with:{type:`json`}})).default);if(e)throw new b(`Error loading configuration file.
|
|
2
|
+
Make sure "${x}" is present in the root directory and is a valid JSON file.
|
|
3
|
+
Run "npx cliframe init" to generate the config file.`);return t},w=()=>d.default.argv.slice(2),T=e=>e.startsWith(`cmd_`)?{type:`COMMAND`,entry:e,cleanEntry:E(e)}:e.startsWith(`arg_`)?{type:`ARGUMENT`,entry:e,cleanEntry:E(e)}:e.startsWith(`opt_`)?{type:`OPTION`,entry:e,cleanEntry:E(e)}:{type:`VALUE`,entry:e,cleanEntry:e},E=e=>e.slice(4),D=(e,t=`=`)=>{let n=e.indexOf(t);return[e.slice(0,n),e.slice(n+1)]},O=(e,t)=>{let n=t,{type:r,cleanEntry:i}=e;if(r===`ARGUMENT`){let[e,t]=D(i);n.arguments[e]=t}return r===`OPTION`&&(n.options[i]=!n.options[i]),r===`VALUE`&&n.values.push(i),n},k=async(e,t)=>{if(await v(e)){(await y(e))(t);return}else throw new b(`No "command${m()}" file present in "${e}"`)};async function A(){let e=(await C()).cliDirPath,t={arguments:{},options:{},values:[]},n=w(),r=!0;if(n.length===0){k(e,t);return}for(let i=0;i<n.length;i++){let a=T(n[i]).type===`COMMAND`,{type:o,cleanEntry:s}=T(n[i]);if(a){if(!r)throw new b(`Sub command must come immediately after a command. "${s}" is treated as a sub command here.`);if(await f(s,e))e=h(e,s);else throw new b(`No such directory found in → "${e}"
|
|
4
|
+
Entry is a command, but no such command folder is present.`)}else{if(i===0)throw new b(`Invalid command. No such command present. Very first entry must be a command.`);t=O({type:o,cleanEntry:s},t),r=!1}}k(e,t)}function j(){A()}module.exports=j;
|
package/dist/main.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";iBAEwB,QAAA,CAAA;AAAA"}
|
package/dist/main.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";iBAEwB,QAAA,CAAA"}
|
package/dist/main.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import e from"node:fs/promises";import t from"node:path";import{pathToFileURL as n}from"node:url";import r from"node:process";const i=async(t,n)=>{try{let r=await e.stat(s(n,t));return r?r.isDirectory():!1}catch{return!1}},a=async(t,n)=>{try{let r=await e.stat(s(n,t));return r?r.isFile():!1}catch{return!1}},o=()=>(r.env.NODE_ENV??`development`)===`production`?`.js`:`.ts`,s=(...e)=>t.join(...e),c=e=>n(e).href;async function l(e){try{return[null,await e()]}catch(e){return[e,null]}}const u=async e=>await a(`command${o()}`,e),d=async e=>{let{default:t}=await import(c(s(e,`command${o()}`)));return t};var f=class extends Error{constructor(e){super(e),this.name=`CliError`}};const p=`cliframe.config.json`,m={};m.comment=`This file is auto-generated by CLIFrame using 'npx cliframe init'.`,m.projectPath=r.cwd(),m.cliDirName=`CLI`,m.cliDirPath=s(m.projectPath,m.cliDirName);const h=async()=>{let[e,t]=await l(async()=>(await import(c(s(m.projectPath,p)),{with:{type:`json`}})).default);if(e)throw new f(`Error loading configuration file.
|
|
2
|
+
Make sure "${p}" is present in the root directory and is a valid JSON file.
|
|
3
|
+
Run "npx cliframe init" to generate the config file.`);return t},g=()=>r.argv.slice(2),_=e=>e.startsWith(`cmd_`)?{type:`COMMAND`,entry:e,cleanEntry:v(e)}:e.startsWith(`arg_`)?{type:`ARGUMENT`,entry:e,cleanEntry:v(e)}:e.startsWith(`opt_`)?{type:`OPTION`,entry:e,cleanEntry:v(e)}:{type:`VALUE`,entry:e,cleanEntry:e},v=e=>e.slice(4),y=(e,t=`=`)=>{let n=e.indexOf(t);return[e.slice(0,n),e.slice(n+1)]},b=(e,t)=>{let n=t,{type:r,cleanEntry:i}=e;if(r===`ARGUMENT`){let[e,t]=y(i);n.arguments[e]=t}return r===`OPTION`&&(n.options[i]=!n.options[i]),r===`VALUE`&&n.values.push(i),n},x=async(e,t)=>{if(await u(e)){(await d(e))(t);return}else throw new f(`No "command${o()}" file present in "${e}"`)};async function S(){let e=(await h()).cliDirPath,t={arguments:{},options:{},values:[]},n=g(),r=!0;if(n.length===0){x(e,t);return}for(let a=0;a<n.length;a++){let o=_(n[a]).type===`COMMAND`,{type:c,cleanEntry:l}=_(n[a]);if(o){if(!r)throw new f(`Sub command must come immediately after a command. "${l}" is treated as a sub command here.`);if(await i(l,e))e=s(e,l);else throw new f(`No such directory found in → "${e}"
|
|
4
|
+
Entry is a command, but no such command folder is present.`)}else{if(a===0)throw new f(`Invalid command. No such command present. Very first entry must be a command.`);t=b({type:c,cleanEntry:l},t),r=!1}}x(e,t)}function C(){S()}export{C as default};
|
|
5
|
+
//# sourceMappingURL=main.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.mjs","names":[],"sources":["../src/utils.ts","../src/core/command-related.ts","../src/class.ts","../src/core/configuration-related.ts","../src/core/entry-related.ts","../src/index.ts"],"sourcesContent":["import fsPromises from \"node:fs/promises\";\r\nimport fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { pathToFileURL } from \"node:url\";\r\nimport process from \"node:process\";\r\n\r\nexport const dirExists = async (\r\n dirName: string,\r\n path: string,\r\n): Promise<boolean> => {\r\n try {\r\n const result = await fsPromises.stat(\r\n generatePathFromSegments(path, dirName),\r\n );\r\n if (!result) {\r\n return false;\r\n }\r\n return result.isDirectory();\r\n } catch (error) {\r\n return false;\r\n }\r\n};\r\n\r\nexport const fileExists = async (\r\n fileName: string,\r\n dirPath: string,\r\n): Promise<boolean> => {\r\n try {\r\n const result = await fsPromises.stat(\r\n generatePathFromSegments(dirPath, fileName),\r\n );\r\n if (!result) {\r\n return false;\r\n }\r\n return result.isFile();\r\n } catch (error) {\r\n return false;\r\n }\r\n};\r\n\r\nexport const getJsTsExtension = () => {\r\n const env = process.env.NODE_ENV ?? \"development\";\r\n return env === \"production\" ? \".js\" : \".ts\";\r\n};\r\n\r\nexport const generatePathFromSegments = (...segments: string[]): string => {\r\n return path.join(...segments);\r\n};\r\n\r\nexport const convertToFileURL = (filePath: string) => {\r\n return pathToFileURL(filePath).href;\r\n};\r\n\r\nexport const createNewFileSync = (\r\n fileName: string,\r\n path: string,\r\n data: string,\r\n) => {\r\n fs.writeFileSync(generatePathFromSegments(path, fileName), data);\r\n};\r\n\r\nexport const createNewDirSync = async (dirName: string, path: string) => {\r\n if (await dirExists(dirName, path)) {\r\n fs.rmSync(generatePathFromSegments(path, dirName), { recursive: true });\r\n }\r\n fs.mkdirSync(dirName, { recursive: true });\r\n};\r\n\r\nexport async function safeAsync<T, E = Error>(\r\n fn: () => Promise<T>,\r\n): Promise<[null, T] | [E, null]> {\r\n try {\r\n return [null, await fn()];\r\n } catch (error) {\r\n return [error as E, null];\r\n }\r\n}\r\n","import {\r\n fileExists,\r\n getJsTsExtension,\r\n convertToFileURL,\r\n generatePathFromSegments,\r\n} from \"../utils.js\";\r\n\r\n\r\nexport type Passable = {\r\n arguments: Record<string, string | number>;\r\n options: Record<string, boolean>;\r\n values: (string | number)[];\r\n};\r\n\r\nexport const commandFileExists = async (path: string): Promise<boolean> => {\r\n return await fileExists(`command${getJsTsExtension()}`, path);\r\n};\r\n\r\nexport const getCommandFn = async (dirPath: string) => {\r\n const fileURL = convertToFileURL(\r\n generatePathFromSegments(dirPath, `command${getJsTsExtension()}`),\r\n );\r\n\r\n const { default: commandFn }: { default: (passable: Passable) => void } =\r\n await import(fileURL);\r\n \r\n return commandFn;\r\n};\r\n\r\n","// CLIFrame uses the prefix 'Cli' for all its class names.\r\n\r\nexport class CliError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = \"CliError\";\r\n }\r\n}\r\n","// generate the configuration file (cliframe.config.json) & CLI directory in the root directory.\r\n\r\nimport { CliError } from \"../class.js\";\r\nimport {\r\n convertToFileURL,\r\n createNewFileSync,\r\n generatePathFromSegments,\r\n safeAsync,\r\n} from \"../utils.js\";\r\nimport process from \"node:process\";\r\n\r\ntype Configs = {\r\n comment: string;\r\n projectPath: string;\r\n cliDirName: string;\r\n cliDirPath: string;\r\n};\r\n\r\nconst configFileName = \"cliframe.config.json\";\r\nconst configurations: Configs = {} as Configs;\r\n\r\nconst c = configurations;\r\nc.comment =\r\n \"This file is auto-generated by CLIFrame using 'npx cliframe init'.\";\r\nc.projectPath = process.cwd();\r\nc.cliDirName = \"CLI\";\r\nc.cliDirPath = generatePathFromSegments(c.projectPath, c.cliDirName);\r\n\r\nexport const generateConfigFileSync = (\r\n configs = c,\r\n fileName: string = configFileName,\r\n path: string = c.projectPath,\r\n) => {\r\n createNewFileSync(fileName, path, JSON.stringify(configs, null, 2));\r\n return configs;\r\n};\r\n\r\nexport const loadConfigFromFile = async () => {\r\n const [error, data] = await safeAsync(async () => {\r\n return (\r\n await import(\r\n convertToFileURL(\r\n generatePathFromSegments(c.projectPath, configFileName),\r\n ),\r\n {\r\n with: { type: \"json\" },\r\n }\r\n )\r\n ).default as typeof configurations;\r\n });\r\n\r\n if (error) {\r\n throw new CliError(\r\n `Error loading configuration file. \r\n Make sure \"${configFileName}\" is present in the root directory and is a valid JSON file.\r\n Run \"npx cliframe init\" to generate the config file.`,\r\n );\r\n }\r\n return data;\r\n};\r\n","import {\r\n commandFileExists,\r\n getCommandFn,\r\n type Passable,\r\n} from \"./command-related.js\";\r\nimport {\r\n dirExists,\r\n generatePathFromSegments,\r\n getJsTsExtension,\r\n} from \"../utils.js\";\r\nimport { CliError } from \"../class.js\";\r\nimport { loadConfigFromFile } from \"./configuration-related.js\";\r\nimport process from \"node:process\";\r\n\r\nconst getEntries = () => {\r\n return process.argv.slice(2);\r\n};\r\n\r\nconst getEntryInfo = (\r\n entry: string,\r\n): {\r\n type: \"COMMAND\" | \"ARGUMENT\" | \"OPTION\" | \"VALUE\";\r\n entry: string;\r\n cleanEntry: string;\r\n} => {\r\n if (entry.startsWith(\"cmd_\")) {\r\n return {\r\n type: \"COMMAND\",\r\n entry,\r\n cleanEntry: removeEntryPrifix(entry),\r\n };\r\n }\r\n if (entry.startsWith(\"arg_\")) {\r\n return {\r\n type: \"ARGUMENT\",\r\n entry,\r\n cleanEntry: removeEntryPrifix(entry),\r\n };\r\n }\r\n if (entry.startsWith(\"opt_\")) {\r\n return {\r\n type: \"OPTION\",\r\n entry,\r\n cleanEntry: removeEntryPrifix(entry),\r\n };\r\n }\r\n return {\r\n type: \"VALUE\",\r\n entry,\r\n cleanEntry: entry,\r\n };\r\n};\r\n\r\nconst removeEntryPrifix = (entry: string) => {\r\n return entry.slice(4);\r\n};\r\n\r\nconst toKeyValuePair = (\r\n cleanEntry: string,\r\n separator: \"=\" = \"=\",\r\n): [key: string, val: string] => {\r\n const indexOfSeparator = cleanEntry.indexOf(separator);\r\n const key = cleanEntry.slice(0, indexOfSeparator);\r\n const value = cleanEntry.slice(indexOfSeparator + 1);\r\n return [key, value];\r\n};\r\n\r\nconst setNewPassable = (\r\n entryInfo: Omit<ReturnType<typeof getEntryInfo>, \"entry\">,\r\n currentPassable: Passable,\r\n) => {\r\n let newPassable = currentPassable;\r\n const { type, cleanEntry } = entryInfo;\r\n if (type === \"ARGUMENT\") {\r\n const [key, value] = toKeyValuePair(cleanEntry);\r\n newPassable.arguments[key] = value;\r\n }\r\n if (type === \"OPTION\") {\r\n newPassable.options[cleanEntry] = !newPassable.options[cleanEntry];\r\n }\r\n if (type === \"VALUE\") {\r\n newPassable.values.push(cleanEntry);\r\n }\r\n\r\n return newPassable;\r\n};\r\n\r\nconst handleEmptyEntry = async (currentPath: string, passable: Passable) => {\r\n if (await commandFileExists(currentPath)) {\r\n const commandFn = await getCommandFn(currentPath);\r\n commandFn(passable);\r\n return;\r\n } else {\r\n throw new CliError(\r\n `No \"command${getJsTsExtension()}\" file present in \"${currentPath}\"`,\r\n );\r\n }\r\n};\r\n\r\nexport default async function processEntries() {\r\n const cliFrameConfig = await loadConfigFromFile();\r\n let currentPath = cliFrameConfig.cliDirPath;\r\n let passable: Passable = { arguments: {}, options: {}, values: [] };\r\n const entry = getEntries();\r\n let isCommandAllowed = true;\r\n\r\n if (entry.length === 0) {\r\n handleEmptyEntry(currentPath, passable);\r\n return;\r\n }\r\n\r\n for (let i = 0; i < entry.length; i++) {\r\n const isCommand = getEntryInfo(entry[i]!).type === \"COMMAND\" ? true : false;\r\n const { type, cleanEntry } = getEntryInfo(entry[i]!);\r\n\r\n if (!isCommand) {\r\n if (i === 0) {\r\n throw new CliError(\r\n \"Invalid command. No such command present. Very first entry must be a command.\",\r\n );\r\n }\r\n passable = setNewPassable({ type, cleanEntry }, passable);\r\n isCommandAllowed = false;\r\n } else {\r\n if (!isCommandAllowed) {\r\n throw new CliError(\r\n `Sub command must come immediately after a command. \"${cleanEntry}\" is treated as a sub command here.`,\r\n );\r\n }\r\n\r\n if (await dirExists(cleanEntry, currentPath)) {\r\n currentPath = generatePathFromSegments(currentPath, cleanEntry);\r\n } else {\r\n throw new CliError(`No such directory found in → \"${currentPath}\" \r\n Entry is a command, but no such command folder is present.`);\r\n }\r\n }\r\n }\r\n\r\n handleEmptyEntry(currentPath, passable);\r\n return;\r\n}\r\n\r\n// nothing ✔️\r\n// cmd_a ✔️\r\n// cmd_a arg_a=1 ✔️\r\n// cmd_a opt_a ✔️\r\n// cmd_a value-a ✔️\r\n// cmd_a arg_a=1 opt_a value-a ✔️\r\n// cmd_a cmd_b cmd_c cmd_d arg_a=1 opt_a value-a ✔️\r\n\r\n// cmd_a arg_a=1 cmd_b cmd_c opt_a value-a ✔️\r\n// arg_a=1 cmd_a opt_a value-a ✔️\r\n","import processEntries from \"./core/entry-related.js\";\r\n\r\nexport default function cliFrame() {\r\n processEntries();\r\n}\r\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cliframe",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"cliframe": "dist/cli.mjs"
|
|
7
|
+
},
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/main.d.mts",
|
|
12
|
+
"default": "./dist/main.mjs"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/main.d.cts",
|
|
16
|
+
"default": "./dist/main.cjs"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"description": "A simple CLI framework for building command-line applications in Node.js.",
|
|
21
|
+
"keywords": [
|
|
22
|
+
"clitool",
|
|
23
|
+
"cli",
|
|
24
|
+
"toolkit",
|
|
25
|
+
"framework"
|
|
26
|
+
],
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/manojpatra061/cliframe.git"
|
|
30
|
+
},
|
|
31
|
+
"author": "Manoj Patra",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "npm run build:main && npm run build:bin",
|
|
35
|
+
"build:main": "tsdown --config ./tsdown.config.main.ts",
|
|
36
|
+
"build:bin": "tsdown --config ./tsdown.config.cli.ts"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^25.6.0",
|
|
40
|
+
"tsdown": "^0.21.10",
|
|
41
|
+
"tsx": "^4.21.0",
|
|
42
|
+
"typescript": "^6.0.2"
|
|
43
|
+
}
|
|
44
|
+
}
|