pywebexec 1.7.0__py3-none-any.whl → 1.7.2__py3-none-any.whl

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.
pywebexec/pywebexec.py CHANGED
@@ -56,6 +56,8 @@ if os.path.isdir(f"{CONFDIR}/.config"):
56
56
  CONFDIR += '/.config'
57
57
  CONFDIR += "/.pywebexec"
58
58
  term_command_id = str(uuid.uuid4())
59
+ tty_cols = 125
60
+ tty_rows = 30
59
61
 
60
62
  # In-memory cache for command statuses
61
63
  status_cache = {}
@@ -181,6 +183,8 @@ class PyWebExec(Application):
181
183
  return self.application
182
184
  #38;2;66;59;165m
183
185
  ANSI_ESCAPE = re.compile(br'(?:\x1B[@-Z\\-_]|\x1B([(]B|>)|(?:\x1B\[|\x9B)[0-?]*[ -/]*[@-~]|\x1B\[([0-9]{1,2};){0,4}[0-9]{1,3}[m|K]|\x1B\[[0-9;]*[mGKHF]|[\x00-\x1F\x7F])')
186
+ ANSI_ESCAPE = re.compile(br'(?:\x1B[@-Z\\-_]|\x1B([(]B|>)|(?:\x1B\[|\x9B)[0-?]*[ -/]*[@-~]|\x1B\[([0-9]{1,2};){0,4}[0-9]{1,3}[m|K]|\x1B\[[0-9;]*[mGKHF])')
187
+ ANSI_ESCAPE = re.compile(br'(\x1B\[([0-9]{1,2};){0,4}[0-9]{1,3}[m|K]|\x1B\[[0-9;]*[mGKHF])')
184
188
 
185
189
  def strip_ansi_control_chars(text):
186
190
  """Remove ANSI and control characters from the text."""
@@ -202,12 +206,10 @@ def get_visible_output(line, cols, rows):
202
206
  stream = pyte.ByteStream(screen)
203
207
  stream.feed(line)
204
208
  visible_line = ""
205
- row = rows - 1
206
- while row > 0:
207
- visible_line = screen.display[row].strip(" ")
209
+ for visible_line in reversed(screen.display):
210
+ visible_line = visible_line.strip(" ")
208
211
  if visible_line:
209
212
  return visible_line
210
- row -= 1
211
213
  except:
212
214
  return ""
213
215
  return ""
@@ -215,8 +217,8 @@ def get_visible_output(line, cols, rows):
215
217
 
216
218
  def get_last_line(file_path, cols=None, rows=None, maxsize=2048):
217
219
  """Retrieve last non empty line after vt100 interpretation"""
218
- cols = cols or 125
219
- rows = rows or 24
220
+ cols = cols or tty_cols
221
+ rows = rows or tty_rows
220
222
  with open(file_path, 'rb') as fd:
221
223
  try:
222
224
  fd.seek(-maxsize, os.SEEK_END)
@@ -440,7 +442,8 @@ def update_command_status(command_id, updates):
440
442
  status_cache[command_id] = status
441
443
  with open(status_file_path, 'w') as f:
442
444
  json.dump(status, f)
443
-
445
+
446
+
444
447
  def read_command_status(command_id):
445
448
  # Return cached status if available
446
449
  status_data = {}
@@ -449,6 +452,8 @@ def read_command_status(command_id):
449
452
  status = status_data.get('status')
450
453
  if status and status != "running":
451
454
  return status_data
455
+ if command_id in status_cache and status_cache.get('last_read',0)>datetime.now().timestamp()-0.5:
456
+ return status_data
452
457
  status_file_path = get_status_file_path(command_id)
453
458
  if not os.path.exists(status_file_path):
454
459
  return None
@@ -457,6 +462,7 @@ def read_command_status(command_id):
457
462
  status_data.update(json.load(f))
458
463
  except json.JSONDecodeError:
459
464
  return None
465
+ status_data['last_read'] = datetime.now().timestamp()
460
466
  status_cache[command_id] = status_data
461
467
  return status_data
462
468
 
@@ -493,18 +499,19 @@ def run_command(fromip, user, command, params, command_id):
493
499
  'command': command,
494
500
  'params': params,
495
501
  'start_time': start_time,
496
- 'user': user
502
+ 'user': user,
503
+ 'cols': tty_cols,
504
+ 'rows': tty_rows,
497
505
  })
498
506
  output_file_path = get_output_file_path(command_id)
499
507
  try:
500
508
  with open(output_file_path, 'wb') as fd:
501
- p = pexpect.spawn(command, params, ignore_sighup=True, timeout=None)
509
+ p = pexpect.spawn(command, params, ignore_sighup=True, timeout=None, dimensions=(tty_rows, tty_cols))
502
510
  update_command_status(command_id, {
503
511
  'status': 'running',
504
512
  'pid': p.pid,
505
513
  'user': user
506
514
  })
507
- p.setwinsize(24, 125)
508
515
  p.logfile = fd
509
516
  p.expect(pexpect.EOF)
510
517
  fd.flush()
@@ -790,6 +797,7 @@ def get_command_output(command_id):
790
797
  'output': output[-maxsize:],
791
798
  'status': status_data.get("status"),
792
799
  'cols': status_data.get("cols"),
800
+ 'rows': status_data.get("rows"),
793
801
  'links': {
794
802
  'next': f'{request.url_root}command_output/{command_id}?offset={new_offset}&maxsize={maxsize}{token_param}'
795
803
  }
@@ -48,7 +48,6 @@ select { /* Safari bug */
48
48
  min-width: 150px;
49
49
  }
50
50
  .output {
51
- white-space: pre-wrap;
52
51
  background: #111;
53
52
  padding: 10px;
54
53
  border: 1px solid #ccc;
@@ -329,20 +328,18 @@ span {
329
328
 
330
329
  .pause {
331
330
  background-image: url("/static/images/pause.svg");
332
- /*background-size: contain;*/
333
- background-repeat: no-repeat;
334
- background-position: center;
335
- background-size: 24px 24px;
336
331
  }
337
332
  .resume {
338
333
  background-image: url("/static/images/resume.svg");
339
- /*background-size: contain;*/
340
- background-repeat: no-repeat;
341
- background-position: center;
342
- background-size: 24px 24px;
343
334
  }
344
335
 
345
- .pause-resume-button {
336
+ .fit-window {
337
+ background-image: url("/static/images/fit-win.svg");
338
+ }
339
+ .fit-tty {
340
+ background-image: url("/static/images/fit-tty.svg");
341
+ }
342
+ .pause-resume-button, .fit-button {
346
343
  background-color: transparent;
347
344
  border: none;
348
345
  /*padding: 0;*/
@@ -350,6 +347,10 @@ span {
350
347
  height: 24px;
351
348
  cursor: pointer;
352
349
  flex-shrink: 0;
350
+ background-repeat: no-repeat;
351
+ background-position: center;
352
+ background-size: 24px 24px;
353
+
353
354
  }
354
355
 
355
356
 
@@ -389,4 +390,8 @@ span {
389
390
  border-radius: 17px;
390
391
  min-width: 17px;
391
392
  text-align: center;
393
+ }
394
+
395
+ .xterm-accessibility {
396
+ display: none;
392
397
  }
@@ -0,0 +1 @@
1
+ <svg height="200px" width="200px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-42.63 -42.63 558.91 558.91" xml:space="preserve" fill="#000000"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <circle style="fill:#404040;" cx="236.827" cy="236.827" r="236.827"></circle> <g> <path style="fill:#FFFFFF;" d="M421.487,220.971c-32.306,0-64.612,0-96.919,0c10.033-10.033,20.07-20.067,30.104-30.1 c12.782-12.778-7.128-32.538-19.939-19.726c-17.999,17.995-35.993,35.99-53.992,53.984c-5.422,5.419-5.277,14.453,0.105,19.835 c17.999,17.999,35.993,35.993,53.992,53.992c12.782,12.782,32.542-7.128,19.726-19.939c-9.996-9.996-19.992-19.992-29.988-29.988 c32.235,0,64.47,0,96.705,0C439.396,249.026,439.557,220.971,421.487,220.971z"></path> <path style="fill:#FFFFFF;" d="M193.011,225.021c-17.999-17.999-35.993-35.99-53.992-53.984 c-12.782-12.782-32.542,7.128-19.726,19.939c10,10,19.999,19.995,29.995,29.995c-32.239,0-64.474,0-96.713,0 c-18.111,0-18.272,28.054-0.202,28.054c32.302,0,64.601,0,96.904,0c-10.03,10.033-20.063,20.059-30.092,30.092 c-12.782,12.782,7.128,32.542,19.939,19.726c17.999-17.999,35.993-35.993,53.992-53.992 C198.541,239.434,198.396,230.399,193.011,225.021z"></path> <circle style="fill:#FFFFFF;" cx="236.827" cy="236.79" r="24.098"></circle> </g> </g></svg>
@@ -0,0 +1 @@
1
+ <svg height="200px" width="200px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-42.63 -42.63 558.91 558.91" xml:space="preserve" fill="#000000"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <circle style="fill:#404040;" cx="236.827" cy="236.827" r="236.827"></circle> <g> <path style="fill:#FFFFFF;" d="M431.251,225.029c-17.999-17.999-35.993-36.001-53.992-53.996 c-12.778-12.782-32.542,7.128-19.726,19.939c9.996,10,19.992,19.995,29.991,29.995c-32.235,0-64.474,0-96.709,0 c-18.111,0-18.272,28.054-0.202,28.054c32.306,0,64.612,0,96.919,0c-10.033,10.033-20.07,20.067-30.104,30.1 c-12.782,12.778,7.128,32.538,19.939,19.726c17.999-17.995,35.993-35.99,53.992-53.984 C436.782,239.437,436.633,230.406,431.251,225.029z"></path> <path style="fill:#FFFFFF;" d="M183.247,220.964c-32.302,0-64.605,0-96.907,0c10.033-10.033,20.063-20.067,30.096-30.1 c12.782-12.782-7.128-32.542-19.939-19.726c-17.999,17.999-35.993,35.997-53.992,53.996c-5.422,5.422-5.277,14.453,0.105,19.835 c17.999,17.999,35.993,35.99,53.992,53.984c12.782,12.782,32.542-7.128,19.726-19.939c-10-10-19.999-19.996-29.995-29.995 c32.239,0,64.474,0,96.713,0C201.155,249.018,201.316,220.964,183.247,220.964z"></path> <circle style="fill:#FFFFFF;" cx="236.827" cy="236.79" r="24.098"></circle> </g> </g></svg>
@@ -75,8 +75,30 @@ let fullOutput = '';
75
75
  let outputLength = 0;
76
76
  let slider = null;
77
77
  let isPaused = false;
78
+ let cols = 0;
79
+ let rows = 0;
80
+ let fitWindow = false;
81
+
78
82
  const toggleButton = document.getElementById('toggleFetch');
79
83
  const pausedMessage = document.getElementById('pausedMessage');
84
+ const toggleFitButton = document.getElementById('toggleFit');
85
+
86
+ function autoFit(scroll=true) {
87
+ // Scroll output div to bottom
88
+ const outputDiv = document.getElementById('output');
89
+ outputDiv.scrollTop = terminal.element.clientHeight - outputDiv.clientHeight + 20;
90
+ if (cols && !fitWindow) {
91
+ let fit = fitAddon.proposeDimensions();
92
+ if (fit.rows < rows) {
93
+ terminal.resize(cols, rows);
94
+ } else {
95
+ terminal.resize(cols, fit.rows);
96
+ }
97
+ } else {
98
+ fitAddon.fit();
99
+ }
100
+ if (scroll) terminal.scrollToBottom();
101
+ }
80
102
 
81
103
  function getTokenParam() {
82
104
  const urlParams = new URLSearchParams(window.location.search);
@@ -104,8 +126,10 @@ async function fetchOutput(url) {
104
126
  clearInterval(outputInterval);
105
127
  } else {
106
128
  if (data.cols) {
107
- terminal.resize(data.cols, terminal.rows);
108
- } else fitAddon.fit();
129
+ cols = data.cols;
130
+ rows = data.rows;
131
+ autoFit(false);
132
+ }
109
133
  percentage = slider.value;
110
134
  fullOutput += data.output;
111
135
  if (fullOutput.length > maxSize)
@@ -178,8 +202,7 @@ function adjustOutputHeight() {
178
202
  const outputTop = outputDiv.getBoundingClientRect().top;
179
203
  const maxHeight = windowHeight - outputTop - 60; // Adjusted for slider height
180
204
  outputDiv.style.height = `${maxHeight}px`;
181
- fitAddon.fit();
182
- sliderUpdateOutput();
205
+ autoFit();
183
206
  }
184
207
 
185
208
  function sliderUpdateOutput() {
@@ -214,9 +237,20 @@ function toggleFetchOutput() {
214
237
  }
215
238
  isPaused = !isPaused;
216
239
  }
240
+ function toggleFit() {
241
+ fitWindow = ! fitWindow;
242
+ if (fitWindow) {
243
+ toggleFitButton.classList.add('fit-tty');
244
+ toggleFitButton.setAttribute('title', 'terminal fit tty');
245
+ } else {
246
+ toggleFitButton.classList.remove('fit-tty');
247
+ toggleFitButton.setAttribute('title', 'terminal fit window');
248
+ }
249
+ autoFit();
250
+ }
217
251
 
218
252
  toggleButton.addEventListener('click', toggleFetchOutput);
219
-
253
+ toggleFitButton.addEventListener('click', toggleFit);
220
254
  window.addEventListener('resize', adjustOutputHeight);
221
255
  window.addEventListener('load', () => {
222
256
  slider = document.getElementById('outputSlider');
@@ -229,11 +263,11 @@ window.addEventListener('load', () => {
229
263
  document.getElementById('decreaseFontSize').addEventListener('click', () => {
230
264
  fontSize = Math.max(8, fontSize - 1);
231
265
  terminal.options.fontSize = fontSize;
232
- fitAddon.fit();
266
+ autoFit();
233
267
  });
234
268
 
235
269
  document.getElementById('increaseFontSize').addEventListener('click', () => {
236
270
  fontSize = Math.min(32, fontSize + 1);
237
271
  terminal.options.fontSize = fontSize;
238
- fitAddon.fit();
272
+ autoFit();
239
273
  });
@@ -11,6 +11,9 @@ let fontSize = 14;
11
11
  let isPaused = false;
12
12
  let showRunningOnly = false;
13
13
  let hiddenCommandIds = [];
14
+ let fitWindow = false;
15
+ let cols = 0;
16
+ let rows = 0;
14
17
 
15
18
  function initTerminal()
16
19
  {
@@ -97,6 +100,23 @@ terminal.onSelectionChange(() => {
97
100
  }
98
101
  });
99
102
 
103
+ function autoFit(scroll=true) {
104
+ // Scroll output div to bottom
105
+ const outputDiv = document.getElementById('output');
106
+ outputDiv.scrollTop = terminal.element.clientHeight - outputDiv.clientHeight + 20;
107
+ if (cols && !fitWindow) {
108
+ let fit = fitAddon.proposeDimensions();
109
+ if (fit.rows < rows) {
110
+ terminal.resize(cols, rows);
111
+ } else {
112
+ terminal.resize(cols, fit.rows);
113
+ }
114
+ } else {
115
+ fitAddon.fit();
116
+ }
117
+ if (scroll) terminal.scrollToBottom();
118
+ }
119
+
100
120
  function getTokenParam() {
101
121
  const urlParams = new URLSearchParams(window.location.search);
102
122
  return urlParams.get('token') ? `?token=${urlParams.get('token')}` : '';
@@ -201,8 +221,10 @@ async function fetchOutput(url) {
201
221
  clearInterval(outputInterval);
202
222
  } else {
203
223
  if (data.cols) {
204
- terminal.resize(data.cols, terminal.rows);
205
- } else fitAddon.fit();
224
+ cols = data.cols;
225
+ rows = data.rows;
226
+ autoFit(scroll=false);
227
+ }
206
228
  fullOutput += data.output;
207
229
  if (fullOutput.length > maxSize)
208
230
  fullOutput = fullOutput.slice(-maxSize);
@@ -370,7 +392,7 @@ function adjustOutputHeight() {
370
392
  const outputTop = outputDiv.getBoundingClientRect().top;
371
393
  const maxHeight = windowHeight - outputTop - 60; // Adjusted for slider height
372
394
  outputDiv.style.height = `${maxHeight}px`;
373
- fitAddon.fit();
395
+ autoFit();
374
396
  }
375
397
 
376
398
  function initResizer() {
@@ -412,17 +434,19 @@ slider.addEventListener('input', sliderUpdateOutput);
412
434
  document.getElementById('decreaseFontSize').addEventListener('click', () => {
413
435
  fontSize = Math.max(8, fontSize - 1);
414
436
  terminal.options.fontSize = fontSize;
415
- fitAddon.fit();
437
+ autoFit();
416
438
  });
417
439
 
418
440
  document.getElementById('increaseFontSize').addEventListener('click', () => {
419
441
  fontSize = Math.min(32, fontSize + 1);
420
442
  terminal.options.fontSize = fontSize;
421
- fitAddon.fit();
443
+ autoFit();
422
444
  });
423
445
 
424
446
  const toggleButton = document.getElementById('toggleFetch');
425
447
  const pausedMessage = document.getElementById('pausedMessage');
448
+ const toggleFitButton = document.getElementById('toggleFit');
449
+
426
450
 
427
451
  function toggleFetchOutput() {
428
452
  if (isPaused) {
@@ -446,8 +470,20 @@ function toggleFetchOutput() {
446
470
  }
447
471
  isPaused = !isPaused;
448
472
  }
473
+ function toggleFit() {
474
+ fitWindow = ! fitWindow;
475
+ if (fitWindow) {
476
+ toggleFitButton.classList.add('fit-tty');
477
+ toggleFitButton.setAttribute('title', 'terminal fit tty');
478
+ } else {
479
+ toggleFitButton.classList.remove('fit-tty');
480
+ toggleFitButton.setAttribute('title', 'terminal fit window');
481
+ }
482
+ autoFit();
483
+ }
449
484
 
450
485
  toggleButton.addEventListener('click', toggleFetchOutput);
486
+ toggleFitButton.addEventListener('click', toggleFit);
451
487
 
452
488
  document.getElementById('thStatus').addEventListener('click', () => {
453
489
  showRunningOnly = !showRunningOnly;
@@ -52,6 +52,7 @@
52
52
  <button id="toggleFetch" class="pause-resume-button pause"></button>
53
53
  <button id="decreaseFontSize" class="font-size-button font-decrease"></button>
54
54
  <button id="increaseFontSize" class="font-size-button font-increase"></button>
55
+ <button id="toggleFit" class="fit-button fit-window" title="terminal fit window"></button>
55
56
  </div>
56
57
  <script src="/static/js/xterm/xterm.js"></script>
57
58
  <script src="/static/js/xterm/addon-canvas.js"></script>
@@ -20,6 +20,7 @@
20
20
  <button id="toggleFetch" class="pause-resume-button pause"></button>
21
21
  <button id="decreaseFontSize" class="font-size-button font-decrease"></button>
22
22
  <button id="increaseFontSize" class="font-size-button font-increase"></button>
23
+ <button id="toggleFit" class="fit-button fit-window" title="terminal fit window"></button>
23
24
  </div>
24
25
  <script src="/static/js/xterm/xterm.js"></script>
25
26
  <script src="/static/js/xterm/addon-canvas.js"></script>
pywebexec/version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.7.0'
16
- __version_tuple__ = version_tuple = (1, 7, 0)
15
+ __version__ = version = '1.7.2'
16
+ __version_tuple__ = version_tuple = (1, 7, 2)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 1.7.0
3
+ Version: 1.7.2
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -1,8 +1,8 @@
1
1
  pywebexec/__init__.py,sha256=4spIsVaF8RJt8S58AG_wWoORRNkws9Iwqprj27C3ljM,99
2
- pywebexec/pywebexec.py,sha256=J5cPqvF8OfdKAmuvNiRgVIGsiromBBdK1Nna80tNPro,33006
3
- pywebexec/version.py,sha256=2fEqxujmrV2dsREie2BmOYFLu66FowyHtZT2AoLuIzU,411
2
+ pywebexec/pywebexec.py,sha256=gJsI7kob3IyB6DVoWWSyEHOcxpWlsZz-b7jQUyePA-A,33555
3
+ pywebexec/version.py,sha256=Qj1rYkRQ0hSV6NX03bgvPhjsn6HWrQ8maBXi446C5ZM,411
4
4
  pywebexec/static/css/Consolas NF.ttf,sha256=DJEOzF0eqZ-kxu3Gs_VE8X0NJqiobBzmxWDGpdgGRxI,1313900
5
- pywebexec/static/css/style.css,sha256=MJHUBpjWL4sLxM7a7DxypmPKaFJQbmA_ESNXsbLviNI,8201
5
+ pywebexec/static/css/style.css,sha256=3s7QgbCh4wb7kfZ7Pjo-B6o3lDIBogZ-3j6AfaPdpzU,8209
6
6
  pywebexec/static/css/xterm.css,sha256=uo5phWaUiJgcz0DAzv46uoByLLbJLeetYosL1xf68rY,5559
7
7
  pywebexec/static/images/aborted.svg,sha256=2nuvSwGBIZGWtlM1DrBO3qiSq1reDbcZDAj9rJXBnjY,380
8
8
  pywebexec/static/images/copy.svg,sha256=d9OwtGh5GzzZHzYcDrLfNxZYLth1Q64x7bRyYxu4Px0,622
@@ -10,6 +10,8 @@ pywebexec/static/images/copy_ok.svg,sha256=mEqUVUhSq8xaJK2msQkxRawnz_KwlCZ-tok8Q
10
10
  pywebexec/static/images/down-arrow.svg,sha256=4TclEmntMvKk_F_ADXgTpGtviYo826EDmmZiGE7HQBI,121
11
11
  pywebexec/static/images/failed.svg,sha256=rSTBWOtiz7slGDobeU_vaLaMM8CoPeul_tQgWVBcodo,1438
12
12
  pywebexec/static/images/favicon.svg,sha256=9gSN5Oak1zTWhTCyutlupPBKUxcbdoVt7dvhk8xvEug,1224
13
+ pywebexec/static/images/fit-tty.svg,sha256=gyRB9cqvXFSUOzpBq_Cr0Hv8nIpfr5ca74uUXjkLR-A,1438
14
+ pywebexec/static/images/fit-win.svg,sha256=_JNK-ew7mc8QIFG2D2TPNm0W2wN2d3Oa6d2d8iwbCFQ,1435
13
15
  pywebexec/static/images/font-decrease.svg,sha256=89TJXQpfZ-XDJ2qC0c7cbLH-tWC-4AJQr_VOgsp06Gg,1782
14
16
  pywebexec/static/images/font-increase.svg,sha256=u-EBxUzmOhKx4UH96fb4gLZ0l6Jkew1HLhcSqz7Z1ak,1869
15
17
  pywebexec/static/images/norun.svg,sha256=_9PyQklBOfUwFak1gVrm-76tYM825urAFhj-zMBec20,555
@@ -19,8 +21,8 @@ pywebexec/static/images/resume.svg,sha256=99LP1Ya2JXakRCO9kW8JMuT_4a_CannF65Eiuw
19
21
  pywebexec/static/images/running.svg,sha256=fBCYwYb2O9K4N3waC2nURP25NRwZlqR4PbDZy6JQMww,610
20
22
  pywebexec/static/images/success.svg,sha256=NVwezvVMplt46ElW798vqGfrL21Mw_DWHUp_qiD_FU8,489
21
23
  pywebexec/static/js/commands.js,sha256=h2fkd9qpypLBxvhEEbay23nwuqUwcKJA0vHugcyL8pU,7961
22
- pywebexec/static/js/popup.js,sha256=I5TLYUm5s2p12a0VfFONOxxzhXLBmnpVzM-B5W-GPis,8294
23
- pywebexec/static/js/script.js,sha256=EPofQO0ec2bwIr2YdzzNY3dcXipW2_Mi2j34DIYvJeE,17096
24
+ pywebexec/static/js/popup.js,sha256=UPKtjPLIR5KaAV2i1iWUGwcCTX1tT3vnOIMc8VKQqag,9311
25
+ pywebexec/static/js/script.js,sha256=W5NfzFYdyfQpALx_bjeppQFVWxvZGMoVTTq0VOnITxw,18147
24
26
  pywebexec/static/js/xterm/LICENSE,sha256=EU1P4eXTull-_T9I80VuwnJXubB-zLzUl3xpEYj2T1M,1083
25
27
  pywebexec/static/js/xterm/addon-canvas.js,sha256=ez6QTVvsmLVNJmdJlM-ZQ5bErwlxAQ_9DUmDIptl2TM,94607
26
28
  pywebexec/static/js/xterm/addon-canvas.js.map,sha256=ECBA4B-BqUpdFeRzlsEWLSQnudnhLP-yPQJ8_hKquMo,379537
@@ -31,11 +33,11 @@ pywebexec/static/js/xterm/addon-unicode11.js.map,sha256=paDj5KKtTIUGedQn2x7CaUTD
31
33
  pywebexec/static/js/xterm/xterm.js,sha256=H5kaw7Syg-v5bmCuI6AKUnZd06Lkb6b92p8aqwMvdJU,289441
32
34
  pywebexec/static/js/xterm/xterm.js.map,sha256=Y7O2Pb-fIS7Z8AC1D5s04_aiW_Jf1f4mCfN0U_OI6Zw,1118392
33
35
  pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- pywebexec/templates/index.html,sha256=5h8kLyzAhbvUDU9sEwrGIvD6FxAMcDZLXlN-ldlO8KU,2880
35
- pywebexec/templates/popup.html,sha256=3ZqQcE9mYs-RXv0Lfb24zntOlvR137ZYI9mtCZNVAo0,1407
36
- pywebexec-1.7.0.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
37
- pywebexec-1.7.0.dist-info/METADATA,sha256=qEu0SeeVHBVgAhPPeM2Fe8Rhq6RhGNaPudJyJS1t-3k,8000
38
- pywebexec-1.7.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
39
- pywebexec-1.7.0.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
40
- pywebexec-1.7.0.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
41
- pywebexec-1.7.0.dist-info/RECORD,,
36
+ pywebexec/templates/index.html,sha256=2fEN8cggHBEd8-RamDFpnekVJtIbRembFSw0-1YEptc,2979
37
+ pywebexec/templates/popup.html,sha256=GT2jY7oOxpCaBaRl924QJWdFBmfSOP952T13d37R_pY,1506
38
+ pywebexec-1.7.2.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
39
+ pywebexec-1.7.2.dist-info/METADATA,sha256=NudV7MvLxsTsIZzpTjzNuLJNijAmoK0C9o5VDIg0oRI,8000
40
+ pywebexec-1.7.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
41
+ pywebexec-1.7.2.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
42
+ pywebexec-1.7.2.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
43
+ pywebexec-1.7.2.dist-info/RECORD,,