pinokiod 3.9.0 → 3.9.3

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 (119) hide show
  1. package/:w +1247 -0
  2. package/kernel/api/filepicker/index.js +59 -0
  3. package/kernel/api/fs/index.js +6 -4
  4. package/kernel/api/index.js +123 -37
  5. package/kernel/api/input/index.js +2 -0
  6. package/kernel/api/web/index.js +6 -0
  7. package/kernel/bin/caddy.js +127 -0
  8. package/kernel/bin/cloudflared.js +1 -0
  9. package/kernel/bin/conda.js +10 -2
  10. package/kernel/bin/cuda.js +0 -16
  11. package/kernel/bin/ffmpeg.js +4 -6
  12. package/kernel/bin/git.js +55 -29
  13. package/kernel/bin/gxx.js +8 -6
  14. package/kernel/bin/huggingface.js +4 -5
  15. package/kernel/bin/index.js +347 -88
  16. package/kernel/bin/node.js +13 -6
  17. package/kernel/bin/py.js +1 -1
  18. package/kernel/bin/setup.js +146 -0
  19. package/kernel/bin/uv.js +4 -5
  20. package/kernel/bin/zip.js +7 -8
  21. package/kernel/connect/index.js +25 -0
  22. package/kernel/connect/providers/github/README.md +11 -0
  23. package/kernel/connect/providers/x/README.md +96 -0
  24. package/kernel/connect/providers/x/index.js +152 -0
  25. package/kernel/environment.js +50 -1
  26. package/kernel/index.js +152 -32
  27. package/kernel/info.js +4 -2
  28. package/kernel/kv.js +38 -0
  29. package/kernel/loader.js +13 -3
  30. package/kernel/peer.js +161 -0
  31. package/kernel/procs.js +116 -0
  32. package/kernel/prototype.js +62 -0
  33. package/kernel/router/common.js +42 -0
  34. package/kernel/router/connector.js +81 -0
  35. package/kernel/router/index.js +235 -0
  36. package/kernel/router/localhost_home_router.js +84 -0
  37. package/kernel/router/localhost_port_router.js +15 -0
  38. package/kernel/router/localhost_variable_router.js +37 -0
  39. package/kernel/router/peer_home_router.js +15 -0
  40. package/kernel/router/peer_peer_router.js +26 -0
  41. package/kernel/router/peer_port_router.js +45 -0
  42. package/kernel/router/peer_variable_router.js +46 -0
  43. package/kernel/router/processor.js +31 -0
  44. package/kernel/shell.js +141 -60
  45. package/kernel/shells.js +32 -17
  46. package/kernel/store.js +58 -0
  47. package/kernel/sysinfo.js +0 -1
  48. package/kernel/util.js +143 -36
  49. package/package.json +4 -1
  50. package/pipe/index.js +0 -2
  51. package/script/index.js +12 -0
  52. package/server/index.js +1473 -553
  53. package/server/public/Socket.js +5 -1
  54. package/server/public/SourceCodePro-Regular.ttf +0 -0
  55. package/server/public/SpaceMono-Bold.ttf +0 -0
  56. package/server/public/SpaceMono-BoldItalic.ttf +0 -0
  57. package/server/public/SpaceMono-Italic.ttf +0 -0
  58. package/server/public/SpaceMono-Regular.ttf +0 -0
  59. package/server/public/commander.js +40 -0
  60. package/server/public/common.js +60 -0
  61. package/server/public/dropzone-min.js +2 -0
  62. package/server/public/dropzone.css +1 -0
  63. package/server/public/filepond-plugin-file-validate-type.min.js +9 -0
  64. package/server/public/filepond-plugin-image-crop.min.js +9 -0
  65. package/server/public/filepond-plugin-image-edit.min.css +8 -0
  66. package/server/public/filepond-plugin-image-edit.min.js +9 -0
  67. package/server/public/filepond-plugin-image-exif-orientation.min.js +9 -0
  68. package/server/public/filepond-plugin-image-preview.min.css +8 -0
  69. package/server/public/filepond-plugin-image-preview.min.js +9 -0
  70. package/server/public/filepond-plugin-image-resize.min.js +9 -0
  71. package/server/public/filepond-plugin-image-transform.min.js +9 -0
  72. package/server/public/filepond.min.css +8 -0
  73. package/server/public/filepond.min.js +9 -0
  74. package/server/public/fscreator.js +174 -0
  75. package/server/public/fseditor.js +212 -0
  76. package/server/public/github.png +0 -0
  77. package/server/public/highlight-js.js +81 -0
  78. package/server/public/highlight.css +9 -0
  79. package/server/public/highlight.js +1244 -0
  80. package/server/public/install.js +17 -20
  81. package/server/public/modalinput.js +105 -9
  82. package/server/public/opener.js +3 -1
  83. package/server/public/pinokio-black.png +0 -0
  84. package/server/public/pinokio-black2.png +0 -0
  85. package/server/public/redoc.standalone.js +1832 -0
  86. package/server/public/style.css +215 -17
  87. package/server/public/swagger-ui-bundle.js +2 -0
  88. package/server/public/swagger-ui.css +3 -0
  89. package/server/public/x.js +63 -0
  90. package/server/socket.js +136 -39
  91. package/server/views/404.ejs +0 -1
  92. package/server/views/app.ejs +368 -98
  93. package/server/views/bootstrap.ejs +22 -19
  94. package/server/views/connect/x.ejs +324 -0
  95. package/server/views/connect.ejs +197 -0
  96. package/server/views/download.ejs +7 -1
  97. package/server/views/editor.ejs +68 -9
  98. package/server/views/explore.ejs +13 -10
  99. package/server/views/file_explorer.ejs +10 -37
  100. package/server/views/github.ejs +218 -0
  101. package/server/views/help.ejs +4 -3
  102. package/server/views/index.ejs +275 -121
  103. package/server/views/install.ejs +56 -29
  104. package/server/views/keys.ejs +276 -0
  105. package/server/views/network.ejs +889 -0
  106. package/server/views/partials/dynamic.ejs +9 -0
  107. package/server/views/partials/menu.ejs +7 -1
  108. package/server/views/prototype/index.ejs +311 -0
  109. package/server/views/prototype/show.ejs +383 -0
  110. package/server/views/redoc.ejs +18 -0
  111. package/server/views/required_env_editor.ejs +11 -2
  112. package/server/views/settings.ejs +38 -10
  113. package/server/views/setup.ejs +254 -0
  114. package/server/views/setup_home.ejs +192 -0
  115. package/server/views/shell.ejs +781 -0
  116. package/server/views/swaggerui.ejs +19 -0
  117. package/server/views/terminal.ejs +174 -42
  118. package/LICENSE +0 -7
  119. package/server/views/proxy.ejs +0 -405
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>API Docs</title>
5
+ <link rel="stylesheet" type="text/css" href="/swagger-ui.css" />
6
+ </head>
7
+ <body>
8
+ <% if (spec) { %>
9
+ <div id="swagger-ui"></div>
10
+ <script src="/swagger-ui-bundle.js"></script>
11
+ <script>
12
+ const spec = <%- spec %>;
13
+ SwaggerUIBundle({ spec, dom_id: '#swagger-ui' });
14
+ </script>
15
+ <% } else { %>
16
+ <h1>url required</h1>
17
+ <% } %>
18
+ </body>
19
+ </html>
@@ -26,6 +26,7 @@
26
26
  <script src="/notifyinput.js"></script>
27
27
  <script src="/report.js"></script>
28
28
  <script src="/mark.min.js"></script>
29
+ <script src="/dropzone-min.js"></script>
29
30
  <link href="/xterm.min.css" rel="stylesheet" />
30
31
  <link href="/css/fontawesome.min.css" rel="stylesheet">
31
32
  <link href="/css/solid.min.css" rel="stylesheet">
@@ -33,6 +34,7 @@
33
34
  <link href="/css/brands.min.css" rel="stylesheet">
34
35
  <link href="/style.css" rel="stylesheet"/>
35
36
  <link href="/noty.css" rel="stylesheet"/>
37
+ <link href="/dropzone.css" rel="stylesheet"/>
36
38
  <% if (agent === "electron") { %>
37
39
  <link href="/electron.css" rel="stylesheet"/>
38
40
  <% } %>
@@ -92,12 +94,16 @@ header {
92
94
  .xterm .xterm-viewport {
93
95
  width: initial !important;
94
96
  }
97
+ /*
95
98
  .navheader {
96
99
  background: var(--dark-bg);
97
100
  }
101
+ */
102
+ /*
98
103
  .btn {
99
104
  background: royalblue;
100
105
  }
106
+ */
101
107
  #del-bin {
102
108
  color: royalblue;
103
109
  cursor: pointer;
@@ -111,6 +117,8 @@ body.frozen {
111
117
  </style>
112
118
  <link href="/terminal.css" rel="stylesheet"/>
113
119
  <script>
120
+ let shell_id
121
+ Dropzone.autoDiscover = false;
114
122
  document.addEventListener("DOMContentLoaded", async () => {
115
123
  <% if (error) { %>
116
124
  document.querySelector(".requirements .content").innerHTML = '<div class="loading"><i class="fa-solid fa-circle-exclamation"></i> <%=error%></div>'
@@ -137,9 +145,22 @@ document.addEventListener("DOMContentLoaded", async () => {
137
145
  class RPC {
138
146
  constructor() {
139
147
  this.socket = new Socket()
148
+ this.buffer = []
140
149
  }
141
150
  write(text) {
142
- this.term.write(text)
151
+ // console.log(text)
152
+ // this.buffer += text;
153
+ // if (!this.timeout) {
154
+ // this.timeout = setTimeout(() => {
155
+ // console.log("write", this.buffer)
156
+ // this.term.write(this.buffer);
157
+ // this.buffer = "";
158
+ // this.timeout = null;
159
+ // }, 50);
160
+ // }
161
+ if (text !== "\u0007") {
162
+ this.term.write(text)
163
+ }
143
164
  this.dirty = true
144
165
  }
145
166
  finished() {
@@ -158,14 +179,22 @@ document.addEventListener("DOMContentLoaded", async () => {
158
179
  params: {
159
180
  //uri: "<%-uri%>",
160
181
  //uri: location.pathname.slice(1).replace("api/", ""),
161
- uri: "~" + location.pathname
182
+ <% if (script_path) { %>
183
+ uri: "<%=script_path%>",
184
+ <% } else { %>
185
+ uri: "~" + location.pathname,
186
+ <% } %>
162
187
  }
163
188
  }, (stream) => {
164
189
  })
165
190
  }
166
191
  save() {
167
192
  return new Promise((resolve, reject) => {
168
- let cwd = "~" + location.pathname
193
+ <% if (script_path) { %>
194
+ let cwd = "<%=script_path%>"
195
+ <% } else { %>
196
+ let cwd = "~" + location.pathname
197
+ <% } %>
169
198
 
170
199
  this.socket.close()
171
200
  this.socket.run({
@@ -194,7 +223,12 @@ document.addEventListener("DOMContentLoaded", async () => {
194
223
 
195
224
  this.socket.run({
196
225
  //uri: location.pathname.slice(1).replace("api/", ""),
197
- uri: "~" + location.pathname,
226
+ <% if (script_path) { %>
227
+ uri: "<%=script_path%>",
228
+ cwd: "<%=cwd%>",
229
+ <% } else { %>
230
+ uri: "~" + location.pathname,
231
+ <% } %>
198
232
  //uri: "<%-uri%>",
199
233
  mode,
200
234
  input: query,
@@ -206,6 +240,9 @@ document.addEventListener("DOMContentLoaded", async () => {
206
240
  if (packet.type === 'start') {
207
241
  refreshParent(packet)
208
242
  reloadMemory()
243
+ document.querySelector(".run .play").classList.add("hidden")
244
+ document.querySelector(".run .starting").classList.add("hidden")
245
+ document.querySelector(".run .stop").classList.remove("hidden")
209
246
  if (packet.data && packet.data.description) {
210
247
  if ('current' in packet.data) {
211
248
  document.querySelector("footer").innerHTML = `<b>
@@ -234,7 +271,12 @@ document.addEventListener("DOMContentLoaded", async () => {
234
271
  // </div>`
235
272
  }
236
273
  } else if (packet.type === "stream") {
274
+ // set the current shell id
275
+ if (packet.data.id) {
276
+ shell_id = packet.data.id
277
+ }
237
278
  if (packet.data.raw) {
279
+ // console.log({ packet })
238
280
  this.write(packet.data.raw)
239
281
  } else if (packet.data.json) {
240
282
  this.write(JSON.stringify(packet.data.json).replace(/\n/g, "\r\n"))
@@ -254,9 +296,33 @@ document.addEventListener("DOMContentLoaded", async () => {
254
296
  this.socket.close()
255
297
  document.querySelector(".run .play").classList.remove("hidden")
256
298
  document.querySelector(".run .stop").classList.add("hidden")
299
+
300
+ <% if (kill_message) { %>
301
+ n.Noty({
302
+ text: "<%-kill_message%>",
303
+ // timeout: 3000,
304
+ <% if (callback) { %>
305
+ callbacks: {
306
+ onClose: () => {
307
+ location.href = "<%=callback%>"
308
+ }
309
+ }
310
+ <% } %>
311
+ })
312
+ <% } else { %>
313
+ <% if (callback) { %>
314
+ location.href = "<%=callback%>"
315
+ <% } %>
316
+ <% } %>
257
317
  } else if (packet.type === 'connect') {
258
- const message = "..........Connected!\r\n"
259
- this.write(message)
318
+ if (packet.data) {
319
+ if (packet.data.shell) {
320
+ shell_id = packet.data.shell
321
+ }
322
+ if (packet.data.state) {
323
+ this.write(packet.data.state)
324
+ }
325
+ }
260
326
  /*
261
327
  for(let i=0; i<message.length; i++) {
262
328
  await new Promise((r, reject) => {
@@ -316,17 +382,21 @@ document.addEventListener("DOMContentLoaded", async () => {
316
382
  let type = (params.type ? params.type : "modal")
317
383
  let input
318
384
  if (type === "modal") {
319
- input = await ModalInput(packet.data)
385
+ input = await ModalInput(packet.data, packet.id)
320
386
  } else if (type === "notify") {
321
387
  input = await NotifyInput(packet.data, n)
322
388
  }
323
389
  if (input) {
324
- this.socket.respond({
325
- response: input,
326
- uri: packet.id
327
- // uri: "~" + location.pathname,
328
- // uri: (packet.caller ? packet.caller : packet.id)
329
- })
390
+ if (input.constructor.name === "ArrayBuffer") {
391
+ this.socket.respond(input)
392
+ } else {
393
+ this.socket.respond({
394
+ response: input,
395
+ uri: packet.id
396
+ // uri: "~" + location.pathname,
397
+ // uri: (packet.caller ? packet.caller : packet.id)
398
+ })
399
+ }
330
400
  }
331
401
  /*
332
402
  params := {
@@ -340,6 +410,25 @@ document.addEventListener("DOMContentLoaded", async () => {
340
410
  */
341
411
  } else if (packet.type === "tab.open") {
342
412
  refreshParent(packet)
413
+ } else if (packet.type === "web.open") {
414
+ /*
415
+ {
416
+ "method": "web.open",
417
+ "params": {
418
+ "uri",
419
+ "target": "_self (default)"|"_blank"|"_parent"|"_top",
420
+ "features"
421
+ }
422
+ }
423
+ */
424
+
425
+ refreshParent()
426
+ let params = packet.data
427
+ window.open(
428
+ params.uri,
429
+ (params.target || "_self"),
430
+ params.features
431
+ )
343
432
  } else if (packet.type === "browser.open") {
344
433
  /*
345
434
  {
@@ -444,10 +533,10 @@ document.addEventListener("DOMContentLoaded", async () => {
444
533
 
445
534
 
446
535
  //document.querySelector("footer .content").innerHTML = document.querySelector("footer .content").innerHTML + `<pre class='error'>${packet.data}</pre>`
447
- document.querySelector("footer .content").innerHTML = document.querySelector("footer .content").innerHTML + `<pre class='error'>ERROR</pre>`
536
+ //document.querySelector("footer .content").innerHTML = document.querySelector("footer .content").innerHTML + `<pre class='error'>ERROR</pre>`
448
537
  // document.querySelector("footer .toggle-expand i").className = "fa-solid fa-circle-chevron-down"
449
538
  // document.querySelector("footer").classList.add("expanded")
450
- document.querySelector("footer i").className = "fa-solid fa-triangle-exclamation"
539
+ //document.querySelector("footer i").className = "fa-solid fa-triangle-exclamation"
451
540
 
452
541
  document.querySelector(".run .play").classList.remove("hidden")
453
542
  document.querySelector(".run .starting").classList.add("hidden")
@@ -465,7 +554,6 @@ document.addEventListener("DOMContentLoaded", async () => {
465
554
  document.querySelector("#error-screen").classList.add("hidden")
466
555
  })
467
556
  */
468
- console.log("instance", instance)
469
557
  instance.mark(packet.event)
470
558
  let element = document.querySelector("mark")
471
559
  element.scrollIntoView({ behavior: "smooth", block: "center" });
@@ -554,15 +642,36 @@ document.addEventListener("DOMContentLoaded", async () => {
554
642
  // })
555
643
  // }
556
644
 
557
- await this.createTerm()
645
+ <% if (theme === "dark") { %>
646
+ await this.createTerm(xtermTheme.FrontEndDelight)
647
+ <% } else { %>
648
+ await this.createTerm(xtermTheme.Tomorrow)
649
+ <% } %>
558
650
  await this.start(mode)
559
651
  }
560
- async createTerm () {
652
+ async createTerm (_theme) {
561
653
  if (!this.term) {
654
+ const theme = Object.assign({ }, _theme, {
655
+ selectionBackground: "red",
656
+ selectionForeground: "white"
657
+ })
658
+
562
659
  let config = {
563
660
  scrollback: 9999999,
564
- fontSize: 12,
565
- theme: xtermTheme.FrontEndDelight
661
+ //fontSize: 12,
662
+ fontSize: 14,
663
+ theme,
664
+ //theme: xtermTheme.FrontEndDelight
665
+ //theme: xtermTheme.Afterglow
666
+
667
+ //theme: xtermTheme.PencilLight
668
+
669
+ //theme: xtermTheme.Flatland
670
+ //theme: xtermTheme.OneHalfLight
671
+ //theme: xtermTheme.Piatto_Light
672
+ //theme: xtermTheme.Spring
673
+ //theme: xtermTheme.Terminal_Basic
674
+ //theme: xtermTheme.Tomorrow
566
675
  }
567
676
  let res = await fetch("/xterm_config").then((res) => {
568
677
  return res.json()
@@ -572,13 +681,22 @@ document.addEventListener("DOMContentLoaded", async () => {
572
681
  }
573
682
  const term = new Terminal(config)
574
683
  term.open(document.querySelector("#terminal"))
575
-
576
684
  term.attachCustomKeyEventHandler(event => {
577
- if (event.ctrlKey && event.key === 'c' && term.hasSelection()) {
578
- return false;
685
+ if ((event.ctrlKey || event.metaKey) && event.key === 'c') {
686
+ const selection = term.getSelection();
687
+ if (selection) {
688
+ navigator.clipboard.writeText(selection);
689
+ return false;
690
+ }
579
691
  }
580
- if (event.ctrlKey && event.key === 'v' && this._options.pasteWithCtrlV) {
581
- return false;
692
+ if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
693
+ navigator.clipboard.readText().then((text) => {
694
+ this.socket.run({
695
+ key: "\x1b[200~" + text + "\x1b[201~",
696
+ id: shell_id
697
+ })
698
+ })
699
+ return false
582
700
  }
583
701
  return true;
584
702
  });
@@ -589,6 +707,17 @@ document.addEventListener("DOMContentLoaded", async () => {
589
707
  ////term.resize(cols, rows-5);
590
708
  //term.resize(cols, rows);
591
709
 
710
+ term.onKey(({ key }) => {
711
+ if (this.socket) {
712
+ if (shell_id) {
713
+ this.socket.run({
714
+ key,
715
+ id: shell_id
716
+ })
717
+ }
718
+ }
719
+ });
720
+
592
721
  const fitAddon = new FitAddon.FitAddon();
593
722
  // const searchAddon = new SearchAddon.SearchAddon();
594
723
  // const searchAddonBar = new SearchBarAddon.SearchBarAddon({searchAddon});
@@ -606,6 +735,7 @@ document.addEventListener("DOMContentLoaded", async () => {
606
735
  fitAddon.fit();
607
736
  this.term = term
608
737
  this.fit = fitAddon
738
+
609
739
  }
610
740
  this.term.focus()
611
741
  }
@@ -771,25 +901,27 @@ const reloadMemory = async () => {
771
901
  <% } else { %>
772
902
  <body class='<%=theme%>'>
773
903
  <% } %>
774
- <header class='navheader'>
775
904
  <% if (!install_required) { %>
776
- <div class='runner'>
777
- <% if (locals.prev) { %>
778
- <a class='btn' href="<%=prev%>"><i class="fa-solid fa-arrow-left"></i> Back</a>
779
- <% } %>
780
- <div class='btn run <%= mod && runnable ? "" : "hidden" %>'>
781
- <span class='play'><i class="fa-solid fa-play"></i> Start</span>
782
- <span class='starting hidden'><i class="fa-solid fa-circle-notch fa-spin"></i> Starting...</span>
783
- <span class='stop hidden'><i class="fa-solid fa-stop"></i> Stop</span>
905
+ <header class='navheader2'>
906
+ <div class='runner'>
907
+ <% if (locals.prev) { %>
908
+ <a class='btn' href="<%=prev%>"><i class="fa-solid fa-arrow-left"></i> Back</a>
909
+ <% } %>
910
+ <div class='btn run <%= mod && runnable ? "" : "hidden" %>'>
911
+ <span class='play'><i class="fa-solid fa-play"></i> Start</span>
912
+ <span class='starting hidden'><i class="fa-solid fa-circle-notch fa-spin"></i> Starting...</span>
913
+ <span class='stop hidden'><i class="fa-solid fa-stop"></i> Stop</span>
914
+ </div>
915
+ <% if (locals.filepath) { %>
916
+ <button class='btn' id='open-fs' data-filepath="<%=filepath%>"><i class="fa-solid fa-eye"></i> View File</button>
917
+ <% } %>
918
+ <!--
919
+ <button class='btn' id='open-log' data-logpath="<%=logpath%>"><i class="fa-solid fa-align-left"></i> View Logs</button>
920
+ -->
784
921
  </div>
785
- <button class='btn' id='open-fs' data-filepath="<%=filepath%>"><i class="fa-solid fa-eye"></i> View File</button>
786
- <!--
787
- <button class='btn' id='open-log' data-logpath="<%=logpath%>"><i class="fa-solid fa-align-left"></i> View Logs</button>
788
- -->
789
- </div>
922
+ </header>
790
923
  <% } %>
791
- </header>
792
- <% if (requirements_pending) { %>
924
+ <% if (locals.requirements_pending) { %>
793
925
  <div class='requirements'>
794
926
  <div class='content'>
795
927
  <div class='loading'>
@@ -798,7 +930,7 @@ const reloadMemory = async () => {
798
930
  </div>
799
931
  </div>
800
932
  <% } else { %>
801
- <% if (install_required) { %>
933
+ <% if (locals.install_required) { %>
802
934
  <div class='requirements'>
803
935
  <div class='content'>
804
936
  <div class='title'><i class="fa-solid fa-circle-exclamation"></i> Installation required</div>
package/LICENSE DELETED
@@ -1,7 +0,0 @@
1
- Copyright 2023 Pinokio
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
-
5
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
-
7
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.