tadcode-wpsjs 0.1.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/.editorconfig ADDED
@@ -0,0 +1,16 @@
1
+ # EditorConfig is awesome: https://editorconfig.org
2
+
3
+ # top-most EditorConfig file
4
+ root = true
5
+
6
+ [*]
7
+ end_of_line = lf
8
+ insert_final_newline = true
9
+ charset = utf-8
10
+ indent_style = tab
11
+ tab_width = 2
12
+ trim_trailing_whitespace = true
13
+
14
+ [*.md]
15
+ indent_style = tab
16
+ trim_trailing_whitespace = false
@@ -0,0 +1,44 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ /* 需要插件Bun for Visual Studio Code id:oven.bun-vscode */
6
+ "type": "bun",
7
+ "request": "launch",
8
+ "name": "Debug Bun",
9
+ // The path to a JavaScript or TypeScript file to run.
10
+ "program": "${file}",
11
+ // The arguments to pass to the program, if any.
12
+ "args": [],
13
+ // The working directory of the program.
14
+ "cwd": "${workspaceFolder}",
15
+ // The environment variables to pass to the program.
16
+ "env": {},
17
+ // If the environment variables should not be inherited from the parent process.
18
+ "strictEnv": false,
19
+ // If the program should be run in watch mode.
20
+ // This is equivalent to passing `--watch` to the `bun` executable.
21
+ // You can also set this to "hot" to enable hot reloading using `--hot`.
22
+ "watchMode": true,
23
+ // If the debugger should stop on the first line of the program.
24
+ "stopOnEntry": false,
25
+ // If the debugger should be disabled. (for example, breakpoints will not be hit)
26
+ "noDebug": false,
27
+ // The path to the `bun` executable, defaults to your `PATH` environment variable.
28
+ "runtime": "bun",
29
+ // The arguments to pass to the `bun` executable, if any.
30
+ // Unlike `args`, these are passed to the executable itself, not the program.
31
+ "runtimeArgs": [
32
+ // "--hot"
33
+ ],
34
+ },
35
+ {
36
+ "type": "bun",
37
+ "request": "attach",
38
+ "name": "Attach to Bun",
39
+ // The URL of the WebSocket inspector to attach to.
40
+ // This value can be retrieved by using `bun --inspect`.
41
+ "url": "ws://localhost:6499/",
42
+ },
43
+ ]
44
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "files.autoSave": "off",
3
+ // The path to the `bun` executable.
4
+ // "bun.runtime": "/path/to/bun",
5
+ // If support for Bun should be added to the default "JavaScript Debug Terminal".
6
+ "bun.debugTerminal.enabled": true,
7
+ // If the debugger should stop on the first line of the program.
8
+ "bun.debugTerminal.stopOnEntry": false,
9
+ // Glob pattern to find test files. Defaults to the value shown below.
10
+ "bun.test.filePattern": "**/*{.test.,.spec.,_test_,_spec_}{js,ts,tsx,jsx,mts,cts}",
11
+ }
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # tadcode-wpsjs
2
+
3
+ ## 应用
4
+
5
+ 用于学习wpsjsapi,远程调用wpsjsapi。
6
+
7
+ 使用wpsjs-1.0api。支持异步任务。支持`KSDrive`的类型。
8
+
9
+ 在远程部署代码好代码,通过传输的调用信息进行调用api。原理是使用代理收集调用信息,之后让远程代码进行调用并且返回结果。
10
+
11
+ 远程代码在`remoteCode`目录的`index.js`文件里面。将其复制粘贴到对应`webhook`的脚本中才能支持`wpsjsGlobal`的调用。
12
+
13
+ ## 安装
14
+
15
+ `npm install tadcode-wpsjs` 或 `bun install tadcode-wpsjs`
16
+
17
+ ## 案例
18
+
19
+ ```ts
20
+ import { RemoteCallWpsjsGlobal } from 'tadcode-wpsjs'
21
+ const remoteCall = new RemoteCallWpsjsGlobal()
22
+ remoteCall.scriptToken = 'xxxx' /* 脚本令牌 */
23
+ remoteCall.webhookURL = 'xxxx' /* webhook url地址 */
24
+ const { wpsjsGlobal } = remoteCall
25
+ wpsjsGlobal.KSDrive.listFiles()/* 返回云文档下面的文件列表 */
26
+ const response = await remoteCall.execute()
27
+ console.log(await response.text())
28
+ ```
package/bun.lock ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "workspaces": {
4
+ "": {
5
+ "name": "tadcode-wpsjs",
6
+ "devDependencies": {
7
+ "@types/bun": "latest",
8
+ },
9
+ "peerDependencies": {
10
+ "typescript": "latest",
11
+ },
12
+ },
13
+ },
14
+ "packages": {
15
+ "@types/bun": ["@types/bun@1.2.8", "", { "dependencies": { "bun-types": "1.2.7" } }, "sha512-t8L1RvJVUghW5V+M/fL3Thbxcs0HwNsXsnTEBEfEVqGteiJToOlZ/fyOEaR1kZsNqnu+3XA4RI/qmnX4w6+S+w=="],
16
+
17
+ "@types/node": ["@types/node@22.13.14", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w=="],
18
+
19
+ "@types/ws": ["@types/ws@8.18.0", "", { "dependencies": { "@types/node": "*" } }, "sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw=="],
20
+
21
+ "bun-types": ["bun-types@1.2.7", "", { "dependencies": { "@types/node": "*", "@types/ws": "*" } }, "sha512-P4hHhk7kjF99acXqKvltyuMQ2kf/rzIw3ylEDpCxDS9Xa0X0Yp/gJu/vDCucmWpiur5qJ0lwB2bWzOXa2GlHqA=="],
22
+
23
+ "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="],
24
+
25
+ "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
26
+ }
27
+ }
package/index.js ADDED
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import K from"node:path";class N{sync=!0;scriptToken="";webhookURL="";asyncQueryURL="https://www.kdocs.cn/api/v3/script/task";info=[];wpsjsGlobal=new Proxy(()=>{},{get:(B,z)=>{let{info:q,wpsjsGlobal:v}=this;return q.push({method:"get",arguments:[z]}),v},apply:(B,z,q)=>{let{info:v,wpsjsGlobal:F}=this;return v.push({method:"apply",arguments:q}),F}});execute(){let{scriptToken:B,webhookURL:z,info:q,sync:v}=this,F=JSON.stringify({Context:{argv:{info:q}}}),E=K.parse(z);E.base=v?"sync_task":"task";let H=K.format(E);return fetch(H,{method:"post",headers:{"Content-Type":"application/json","AirScript-Token":B},body:F})}queryTask(B){let{asyncQueryURL:z}=this,q=new URL(z);return q.searchParams.append("task_id",B),fetch(q.toString())}}async function S(B){let z=await B.json(),{status:q,data:v,error:F,error_details:E}=z;console.log("result:"),console.log(v.result);let H=v.logs.filter((J)=>J.filename!=="<system>");if(H.length!==0){console.log("log:");for(let J of H)console[J.level](...J.args)}console.log("status:",q);let M=v.logs.at(-1).unix_time-v.logs[1].unix_time;if(console.log("runtime:",M),F)console.error(E.name),console.error(E.msg),console.error(E.stack);return z}export{S as printInfo,N as RemoteCallWpsjsGlobal};
package/index.ts ADDED
@@ -0,0 +1,74 @@
1
+ import type { InfoItem, RemoteCallWpsjsGlobalReturn, WpsjsGlobal } from './types'
2
+ import path from 'path'
3
+ export class RemoteCallWpsjsGlobal {
4
+ sync = true
5
+ scriptToken = ''
6
+ webhookURL = ''
7
+ asyncQueryURL = 'https://www.kdocs.cn/api/v3/script/task'
8
+ info: InfoItem[] = []
9
+ wpsjsGlobal = new Proxy(() => { }, {
10
+ get: (_target, p) => {
11
+ const { info, wpsjsGlobal } = this
12
+ info.push({
13
+ method: 'get',
14
+ arguments: [p]
15
+ })
16
+ return wpsjsGlobal
17
+ },
18
+ apply: (_target, _thisArg, argArray) => {
19
+ const { info, wpsjsGlobal } = this
20
+ info.push({
21
+ method: 'apply',
22
+ arguments: argArray
23
+ })
24
+ return wpsjsGlobal
25
+ },
26
+ }) as WpsjsGlobal
27
+ execute() {
28
+ const { scriptToken, webhookURL, info, sync } = this
29
+ const data = JSON.stringify({
30
+ 'Context': { 'argv': { info }, }
31
+ })
32
+ /* 根据是否同步返回不同的url */
33
+ const parsedPath = path.parse(webhookURL)
34
+ parsedPath.base = sync ? 'sync_task' : 'task'
35
+ const url = path.format(parsedPath)
36
+ return fetch(url, {
37
+ method: 'post',
38
+ headers: {
39
+ 'Content-Type': 'application/json',
40
+ 'AirScript-Token': scriptToken
41
+ },
42
+ body: data
43
+ })
44
+ }
45
+ queryTask(id: string) {
46
+ const { asyncQueryURL } = this
47
+ const url = new URL(asyncQueryURL)
48
+ /* 这样子可以不用 encodeURIComponent */
49
+ url.searchParams.append('task_id', id)
50
+ return fetch(url.toString())
51
+ }
52
+ }
53
+ export async function printInfo(response: Response) {
54
+ const responseData = await response.json() as RemoteCallWpsjsGlobalReturn
55
+ const { status, data, error, error_details } = responseData
56
+ console.log('result:')
57
+ console.log(data.result)
58
+ const userInfo = data.logs.filter(x => x.filename !== '<system>')
59
+ if (userInfo.length !== 0) {
60
+ console.log('log:')
61
+ for (const item of userInfo) {
62
+ console[item.level](...item.args)
63
+ }
64
+ }
65
+ console.log('status:', status)
66
+ const time = data.logs.at(-1)!.unix_time - data.logs[1].unix_time
67
+ console.log('runtime:', time)
68
+ if (error) {
69
+ console.error(error_details.name)
70
+ console.error(error_details.msg)
71
+ console.error(error_details.stack)
72
+ }
73
+ return responseData
74
+ }
package/package.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "tadcode-wpsjs",
3
+ "version": "0.1.0",
4
+ "main": "index.js",
5
+ "type": "module",
6
+ "scripts": {
7
+ "hot": "NODE_ENV=development bun --hot index.ts",
8
+ "dev": "NODE_ENV=development bun --watch index.ts",
9
+ "build": "NODE_ENV=production bun build index.ts --target bun --minify --outfile index.js"
10
+ },
11
+ "devDependencies": {
12
+ "@types/bun": "latest"
13
+ },
14
+ "keywords": [
15
+ "tadcode-wpsjs"
16
+ ]
17
+ }
@@ -0,0 +1,19 @@
1
+ /* version 0.1 */
2
+ const { info } = Context.argv
3
+ let peviousTemp = undefined
4
+ let current = globalThis
5
+ for (const item of info) {
6
+ switch (item.method) {
7
+ case 'get': {
8
+ peviousTemp = current
9
+ current = Reflect.get(current, item.arguments[0])
10
+ } break
11
+ case 'apply': {
12
+ current = Reflect.apply(current, peviousTemp, item.arguments)
13
+ } break
14
+ default:
15
+ throw Error('reflect method undefined')
16
+ break
17
+ }
18
+ }
19
+ return current
@@ -0,0 +1,14 @@
1
+ import type { RemoteCallWpsjsGlobalReturn } from '../types'
2
+ import { test, expect } from 'bun:test'
3
+ import { RemoteCallWpsjsGlobal } from '../index'
4
+
5
+ test('ok', async () => {
6
+ const remoteCall = new RemoteCallWpsjsGlobal()
7
+ remoteCall.webhookURL = 'xxxx' /* webhook url地址 */
8
+ remoteCall.webhookURL = 'xxxx' /* webhook url地址 */
9
+ const { wpsjsGlobal } = remoteCall
10
+ wpsjsGlobal.KSDrive.listFiles()
11
+ const response = await remoteCall.execute()
12
+ console.log(await response.text())
13
+ // const responseData = await printInfo(response)
14
+ })
package/tsconfig.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Enable latest features
4
+ "lib": [
5
+ "ESNext",
6
+ "DOM"
7
+ ],
8
+ "target": "ESNext",
9
+ "module": "ESNext",
10
+ "moduleDetection": "force",
11
+ "jsx": "react-jsx",
12
+ "allowJs": true,
13
+ // Bundler mode
14
+ "moduleResolution": "bundler",
15
+ "allowImportingTsExtensions": true,
16
+ "verbatimModuleSyntax": true,
17
+ "noEmit": true,
18
+ // Best practices
19
+ "strict": true,
20
+ "skipLibCheck": true,
21
+ "noFallthroughCasesInSwitch": true,
22
+ // Some stricter flags (disabled by default)
23
+ "noUnusedLocals": false,
24
+ "noUnusedParameters": false,
25
+ "noPropertyAccessFromIndexSignature": false
26
+ }
27
+ }
@@ -0,0 +1,120 @@
1
+ export default interface DB_Application {
2
+ Sheet: DBSheet
3
+ Record: DBRecord
4
+ Field: DBField
5
+ View: DBView
6
+ }
7
+ /* 表 */
8
+ interface DBSheet {
9
+ GetSheets(): SheetInfo
10
+ CreateSheet(options: Pick<SheetOptions, 'SheetId'>)
11
+ DeleteSheet(options: Pick<SheetOptions, 'SheetId'>)
12
+ UpdateSheet(options: Omit<SheetOptions, 'SheetId'> & Partial<SheetOptions>)
13
+ }
14
+ interface SheetOptions {
15
+ SheetId: number
16
+ Name: string
17
+ Views: {
18
+ name: string
19
+ /**
20
+ * 表格视图 看板视图 画册视图 表单视图 甘特视图
21
+ */
22
+ type: ViewType
23
+ }[]
24
+ Fields: { name: string, type: FieldType }[]
25
+ }
26
+ interface SheetInfo {
27
+ "description": string,
28
+ "fields": {
29
+ "arraySupport": boolean,
30
+ "autoFillSourceField": string,
31
+ "customConfig": string,
32
+ "defaultValueType": "Normal",
33
+ "description": string,
34
+ "id": string,
35
+ "name": string,
36
+ "numberFormat": string,
37
+ "syncField": boolean,
38
+ "type": FieldType,
39
+ "uniqueValue": boolean
40
+ "loadLegalHoliday": number,
41
+ "items": {
42
+ "color": number,
43
+ "id": string,
44
+ "value": string
45
+ }[],
46
+ "allowAddItemWhenInputting": true,
47
+ "autoAddItem": boolean,
48
+ }[],
49
+ "icon": string,
50
+ "id": number,
51
+ "name": number,
52
+ "primaryFieldId": number,
53
+ "recordsCount": number,
54
+ "sheetType": "xlEtDataBaseSheet",
55
+ "subType": "Normal",
56
+ "syncFieldSourceId": string,
57
+ "syncFieldSourceNameId": string,
58
+ "syncType": "None",
59
+ "views": {
60
+ "id": string,
61
+ "name": string,
62
+ "notice": string,
63
+ "recordsCount": number,
64
+ "type": ViewType
65
+ }[]
66
+ }
67
+
68
+ type FieldType = 'MultiLineText' | 'Date' | 'Time' | 'Number' | 'Currency' | 'Percentage' | 'ID' | 'Phone' | 'Email' | 'Url' | 'Checkbox' | 'SingleSelect' | 'MultipleSelect' | 'Rating' | 'Complete' | 'Contact' | 'Attachment' | 'Link' | 'Note' | 'AutoNumber' | 'CreatedBy' | 'CreatedTime' | 'Formula' | 'Lookup'
69
+ type ViewType = 'Grid' | 'Kanban' | 'Gallery' | 'Form' | 'Gantt'
70
+
71
+ /* 行记录 */
72
+ interface DBRecord {
73
+ GetRecords(options: Pick<RcordOptions, 'SheetId'>)
74
+ GetRecord(options: Pick<RcordOptions, 'SheetId' | 'RecordId'>)
75
+ DeleteRecords(options: Pick<RcordOptions, 'SheetId' | 'RecordIds'>)
76
+ UpdateRecords(options: Pick<RcordOptions, 'SheetId' | 'Records'>)
77
+ }
78
+ interface RcordOptions {
79
+ SheetId: number
80
+ RecordId: string
81
+ RecordIds: string[]
82
+ Records: {
83
+ id: string,
84
+ fields: Record<string, string | number | string[]>
85
+ }[]
86
+ }
87
+
88
+ /* 字段 */
89
+ interface DBField {
90
+ GetFields(options: Pick<FieldOptions, 'SheetId'>)
91
+ CreateFields(options: Pick<FieldOptions, 'SheetId' | 'Fields'>)
92
+ DeleteFields(options: Pick<FieldOptions, 'SheetId' | 'FieldIds'>)
93
+ UpdateFields(options: Pick<FieldOptions, 'SheetId' | 'Fields'> & {
94
+
95
+ })
96
+ }
97
+ interface FieldOptions {
98
+ SheetId: number
99
+ Fields: Partial<Field>[]
100
+ FieldIds: string[]
101
+ }
102
+ interface Field {
103
+ id: string,
104
+ name: string,
105
+ type: FieldType
106
+ }
107
+
108
+ /* 视图 */
109
+ interface DBView {
110
+ GetViews(options: Pick<ViewOptions, 'SheetId'>)
111
+ CreateView(options: Pick<ViewOptions, 'SheetId' | 'Name' | 'ViewType'>)
112
+ DeleteView(options: Pick<ViewOptions, 'SheetId' | 'ViewId'>)
113
+ UpdateView(options: Pick<ViewOptions, 'SheetId' | 'Name' | 'ViewId'>)
114
+ }
115
+ interface ViewOptions {
116
+ SheetId: number
117
+ ViewId: string
118
+ Name: string
119
+ ViewType: ViewType
120
+ }
@@ -0,0 +1,53 @@
1
+ import DB_Application from './DB_Application'
2
+ import KSheet_Application from './KSheet_Application'
3
+ export default interface KSDrive {
4
+ FileType: {
5
+ /**智能文档 */
6
+ AP: string
7
+ /**智能表格 */
8
+ KSheet: string
9
+ /**表格 */
10
+ ET: string
11
+ /**多维表 */
12
+ DB: string
13
+ }
14
+ /**
15
+ * 创建文件
16
+ * @param type 新文件的类型
17
+ * @param createOptions 新文件的参数选项
18
+
19
+ */
20
+ createFile(type: string, createOptions: createOptions)
21
+ openFile(url: string): {
22
+ Application: KSheet_Application & DB_Application
23
+ close()
24
+ }
25
+ listFiles(options?: {
26
+ dirUrl: string
27
+ offset: number
28
+ count: number
29
+ includeExts: string[]
30
+ })
31
+ }
32
+ interface CreateOptions {
33
+ /**是 新文件的文件名 */
34
+ name: string
35
+ /**否 新文件的文件目录 */
36
+ dirUrl: string
37
+ /**否 将目标文件另存为新文件 */
38
+ source: string
39
+ }
40
+ interface FilesInfo {
41
+ files: FileInfo[]
42
+ nextOffset: number
43
+ }
44
+ interface FileInfo {
45
+ /** 文件名 */
46
+ fileName: string
47
+ /** 加密后的文件 id */
48
+ fileId: string
49
+ /** 文件创建时间戳 */
50
+ createTime: number
51
+ /** 文件修改时间戳 */
52
+ updateTime: number
53
+ }
@@ -0,0 +1,25 @@
1
+ export interface KSheet_Application {
2
+ Sheets: {
3
+ Item(index: number | string): Sheet
4
+ }
5
+ Range(index: string): {
6
+ Value: any
7
+ }
8
+ }
9
+ interface Sheet {
10
+ /**
11
+ * 获取一个单元格或单元格区域,返回一个 Range 对象
12
+ * @paramaddress — 地址,可以是单元格地址或者选区范围范围地址
13
+ * @returns — 工作表里的一个单元格或单元格区域
14
+ * @example — 参考示例
15
+ * const sheet = Application.ActiveSheet
16
+ * // 打印当前活动工作表D2单元格的内容
17
+ * console.log(sheet.Range('D2').Text) // D2
18
+ * // 修改当前活动工作表D2单元格的内容
19
+ * sheet.Range('D2').Value = 'this is D2'
20
+ */
21
+ Range(address: string): Range
22
+ }
23
+ interface Range {
24
+ Value2: any
25
+ }
@@ -0,0 +1,81 @@
1
+ import KSDrive from './KSDrive'
2
+ interface WpsjsGlobal {
3
+ (): WpsjsGlobal
4
+ Date: typeof Date
5
+ KSDrive: KSDrive
6
+ }
7
+ interface InfoItem {
8
+ method: keyof typeof Reflect
9
+ arguments: (string | symbol)[]
10
+ }
11
+ interface RemoteCallWpsjsGlobalReturn {
12
+ "data": {
13
+ "logs": [
14
+ {
15
+ "filename": "<system>",
16
+ "timestamp": string,
17
+ "unix_time": number,
18
+ "level": "info",
19
+ "args": [
20
+ "脚本环境(2.0)初始化..."
21
+ ]
22
+ },
23
+ {
24
+ "filename": "<system>",
25
+ "timestamp": string,
26
+ "unix_time": number,
27
+ "level": "info",
28
+ "args": [
29
+ "已开始执行"
30
+ ]
31
+ },
32
+ {
33
+ "filename": "xxxx.js:row:column",
34
+ "timestamp": string,
35
+ "unix_time": number,
36
+ "level": "error",
37
+ "args": []
38
+ },
39
+ {
40
+ "filename": "xxxx.js:row:column",
41
+ "timestamp": string,
42
+ "unix_time": number,
43
+ "level": "warn",
44
+ "args": []
45
+ },
46
+ {
47
+ "filename": "xxxx.js:row:column",
48
+ "timestamp": string,
49
+ "unix_time": number,
50
+ "level": "info",
51
+ "args": []
52
+ },
53
+ {
54
+ "filename": "<system>",
55
+ "timestamp": string,
56
+ "unix_time": number,
57
+ "level": "info",
58
+ "args": [
59
+ "执行完毕"
60
+ ]
61
+ }
62
+ ],
63
+ "result": unknown,
64
+ "task_id": string,
65
+ },
66
+ "error": string,
67
+ "error_details": {
68
+ "name": string,
69
+ "msg": string,
70
+ "stack": string[],
71
+ "unix_time": number,
72
+ },
73
+ "status": "finished",
74
+ "task_id": "GN/KU3B3BG84MdCjraN5mukx0Rt5Sp1eJ9k2qClmcaOkkF3PUVNDOYPY7Kz4aQMXSvXn9N08QabldRKjPfzii87fuGYydIuK2la2HMfcxmGK1Pf4WcPEflb5xOOkQQEo8fmEbzcobhurYg==",
75
+ "task_type": "open_air_script",
76
+ }
77
+ export {
78
+ WpsjsGlobal,
79
+ InfoItem,
80
+ RemoteCallWpsjsGlobalReturn,
81
+ }