runtimepy 5.7.0__py3-none-any.whl → 5.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.
runtimepy/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
3
  # version=3.1.4
4
- # hash=c51f4ac6cf134b3c3fa872a096e83489
4
+ # hash=0a0c607a8f78dc35cf48427539c9bafa
5
5
  # =====================================
6
6
 
7
7
  """
@@ -10,7 +10,7 @@ Useful defaults and other package metadata.
10
10
 
11
11
  DESCRIPTION = "A framework for implementing Python services."
12
12
  PKG_NAME = "runtimepy"
13
- VERSION = "5.7.0"
13
+ VERSION = "5.7.2"
14
14
 
15
15
  # runtimepy-specific content.
16
16
  METRICS_NAME = "metrics"
@@ -98,13 +98,8 @@ button:hover {
98
98
  width: 6em;
99
99
  }
100
100
 
101
- /*
102
- * Should probably build the bootstrap stuff from source and set custom Sass:
103
- * https://getbootstrap.com/docs/5.3/customize/sass/
104
- */
105
-
106
- :root {
107
- /* Prefer 'Arial' and 'Consolas' at the highest priority. */
108
- --bs-font-sans-serif: Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
109
- --bs-font-monospace: Consolas, "Liberation Mono", "Courier New", monospace;
101
+ /* Prefer 'CascadiaCode' and 'CascadiaMono' at the highest priority. */
102
+ :root, [data-bs-theme=dark], [data-bs-theme=light] {
103
+ --bs-font-sans-serif: CascadiaCode, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
104
+ --bs-font-monospace: CascadiaMono, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
110
105
  }
@@ -0,0 +1,47 @@
1
+ @font-face {
2
+ font-family: CascadiaCode;
3
+ src: url("/static/woff2/CascadiaCode-Regular.woff2");
4
+ }
5
+
6
+ @font-face {
7
+ font-family: CascadiaCode;
8
+ src: url("/static/woff2/CascadiaCode-Bold.woff2");
9
+ font-weight: bold;
10
+ }
11
+
12
+ @font-face {
13
+ font-family: CascadiaCode;
14
+ src: url("/static/woff2/CascadiaCode-BoldItalic.woff2");
15
+ font-weight: bold;
16
+ font-style: italic;
17
+ }
18
+
19
+ @font-face {
20
+ font-family: CascadiaCode;
21
+ src: url("/static/woff2/CascadiaCode-Italic.woff2");
22
+ font-style: italic;
23
+ }
24
+
25
+ @font-face {
26
+ font-family: CascadiaMono;
27
+ src: url("/static/woff2/CascadiaMono-Regular.woff2");
28
+ }
29
+
30
+ @font-face {
31
+ font-family: CascadiaMono;
32
+ src: url("/static/woff2/CascadiaMono-Bold.woff2");
33
+ font-weight: bold;
34
+ }
35
+
36
+ @font-face {
37
+ font-family: CascadiaMono;
38
+ src: url("/static/woff2/CascadiaMono-BoldItalic.woff2");
39
+ font-weight: bold;
40
+ font-style: italic;
41
+ }
42
+
43
+ @font-face {
44
+ font-family: CascadiaMono;
45
+ src: url("/static/woff2/CascadiaMono-Italic.woff2");
46
+ font-style: italic;
47
+ }
Binary file
runtimepy/data/js/main.js CHANGED
@@ -1,6 +1,14 @@
1
+ function changeFileName(urlObj, newFileName) {
2
+ let pathParts = urlObj.pathname.split('/');
3
+ pathParts[pathParts.length - 1] = newFileName;
4
+ return pathParts.join('/');
5
+ }
6
+
1
7
  /* Load configuration data then run application entry. */
2
8
  window.onload = async () => {
3
- await (new App(await (await fetch(window.location.origin + "/json")).json(),
4
- worker))
9
+ await (
10
+ new App(
11
+ await (await fetch(changeFileName(window.location, "json"))).json(),
12
+ worker))
5
13
  .main();
6
14
  };
@@ -0,0 +1,22 @@
1
+ <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
2
+ <circle r="50.0" cx="50.0" cy="50.0" style="fill: #ADB5BD" />
3
+ <rect x="16.666666666666664" y="33.333333333333336" width="16.666666666666668" height="8.333333333333334" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
4
+ <rect x="16.666666666666664" y="45.833333333333336" width="16.666666666666668" height="8.333333333333334" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
5
+ <rect x="16.666666666666664" y="58.333333333333336" width="16.666666666666668" height="8.333333333333334" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
6
+ <rect x="58.33333333333333" y="16.666666666666664" width="8.333333333333334" height="16.666666666666668" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
7
+ <rect x="45.83333333333333" y="16.666666666666664" width="8.333333333333334" height="16.666666666666668" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
8
+ <rect x="33.33333333333333" y="16.666666666666664" width="8.333333333333334" height="16.666666666666668" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
9
+ <rect x="33.333333333333336" y="66.66666666666667" width="8.333333333333334" height="16.666666666666668" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
10
+ <rect x="45.833333333333336" y="66.66666666666667" width="8.333333333333334" height="16.666666666666668" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
11
+ <rect x="58.333333333333336" y="66.66666666666667" width="8.333333333333334" height="16.666666666666668" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
12
+ <rect x="66.66666666666667" y="58.33333333333333" width="16.666666666666668" height="8.333333333333334" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
13
+ <rect x="66.66666666666667" y="45.83333333333333" width="16.666666666666668" height="8.333333333333334" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
14
+ <rect x="66.66666666666667" y="33.33333333333333" width="16.666666666666668" height="8.333333333333334" rx="4.166666666666667" ry="4.166666666666667" style="fill: #495057" />
15
+ <rect x="25.0" y="25.0" width="50.0" height="50.0" rx="8.333333333333334" ry="8.333333333333334" style="fill: #212529" />
16
+ <line stroke-linecap="round" style="stroke:#DEE2E6;stroke-width:3.125" x1="31.25" y1="50.0" x2="40.625" y2="59.375" />
17
+ <line stroke-linecap="round" style="stroke:#DEE2E6;stroke-width:3.125" x1="31.25" y1="50.0" x2="40.625" y2="40.625" />
18
+ <line stroke-linecap="round" style="stroke:#DEE2E6;stroke-width:3.125" x1="68.75" y1="50.0" x2="59.375" y2="59.375" />
19
+ <line stroke-linecap="round" style="stroke:#DEE2E6;stroke-width:3.125" x1="68.75" y1="50.0" x2="59.375" y2="40.625" />
20
+ <line stroke-linecap="round" style="stroke:#DEE2E6;stroke-width:3.125" x1="45.3125" y1="61.71875" x2="50.0" y2="50.0" />
21
+ <line stroke-linecap="round" style="stroke:#DEE2E6;stroke-width:3.125" x1="54.6875" y1="38.28125" x2="50.0" y2="50.0" />
22
+ </svg>
@@ -0,0 +1,9 @@
1
+ # [Cascadia Code](https://github.com/microsoft/cascadia-code)
2
+
3
+ Assets sourced from
4
+ [this release](https://github.com/microsoft/cascadia-code/releases/tag/v2404.23).
5
+
6
+ See also:
7
+ [LICENSE](https://github.com/microsoft/cascadia-code/blob/main/LICENSE).
8
+
9
+ **Fonts are used from release as-is.**
@@ -3,11 +3,12 @@ A module implementing a server interface for this package.
3
3
  """
4
4
 
5
5
  # built-in
6
+ import http
6
7
  from io import StringIO
7
8
  import logging
8
9
  import mimetypes
9
10
  from pathlib import Path
10
- from typing import Any, Optional, TextIO
11
+ from typing import Any, Optional, TextIO, Union
11
12
 
12
13
  # third-party
13
14
  from vcorelib.io import JsonObject
@@ -22,6 +23,7 @@ from runtimepy.net.http.response import ResponseHeader
22
23
  from runtimepy.net.server.html import HtmlApp, HtmlApps, html_handler
23
24
  from runtimepy.net.server.json import encode_json, json_handler
24
25
  from runtimepy.net.tcp.http import HttpConnection
26
+ from runtimepy.util import normalize_root, path_has_part
25
27
 
26
28
  MIMETYPES_INIT = False
27
29
 
@@ -48,6 +50,7 @@ class RuntimepyServerConnection(HttpConnection):
48
50
 
49
51
  paths: list[Path]
50
52
  class_paths: list[Pathlike] = [Path(), package_data_dir()]
53
+ class_redirect_paths: dict[Path, Union[str, Path]] = {}
51
54
 
52
55
  def add_path(self, path: Pathlike, front: bool = False) -> None:
53
56
  """Add a path."""
@@ -60,6 +63,19 @@ class RuntimepyServerConnection(HttpConnection):
60
63
 
61
64
  self.log_paths()
62
65
 
66
+ @classmethod
67
+ def add_redirect_path(
68
+ cls, dest: Union[str, Path], *src_parts: Union[str, Path]
69
+ ) -> None:
70
+ """Add a redirect path."""
71
+
72
+ source = normalize_root(*src_parts)
73
+ assert source not in cls.class_redirect_paths, (
74
+ source,
75
+ cls.class_redirect_paths,
76
+ )
77
+ cls.class_redirect_paths[source] = dest
78
+
63
79
  def log_paths(self) -> None:
64
80
  """Log search paths."""
65
81
 
@@ -90,6 +106,23 @@ class RuntimepyServerConnection(HttpConnection):
90
106
  with favicon.open("rb") as favicon_fd:
91
107
  type(self).favicon_data = favicon_fd.read()
92
108
 
109
+ def try_redirect(
110
+ self, path: PathMaybeQuery, response: ResponseHeader
111
+ ) -> Optional[bytes]:
112
+ """Try handling any HTTP redirect rules."""
113
+
114
+ result = None
115
+
116
+ curr = Path(path[0])
117
+ if curr in self.class_redirect_paths:
118
+ response["Location"] = str(self.class_redirect_paths[curr])
119
+ response.status = http.HTTPStatus.TEMPORARY_REDIRECT
120
+
121
+ # No data payload, but signal to caller that a response is ready.
122
+ result = bytes()
123
+
124
+ return result
125
+
93
126
  def try_file(
94
127
  self, path: PathMaybeQuery, response: ResponseHeader
95
128
  ) -> Optional[bytes]:
@@ -188,13 +221,14 @@ class RuntimepyServerConnection(HttpConnection):
188
221
  response["Content-Type"] = "image/x-icon"
189
222
  return self.favicon_data
190
223
 
191
- # Try serving the path as a file.
192
- result = self.try_file(request.target.origin_form, response)
193
- if result is not None:
194
- return result
224
+ # Try serving a file and handling redirects.
225
+ for handler in [self.try_redirect, self.try_file]:
226
+ result = handler(request.target.origin_form, response)
227
+ if result is not None:
228
+ return result
195
229
 
196
230
  # Handle raw data queries.
197
- if path.startswith("/json"):
231
+ if path_has_part(request.target.path):
198
232
  json_handler(
199
233
  stream,
200
234
  request,
@@ -73,6 +73,11 @@ async def setup(app: AppInfo) -> int:
73
73
  RuntimepyServerConnection.apps["/app.html"] = web_app
74
74
  RuntimepyServerConnection.default_app = web_app
75
75
 
76
+ # Register redirects.
77
+ redirects: dict[str, str] = app.config_param("http_redirects", {})
78
+ for key, val in redirects.items():
79
+ RuntimepyServerConnection.add_redirect_path(val, key)
80
+
76
81
  # Register custom applications.
77
82
  for key, app_method in APPS.items():
78
83
  app_cfg: dict[str, Any] = app.config_param(key, {})
@@ -52,10 +52,9 @@ class WebApplication:
52
52
  def populate(self, document: Html, app: TabPopulater) -> None:
53
53
  """Populate the body element with the application."""
54
54
 
55
- # Third-party dependencies.
55
+ # CSS.
56
+ append_kind(document.head, "font", kind="css", tag="style")
56
57
  add_bootstrap_css(document.head)
57
-
58
- # Internal CSS.
59
58
  append_kind(
60
59
  document.head, "main", "bootstrap_extra", kind="css", tag="style"
61
60
  )
@@ -50,6 +50,9 @@ def create_name_td(parent: Element) -> Element:
50
50
  return div(tag="td", parent=parent, class_str="p-0 text-nowrap")
51
51
 
52
52
 
53
+ COMMANDABLE = "text-info-emphasis"
54
+
55
+
53
56
  class ChannelEnvironmentTabHtml(ChannelEnvironmentTabControls):
54
57
  """A channel-environment tab interface."""
55
58
 
@@ -67,7 +70,7 @@ class ChannelEnvironmentTabHtml(ChannelEnvironmentTabControls):
67
70
 
68
71
  name_elem = div(tag="span", text=name, parent=name_td)
69
72
  if chan.commandable:
70
- name_elem.add_class("text-success")
73
+ name_elem.add_class(COMMANDABLE)
71
74
 
72
75
  if description:
73
76
  set_tooltip(name_elem, description, placement="left")
@@ -105,7 +108,7 @@ class ChannelEnvironmentTabHtml(ChannelEnvironmentTabControls):
105
108
 
106
109
  name_elem = div(tag="span", text=name, parent=name_td)
107
110
  if field.commandable:
108
- name_elem.add_class("text-success")
111
+ name_elem.add_class(COMMANDABLE)
109
112
 
110
113
  if field.description:
111
114
  description = field.description
@@ -13,6 +13,7 @@ from vcorelib.io import ARBITER, JsonObject
13
13
  # internal
14
14
  from runtimepy.net.http.header import RequestHeader
15
15
  from runtimepy.net.http.response import ResponseHeader
16
+ from runtimepy.util import parse_path_parts
16
17
 
17
18
 
18
19
  class Encoder(JSONEncoder):
@@ -94,7 +95,7 @@ def json_handler(
94
95
  del request_data
95
96
 
96
97
  # Traverse path.
97
- data = traverse_dict(data, *request.target.path.split("/")[2:])
98
+ data = traverse_dict(data, *parse_path_parts(request.target.path))
98
99
 
99
100
  # Use a convention for indexing data to non-dictionary leaf nodes.
100
101
  if not isinstance(data, dict):
runtimepy/util.py CHANGED
@@ -2,6 +2,25 @@
2
2
  A module implementing package utilities.
3
3
  """
4
4
 
5
+ # built-in
6
+ from os import sep
7
+ from pathlib import Path
8
+ from typing import Iterator, Union
9
+
10
+ # third-party
11
+ from vcorelib.paths import normalize
12
+
13
+ ROOT_PATH = Path(sep)
14
+
15
+
16
+ def normalize_root(*src_parts: Union[str, Path]) -> Path:
17
+ """Make paths absolute that aren't. Useful for HTTP-request pathing."""
18
+
19
+ result = normalize(*src_parts)
20
+ if not result.is_absolute():
21
+ result = ROOT_PATH.joinpath(result)
22
+ return result
23
+
5
24
 
6
25
  class Identifier:
7
26
  """A simple message indentifier interface."""
@@ -16,3 +35,26 @@ class Identifier:
16
35
  curr = self.curr_id
17
36
  self.curr_id += self.scale
18
37
  return curr
38
+
39
+
40
+ def path_has_part(path: str, key: str = "json") -> bool:
41
+ """Determine if a key appears as a part of a path."""
42
+
43
+ # Ignore '/' component (intended for URI paths).
44
+ return key in path.split("/")[1:]
45
+
46
+
47
+ def parse_path_parts(path: str, key: str = "json") -> Iterator[str]:
48
+ """
49
+ Parse a path such that all parts appearing after a possible 'key' appears
50
+ are yielded.
51
+ """
52
+
53
+ key_found = False
54
+
55
+ # Ignore '/' component (intended for URI paths).
56
+ for item in path.split("/")[1:]:
57
+ if key_found:
58
+ yield item
59
+ elif item == key:
60
+ key_found = True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: runtimepy
3
- Version: 5.7.0
3
+ Version: 5.7.2
4
4
  Summary: A framework for implementing Python services.
5
5
  Home-page: https://github.com/vkottler/runtimepy
6
6
  Author: Vaughn Kottler
@@ -17,11 +17,11 @@ Classifier: License :: OSI Approved :: MIT License
17
17
  Requires-Python: >=3.11
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
- Requires-Dist: svgen >=0.6.8
21
- Requires-Dist: aiofiles
20
+ Requires-Dist: vcorelib >=3.4.2
22
21
  Requires-Dist: websockets
22
+ Requires-Dist: aiofiles
23
23
  Requires-Dist: psutil
24
- Requires-Dist: vcorelib >=3.4.2
24
+ Requires-Dist: svgen >=0.6.8
25
25
  Provides-Extra: test
26
26
  Requires-Dist: pylint ; extra == 'test'
27
27
  Requires-Dist: flake8 ; extra == 'test'
@@ -45,11 +45,11 @@ Requires-Dist: uvloop ; (sys_platform != "win32" and sys_platform != "cygwin") a
45
45
  =====================================
46
46
  generator=datazen
47
47
  version=3.1.4
48
- hash=aa59dcef7f11c767458b14ad97f9de59
48
+ hash=618546df79dd7f387faa6f84f9a58c79
49
49
  =====================================
50
50
  -->
51
51
 
52
- # runtimepy ([5.7.0](https://pypi.org/project/runtimepy/))
52
+ # runtimepy ([5.7.2](https://pypi.org/project/runtimepy/))
53
53
 
54
54
  [![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
55
55
  ![Build Status](https://github.com/vkottler/runtimepy/workflows/Python%20Package/badge.svg)
@@ -1,4 +1,4 @@
1
- runtimepy/__init__.py,sha256=7qUy8p7EC5Gtz7wvmBh-jnZVUn-dIOF6t1tjTI1I9v8,390
1
+ runtimepy/__init__.py,sha256=52lFAvkdOBUthOa7tJ66FInklDlbnSn3q9BoqWKadlY,390
2
2
  runtimepy/__main__.py,sha256=OPAed6hggoQdw-6QAR62mqLC-rCkdDhOq0wyeS2vDRI,332
3
3
  runtimepy/app.py,sha256=sTvatbsGZ2Hdel36Si_WUbNMtg9CzsJyExr5xjIcxDE,970
4
4
  runtimepy/dev_requirements.txt,sha256=j0dh11ztJAzfaUL0iFheGjaZj9ppDzmTkclTT8YKO8c,230
@@ -7,7 +7,7 @@ runtimepy/mapping.py,sha256=VQK1vzmQVvYYKI85_II37-hIEbvgL3PzNy-WI6TTo80,5091
7
7
  runtimepy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  runtimepy/requirements.txt,sha256=77PnkPte9OZyyJg88wF_6su2H4XSvuN8rQH1tibLdv4,124
9
9
  runtimepy/schemas.py,sha256=NROlzVCZGLTJ9xe7d1eNIYmjzf0AOv3qHK-f6g1jGHk,678
10
- runtimepy/util.py,sha256=q1Spqt8AiG8_64COh1fU5cUKl-cZhp8BK1CHw_IOya0,399
10
+ runtimepy/util.py,sha256=1279Ea7CNHa1U_JvUydGAb2oEI2TxilXkq5V1RseCwU,1437
11
11
  runtimepy/channel/__init__.py,sha256=pf0RJ5g37_FVV8xoUNgzFGuIfbZEYSBA_cQlJSDTPDo,4774
12
12
  runtimepy/channel/registry.py,sha256=nk36qM_Bf6qK6AFR0plaZHR1PU7b4LZqbQ0feJqk4lc,4784
13
13
  runtimepy/channel/environment/__init__.py,sha256=0Jj8g7Y4bdDvmWtzpegB9D4milGPhsZokoYxmps5zgU,1612
@@ -44,20 +44,21 @@ runtimepy/control/env/__init__.py,sha256=RHJqysY7Pv4VDs2SGk0X-qc5xp_SrQ_oxb5Deug
44
44
  runtimepy/data/browser.yaml,sha256=oc5KEV1C1uAJ4MkhNo4hyVVfJtZvHelRNqzNvD313Ow,79
45
45
  runtimepy/data/dummy_load.yaml,sha256=89BPHLaHJOgiiZSVACBA0_xmlN_N6v2fpcCauB03ZkE,1830
46
46
  runtimepy/data/factories.yaml,sha256=Jm0QPwW2BQgnj1fIFQwygsWXzT78QJuf7auVRtRzWKQ,1847
47
- runtimepy/data/favicon.ico,sha256=jgGIqM4gTrqPs3I6wajqKUH6Je885zy-jI7eU-Nl3AA,362870
47
+ runtimepy/data/favicon.ico,sha256=iPOtqnqrFVr5tNBM6kTsw7nh0KullEz4TpS6CEQ2HVM,362870
48
48
  runtimepy/data/sample_telemetry.yaml,sha256=OpdFurkvtWJGaNl9LMlU2rKo15AaVVr-U_hoZfsbp-Y,695
49
49
  runtimepy/data/server.yaml,sha256=wS_Ceiu2TpkfPurpqoYoPlgzc9DAWtUd24MW7t-S5rU,97
50
50
  runtimepy/data/server_base.yaml,sha256=QkF1xcHyMEViUhOc5rKFbFXjbRDDDHbX5LXvSQJRS58,615
51
51
  runtimepy/data/server_dev.yaml,sha256=nQsPh7LuQig3pzHfdg_aD3yOUiCj1sKKfI-WwW3hXmQ,523
52
52
  runtimepy/data/tftp_server.yaml,sha256=-bFOWJSagI-fEQQcT8k7eDMJVfSPm2XAxLVG3dqUTa4,204
53
- runtimepy/data/css/bootstrap_extra.css,sha256=la8scLWyYDzAmQV5qh_44PAEX0RMnPP35Kcs9US63sU,1758
53
+ runtimepy/data/css/bootstrap_extra.css,sha256=-clAoiYcyOkS4xana4O-jvGVsphOaYB_VlmX9mUjI80,1796
54
+ runtimepy/data/css/font.css,sha256=Pe82E66rNi-cwlQ-_1GHAuhPGu5L4x5KqgV0dbDe51w,977
54
55
  runtimepy/data/css/main.css,sha256=OSg5g7FYbjsHY7QNbFCTPAD1MlypeoYfaOyAfvnT2kI,680
55
56
  runtimepy/data/js/DataConnection.js,sha256=DnX8FMehjJXqmI62UMYXSvl_XdfQMzq3XUDFbLu2GgI,98
56
57
  runtimepy/data/js/JsonConnection.js,sha256=rclZrbmWc_zSs6I_JhOgxnVPFIyPMo5WdjAe8alyZ3o,2729
57
58
  runtimepy/data/js/audio.js,sha256=bLkBqbeHMiGGidfL3iXjmVoF9seK-ZeZ3kwgOrcpgk4,1092
58
59
  runtimepy/data/js/events.js,sha256=rgz3Q_8J6sfU_7Sa7fG1mZD0pQ4S3vwN2mqcvQfePkM,554
59
60
  runtimepy/data/js/init.js,sha256=IeFqfab7CM2-Z4fIbyGaUD4M2orUT8uLwcVlleQqXzg,1522
60
- runtimepy/data/js/main.js,sha256=r0P_0xx5Czd1jfTjsB-tLfwhp4iPNoajlYC858u0ltc,211
61
+ runtimepy/data/js/main.js,sha256=nYIQ6O76EWqlzwX7oEwPXqC-LCUFCZYDADK9QbYRDKk,404
61
62
  runtimepy/data/js/util.js,sha256=Xc8pHUiFDBDvIqTamWrCYUOpF7iR9VNvPDCSCQAfLDA,1424
62
63
  runtimepy/data/js/worker.js,sha256=V9deGAynjvUr1D-WGi3wUW8rxoaNLvBvayMoLFZk3w0,2444
63
64
  runtimepy/data/js/classes/App.js,sha256=nnY42Q3tlNzf8JZtuGKyxJZLLNMfResdww8svOQMC3U,3402
@@ -104,6 +105,16 @@ runtimepy/data/schemas/has_factory.yaml,sha256=Rsqrxv3HEBUGxPcW6CN7QczA96iBSgtm0
104
105
  runtimepy/data/schemas/has_markdown.yaml,sha256=LbnEQRYdk5KR_GgORmIOiKjRg-HF8wjhA6Dm6pSm66I,45
105
106
  runtimepy/data/schemas/has_name.yaml,sha256=I5YkXxQRYz-1-49CLyr_NA2zVqyRVQCAsb-icTaxF4s,59
106
107
  runtimepy/data/schemas/has_request_flag.yaml,sha256=S8ly8g-FkrCVNEizbXPqicg_hpGvtH7WRsHZAA4uhjc,66
108
+ runtimepy/data/static/svg/chip-circle-bootstrap.svg,sha256=cGCiwiVWoO39vzdAt683Fk3W42XE6-RGT0QZtsDAv4o,3124
109
+ runtimepy/data/static/woff2/CascadiaCode-Bold.woff2,sha256=vnrwH_YbbVnq0_aedSECg-eieky43TOK3MxtCWIc_Ug,154520
110
+ runtimepy/data/static/woff2/CascadiaCode-BoldItalic.woff2,sha256=OOWBMRXRJJKxEfEIlKKnT-tFqoZKqGw5hMa69t-gp1c,113236
111
+ runtimepy/data/static/woff2/CascadiaCode-Italic.woff2,sha256=RbBc8ehMSl_ixGWnEe7zn841xDsyxdDJTo3rkYY-bf8,111628
112
+ runtimepy/data/static/woff2/CascadiaCode-Regular.woff2,sha256=n0sjuK3zmAMLxahwrTJ1sApEHp9pbJb_zUrENr3Wetk,152304
113
+ runtimepy/data/static/woff2/CascadiaMono-Bold.woff2,sha256=pxV93LGT3ZVLA_WmSVFtHC3DqvDt0krcPbOS8u3LhGs,145952
114
+ runtimepy/data/static/woff2/CascadiaMono-BoldItalic.woff2,sha256=CwE1OsdCYTPqdWxKWYGOPn_z1P3Lh298MbEIgWv9voY,106232
115
+ runtimepy/data/static/woff2/CascadiaMono-Italic.woff2,sha256=S31PimDgq0GV7XMRV-YXeBA9gC54Wz9ukdAzw1nrc8g,104768
116
+ runtimepy/data/static/woff2/CascadiaMono-Regular.woff2,sha256=hHPAFO0U10TCKBw-UofHN2BLjax9qNClzN9oWGKkQx0,143936
117
+ runtimepy/data/static/woff2/README.md,sha256=flHwSRmDxd6OnWhzxmnXzwio1Mong5tB4d8VgieWCOs,289
107
118
  runtimepy/enum/__init__.py,sha256=WIBMOaogauR1u7mK-I4Z5BZUoWANU7alIlrz82QdCmY,5820
108
119
  runtimepy/enum/registry.py,sha256=EU7oUejI60kzrhdtzgWpnFYP8h4CFLy_fxvGTwq1Uvc,2631
109
120
  runtimepy/enum/types.py,sha256=uQYGvaAJVm5tUdwxn_SLHkTZHJpEf7364rTSL27necA,1027
@@ -160,11 +171,11 @@ runtimepy/net/http/request_target.py,sha256=EE1aI5VSARw1h93jyZvP56ir5O5fjd6orYK-
160
171
  runtimepy/net/http/response.py,sha256=Sup8W_A0ADNzR5olKrQsVNhsQXUwPOD-eJLlLOgYlAY,2316
161
172
  runtimepy/net/http/state.py,sha256=qCMN8aWfCRfU9XP-cIhSOo2RqfljTjbQRCflfcy2bfY,1626
162
173
  runtimepy/net/http/version.py,sha256=mp6rgIM7-VUVKLCA0Uw96CmBkL0ET860lDVVEewpZ7w,1098
163
- runtimepy/net/server/__init__.py,sha256=J8gl91YltD8Wo2y_AXxaL6liLu3vomfzUz_nULa3e2Y,6707
174
+ runtimepy/net/server/__init__.py,sha256=sxAOQc6jywBYqqZOCuq_jRJMVoA0ZFaFy2hDpgoOtSs,7845
164
175
  runtimepy/net/server/html.py,sha256=xaTGelH4zrwndQjU24kbCj9Yqu-D17nK5682P6xa-cU,1153
165
- runtimepy/net/server/json.py,sha256=RfNt7Gr4-X5DMinV1UeiWneTIJr0LO6BXo2GzE0C1PQ,2475
166
- runtimepy/net/server/app/__init__.py,sha256=9gJr7qcrJNQacAOFpZLfpnzDHzx5KXBMNxPlqQsdwB8,2790
167
- runtimepy/net/server/app/base.py,sha256=1KMEWCwDf3cducIbt9geTmMwugAMKl1Io2sBr6qajo4,2082
176
+ runtimepy/net/server/json.py,sha256=a7vM5yfq2er4DexzFqEMnxoMGDeuywKkVH4-uNJBAik,2522
177
+ runtimepy/net/server/app/__init__.py,sha256=Q5NWlAkIZE2oEHkGdILFyQoX1Fw1lMR1lVQyMVkJ_Hc,2989
178
+ runtimepy/net/server/app/base.py,sha256=9PnonII2qZIf1O9BQ8T-wOAgAVHctpLqyZkWGX2M2r4,2104
168
179
  runtimepy/net/server/app/create.py,sha256=N-g3kClBsG4pKOd9tx947rOq4sfgrH_FAMVfZacjhFA,2666
169
180
  runtimepy/net/server/app/elements.py,sha256=KJt9vWqkfvniJMiLOJN467JjPPrEqJYZXmDuY1JoY1g,455
170
181
  runtimepy/net/server/app/files.py,sha256=cIHtIKqaVvOpKL62LSVV1IRPdUyCRCg0TOX9XXmYtqk,2903
@@ -183,7 +194,7 @@ runtimepy/net/server/app/env/widgets.py,sha256=_kNvPl7MXnZOiwTjoZiU2hfuSjkLnRUrO
183
194
  runtimepy/net/server/app/env/tab/__init__.py,sha256=stTVKyHljLQWnnhxkWPwa7bLdZtjhiMFbiVFgbiYaFI,647
184
195
  runtimepy/net/server/app/env/tab/base.py,sha256=hcHKG17JGkAZjl2X7jT1B72RHTeMdocTakFyNKkmWJc,1168
185
196
  runtimepy/net/server/app/env/tab/controls.py,sha256=hsj0ErywfmOBtJLNZbMISrE2ELJEfyXvtCtpsDbXlYg,4734
186
- runtimepy/net/server/app/env/tab/html.py,sha256=lF7W9zwxgQa-EPWi49lcM0gNVrlXcGjjUjdFyt_BtMQ,7099
197
+ runtimepy/net/server/app/env/tab/html.py,sha256=wjG_hhuJVeN4xWpGTyQF-TLKmMxc31nfe0zU4wU99S8,7130
187
198
  runtimepy/net/server/app/env/tab/message.py,sha256=OWqBIPRt6UdBHAXk5qvFMbnWuvIRUyp34lzb3GYdthk,4070
188
199
  runtimepy/net/server/struct/__init__.py,sha256=Zy37r6RLFu-XFr9vsanSq80BJdS6Dxr7zmPzQbb7xdw,1799
189
200
  runtimepy/net/server/websocket/__init__.py,sha256=KISuFUUQwNn6BXo8BOMuMOXyoVqE7Jw94ZQiSCQuRQE,5279
@@ -269,9 +280,9 @@ runtimepy/tui/task.py,sha256=nUZo9fuOC-k1Wpqdzkv9v1tQirCI28fZVgcC13Ijvus,1093
269
280
  runtimepy/tui/channels/__init__.py,sha256=evDaiIn-YS9uGhdo8ZGtP9VK1ek6sr_P1nJ9JuSET0o,4536
270
281
  runtimepy/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
271
282
  runtimepy/ui/controls.py,sha256=yvT7h3thbYaitsakcIAJ90EwKzJ4b-jnc6p3UuVf_XE,1241
272
- runtimepy-5.7.0.dist-info/LICENSE,sha256=okYCYhGsx_BlzvFdoNVBVpw_Cfb4SOqHA_VAARml4Hc,1071
273
- runtimepy-5.7.0.dist-info/METADATA,sha256=0gGgcxU2Cl_nKgBLgU8Y2RLsE39Iy3Bo_gycEbfvjgc,9308
274
- runtimepy-5.7.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
275
- runtimepy-5.7.0.dist-info/entry_points.txt,sha256=-btVBkYv7ybcopqZ_pRky-bEzu3vhbaG3W3Z7ERBiFE,51
276
- runtimepy-5.7.0.dist-info/top_level.txt,sha256=0jPmh6yqHyyJJDwEID-LpQly-9kQ3WRMjH7Lix8peLg,10
277
- runtimepy-5.7.0.dist-info/RECORD,,
283
+ runtimepy-5.7.2.dist-info/LICENSE,sha256=okYCYhGsx_BlzvFdoNVBVpw_Cfb4SOqHA_VAARml4Hc,1071
284
+ runtimepy-5.7.2.dist-info/METADATA,sha256=alklDGCCJxGdAWxIyShsmg-yZJlbN_arrXDTnMG3QaQ,9308
285
+ runtimepy-5.7.2.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
286
+ runtimepy-5.7.2.dist-info/entry_points.txt,sha256=-btVBkYv7ybcopqZ_pRky-bEzu3vhbaG3W3Z7ERBiFE,51
287
+ runtimepy-5.7.2.dist-info/top_level.txt,sha256=0jPmh6yqHyyJJDwEID-LpQly-9kQ3WRMjH7Lix8peLg,10
288
+ runtimepy-5.7.2.dist-info/RECORD,,