@pyscript/core 0.7.13 → 0.7.15

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 (42) hide show
  1. package/dist/{codemirror-lkW_eC9r.js → codemirror-BIjK0FyF.js} +2 -2
  2. package/dist/{codemirror-lkW_eC9r.js.map → codemirror-BIjK0FyF.js.map} +1 -1
  3. package/dist/{codemirror_commands-DL2aL4qa.js → codemirror_commands-Ot159sys.js} +2 -2
  4. package/dist/{codemirror_commands-DL2aL4qa.js.map → codemirror_commands-Ot159sys.js.map} +1 -1
  5. package/dist/{codemirror_lang-python-DD5EtV36.js → codemirror_lang-python-BrxzY-1G.js} +2 -2
  6. package/dist/{codemirror_lang-python-DD5EtV36.js.map → codemirror_lang-python-BrxzY-1G.js.map} +1 -1
  7. package/dist/{codemirror_language-DRHeqAwG.js → codemirror_language-CGuBIifm.js} +2 -2
  8. package/dist/{codemirror_language-DRHeqAwG.js.map → codemirror_language-CGuBIifm.js.map} +1 -1
  9. package/dist/{codemirror_view-FN7LalDk.js → codemirror_view-C_m1bYT7.js} +2 -2
  10. package/dist/{codemirror_view-FN7LalDk.js.map → codemirror_view-C_m1bYT7.js.map} +1 -1
  11. package/dist/core-uXjUCyYJ.js +4 -0
  12. package/dist/core-uXjUCyYJ.js.map +1 -0
  13. package/dist/core.js +1 -1
  14. package/dist/{deprecations-manager-BRHTwqUZ.js → deprecations-manager-9ZyrTvDd.js} +2 -2
  15. package/dist/{deprecations-manager-BRHTwqUZ.js.map → deprecations-manager-9ZyrTvDd.js.map} +1 -1
  16. package/dist/{donkey-CBEqGHeD.js → donkey-BT724r9p.js} +2 -2
  17. package/dist/{donkey-CBEqGHeD.js.map → donkey-BT724r9p.js.map} +1 -1
  18. package/dist/{error-DRVc1NKK.js → error-M0noMyk4.js} +2 -2
  19. package/dist/{error-DRVc1NKK.js.map → error-M0noMyk4.js.map} +1 -1
  20. package/dist/{index-C-U2wRvV.js → index-DM-nsZEM.js} +2 -2
  21. package/dist/{index-C-U2wRvV.js.map → index-DM-nsZEM.js.map} +1 -1
  22. package/dist/{mpy-B-jI5Qug.js → mpy-C-mFwLd4.js} +2 -2
  23. package/dist/{mpy-B-jI5Qug.js.map → mpy-C-mFwLd4.js.map} +1 -1
  24. package/dist/{py-DNLpCVR2.js → py-CCtvrzWS.js} +2 -2
  25. package/dist/{py-DNLpCVR2.js.map → py-CCtvrzWS.js.map} +1 -1
  26. package/dist/{py-editor-DCtATRBs.js → py-editor-DiFcvRlU.js} +2 -2
  27. package/dist/{py-editor-DCtATRBs.js.map → py-editor-DiFcvRlU.js.map} +1 -1
  28. package/dist/{py-game-BGWt8dH1.js → py-game-2v7HaC-d.js} +2 -2
  29. package/dist/{py-game-BGWt8dH1.js.map → py-game-2v7HaC-d.js.map} +1 -1
  30. package/dist/{py-terminal-BKvzGq7q.js → py-terminal-C8V2KXpf.js} +2 -2
  31. package/dist/{py-terminal-BKvzGq7q.js.map → py-terminal-C8V2KXpf.js.map} +1 -1
  32. package/dist/toml-DCqPSmRg.js +3 -0
  33. package/dist/toml-DCqPSmRg.js.map +1 -0
  34. package/dist/zip-CgZGjqjF.js.map +1 -1
  35. package/package.json +3 -3
  36. package/src/core.js +174 -186
  37. package/src/stdlib/pyscript/context.py +4 -1
  38. package/src/stdlib/pyscript.js +1 -1
  39. package/dist/core-B4BRXuDy.js +0 -4
  40. package/dist/core-B4BRXuDy.js.map +0 -1
  41. package/dist/toml-BK2RWy-G.js +0 -3
  42. package/dist/toml-BK2RWy-G.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyscript/core",
3
- "version": "0.7.13",
3
+ "version": "0.7.15",
4
4
  "type": "module",
5
5
  "description": "PyScript",
6
6
  "module": "./index.js",
@@ -71,7 +71,7 @@
71
71
  "@webreflection/utils": "^0.1.1",
72
72
  "add-promise-listener": "^0.1.3",
73
73
  "basic-devtools": "^0.1.6",
74
- "polyscript": "^0.20.4",
74
+ "polyscript": "^0.20.6",
75
75
  "sticky-module": "^0.1.1",
76
76
  "to-json-callback": "^0.1.1",
77
77
  "type-checked-collections": "^0.1.7"
@@ -96,7 +96,7 @@
96
96
  "codemirror": "^6.0.2",
97
97
  "eslint": "^9.39.2",
98
98
  "flatted": "^3.3.3",
99
- "rollup": "^4.55.3",
99
+ "rollup": "^4.56.0",
100
100
  "rollup-plugin-postcss": "^4.0.2",
101
101
  "rollup-plugin-string": "^3.0.0",
102
102
  "static-handler": "^0.5.3",
package/src/core.js CHANGED
@@ -180,201 +180,189 @@ for (const [TYPE, interpreter] of TYPES) {
180
180
  });
181
181
  };
182
182
 
183
- // define the module as both `<script type="py">` and `<py-script>`
184
- // but only if the config didn't throw an error
185
- if (!error) {
186
- // ensure plugins are bootstrapped already before custom type definition
187
- // NOTE: we cannot top-level await in here as plugins import other utilities
188
- // from core.js itself so that custom definition should not be blocking.
189
- plugins().then(() => {
190
- // possible early errors sent by polyscript
191
- const errors = new Map();
192
-
193
- // specific main and worker hooks
194
- const hooks = {
195
- main: {
196
- ...codeFor(main, TYPE),
197
- async onReady(wrap, element) {
198
- registerModule(wrap);
199
-
200
- // allows plugins to do whatever they want with the element
201
- // before regular stuff happens in here
202
- for (const callback of main("onReady"))
203
- await callback(wrap, element);
204
-
205
- // now that all possible plugins are configured,
206
- // bail out if polyscript encountered an error
207
- if (errors.has(element)) {
208
- let { message } = errors.get(element);
209
- errors.delete(element);
210
- const clone = message === INVALID_CONTENT;
211
- message = `(${ErrorCode.CONFLICTING_CODE}) ${message} for `;
212
- message += element.cloneNode(clone).outerHTML;
213
- wrap.io.stderr(message);
214
- return;
215
- }
183
+ // ensure plugins are bootstrapped already before custom type definition
184
+ // NOTE: we cannot top-level await in here as plugins import other utilities
185
+ // from core.js itself so that custom definition should not be blocking.
186
+ plugins().then(() => {
187
+ // let plugins logic decide how to show the error but stop here if any
188
+ if (error) return;
189
+
190
+ // possible early errors sent by polyscript
191
+ const errors = new Map();
192
+
193
+ // specific main and worker hooks
194
+ const hooks = {
195
+ main: {
196
+ ...codeFor(main, TYPE),
197
+ async onReady(wrap, element) {
198
+ registerModule(wrap);
199
+
200
+ // allows plugins to do whatever they want with the element
201
+ // before regular stuff happens in here
202
+ for (const callback of main("onReady"))
203
+ await callback(wrap, element);
204
+
205
+ // now that all possible plugins are configured,
206
+ // bail out if polyscript encountered an error
207
+ if (errors.has(element)) {
208
+ let { message } = errors.get(element);
209
+ errors.delete(element);
210
+ const clone = message === INVALID_CONTENT;
211
+ message = `(${ErrorCode.CONFLICTING_CODE}) ${message} for `;
212
+ message += element.cloneNode(clone).outerHTML;
213
+ wrap.io.stderr(message);
214
+ return;
215
+ }
216
216
 
217
- if (isScript(element)) {
218
- const isAsync = !isSync(element);
219
- const target = element.getAttribute("target");
220
- const show = target
221
- ? queryTarget(element, target)
222
- : document.createElement("script-py");
223
-
224
- if (!target) {
225
- const { head, body } = document;
226
- if (head.contains(element)) body.append(show);
227
- else element.after(show);
228
- }
229
- if (!show.id) show.id = getID();
230
-
231
- // allows the code to retrieve the target element via
232
- // document.currentScript.target if needed
233
- defineProperty(element, "target", { value: show });
234
-
235
- // notify before the code runs
236
- dispatch(element, TYPE, "ready");
237
- dispatchDone(
238
- element,
239
- isAsync,
240
- wrap[`run${isAsync ? "Async" : ""}`](
241
- await fetchSource(element, wrap.io, true),
242
- ),
243
- );
244
- } else {
245
- // resolve PyScriptElement to allow connectedCallback
246
- element._wrap.resolve(wrap);
217
+ if (isScript(element)) {
218
+ const isAsync = !isSync(element);
219
+ const target = element.getAttribute("target");
220
+ const show = target
221
+ ? queryTarget(element, target)
222
+ : document.createElement("script-py");
223
+
224
+ if (!target) {
225
+ const { head, body } = document;
226
+ if (head.contains(element)) body.append(show);
227
+ else element.after(show);
247
228
  }
248
- console.debug("[pyscript/main] PyScript Ready");
249
- },
250
- onWorker(_, xworker) {
251
- assign(xworker.sync, sync);
252
- for (const callback of main("onWorker"))
253
- callback(_, xworker);
254
- },
255
- onBeforeRun(wrap, element) {
256
- currentElement = element;
257
- bootstrapNodeAndPlugins(
258
- main,
259
- wrap,
260
- element,
261
- "onBeforeRun",
262
- );
263
- },
264
- onBeforeRunAsync(wrap, element) {
265
- currentElement = element;
266
- return bootstrapNodeAndPlugins(
267
- main,
268
- wrap,
269
- element,
270
- "onBeforeRunAsync",
271
- );
272
- },
273
- onAfterRun(wrap, element) {
274
- bootstrapNodeAndPlugins(
275
- main,
276
- wrap,
277
- element,
278
- "onAfterRun",
279
- );
280
- },
281
- onAfterRunAsync(wrap, element) {
282
- return bootstrapNodeAndPlugins(
283
- main,
284
- wrap,
229
+ if (!show.id) show.id = getID();
230
+
231
+ // allows the code to retrieve the target element via
232
+ // document.currentScript.target if needed
233
+ defineProperty(element, "target", { value: show });
234
+
235
+ // notify before the code runs
236
+ dispatch(element, TYPE, "ready");
237
+ dispatchDone(
285
238
  element,
286
- "onAfterRunAsync",
239
+ isAsync,
240
+ wrap[`run${isAsync ? "Async" : ""}`](
241
+ await fetchSource(element, wrap.io, true),
242
+ ),
287
243
  );
288
- },
244
+ } else {
245
+ // resolve PyScriptElement to allow connectedCallback
246
+ element._wrap.resolve(wrap);
247
+ }
248
+ console.debug("[pyscript/main] PyScript Ready");
289
249
  },
290
- worker: {
291
- ...codeFor(worker, TYPE),
292
- // these are lazy getters that returns a composition
293
- // of the current hooks or undefined, if no hook is present
294
- get onReady() {
295
- return createFunction(this, "onReady", true);
296
- },
297
- get onBeforeRun() {
298
- return createFunction(this, "onBeforeRun", false);
299
- },
300
- get onBeforeRunAsync() {
301
- return createFunction(this, "onBeforeRunAsync", true);
302
- },
303
- get onAfterRun() {
304
- return createFunction(this, "onAfterRun", false);
305
- },
306
- get onAfterRunAsync() {
307
- return createFunction(this, "onAfterRunAsync", true);
308
- },
250
+ onWorker(_, xworker) {
251
+ assign(xworker.sync, sync);
252
+ for (const callback of main("onWorker"))
253
+ callback(_, xworker);
309
254
  },
310
- };
311
-
312
- hooked.set(TYPE, hooks);
313
-
314
- // allow offline interpreter detection via [offline] attribute
315
- let version = offline_interpreter(config);
316
- if (!version) {
317
- const css = "script[type='module'][offline]";
318
- const s = document.querySelector(css)?.src;
319
- if (s && import.meta.url.startsWith(s.replace(/\.js$/, ""))) {
320
- version = `./pyscript/${interpreter}/${interpreter}.mjs`;
321
- version = offline_interpreter({ interpreter: version });
322
- }
323
- }
324
-
325
- define(TYPE, {
326
- config,
327
- configURL,
328
- interpreter,
329
- hooks,
330
- version,
331
- env: `${TYPE}-script`,
332
- onerror(error, element) {
333
- errors.set(element, error);
255
+ onBeforeRun(wrap, element) {
256
+ currentElement = element;
257
+ bootstrapNodeAndPlugins(main, wrap, element, "onBeforeRun");
334
258
  },
335
- });
336
-
337
- customElements.define(
338
- `${TYPE}-script`,
339
- class extends HTMLElement {
340
- constructor() {
341
- assign(super(), {
342
- _wrap: withResolvers(),
343
- srcCode: "",
344
- executed: false,
345
- });
346
- }
347
- get id() {
348
- return super.id || (super.id = getID());
349
- }
350
- set id(value) {
351
- super.id = value;
352
- }
353
- async connectedCallback() {
354
- if (!this.executed) {
355
- this.executed = true;
356
- const isAsync = !isSync(this);
357
- const { io, run, runAsync } = await this._wrap
358
- .promise;
359
- this.srcCode = await fetchSource(
360
- this,
361
- io,
362
- !this.childElementCount,
363
- );
364
- this.replaceChildren();
365
- this.style.display = "block";
366
- dispatch(this, TYPE, "ready");
367
- dispatchDone(
368
- this,
369
- isAsync,
370
- (isAsync ? runAsync : run)(this.srcCode),
371
- );
372
- }
373
- }
259
+ onBeforeRunAsync(wrap, element) {
260
+ currentElement = element;
261
+ return bootstrapNodeAndPlugins(
262
+ main,
263
+ wrap,
264
+ element,
265
+ "onBeforeRunAsync",
266
+ );
374
267
  },
375
- );
268
+ onAfterRun(wrap, element) {
269
+ bootstrapNodeAndPlugins(main, wrap, element, "onAfterRun");
270
+ },
271
+ onAfterRunAsync(wrap, element) {
272
+ return bootstrapNodeAndPlugins(
273
+ main,
274
+ wrap,
275
+ element,
276
+ "onAfterRunAsync",
277
+ );
278
+ },
279
+ },
280
+ worker: {
281
+ ...codeFor(worker, TYPE),
282
+ // these are lazy getters that returns a composition
283
+ // of the current hooks or undefined, if no hook is present
284
+ get onReady() {
285
+ return createFunction(this, "onReady", true);
286
+ },
287
+ get onBeforeRun() {
288
+ return createFunction(this, "onBeforeRun", false);
289
+ },
290
+ get onBeforeRunAsync() {
291
+ return createFunction(this, "onBeforeRunAsync", true);
292
+ },
293
+ get onAfterRun() {
294
+ return createFunction(this, "onAfterRun", false);
295
+ },
296
+ get onAfterRunAsync() {
297
+ return createFunction(this, "onAfterRunAsync", true);
298
+ },
299
+ },
300
+ };
301
+
302
+ hooked.set(TYPE, hooks);
303
+
304
+ // allow offline interpreter detection via [offline] attribute
305
+ let version = offline_interpreter(config);
306
+ if (!version) {
307
+ const css = "script[type='module'][offline]";
308
+ const s = document.querySelector(css)?.src;
309
+ if (s && import.meta.url.startsWith(s.replace(/\.js$/, ""))) {
310
+ version = `./pyscript/${interpreter}/${interpreter}.mjs`;
311
+ version = offline_interpreter({ interpreter: version });
312
+ }
313
+ }
314
+
315
+ define(TYPE, {
316
+ config,
317
+ configURL,
318
+ interpreter,
319
+ hooks,
320
+ version,
321
+ env: `${TYPE}-script`,
322
+ onerror(error, element) {
323
+ errors.set(element, error);
324
+ },
376
325
  });
377
- }
326
+
327
+ customElements.define(
328
+ `${TYPE}-script`,
329
+ class extends HTMLElement {
330
+ constructor() {
331
+ assign(super(), {
332
+ _wrap: withResolvers(),
333
+ srcCode: "",
334
+ executed: false,
335
+ });
336
+ }
337
+ get id() {
338
+ return super.id || (super.id = getID());
339
+ }
340
+ set id(value) {
341
+ super.id = value;
342
+ }
343
+ async connectedCallback() {
344
+ if (!this.executed) {
345
+ this.executed = true;
346
+ const isAsync = !isSync(this);
347
+ const { io, run, runAsync } = await this._wrap.promise;
348
+ this.srcCode = await fetchSource(
349
+ this,
350
+ io,
351
+ !this.childElementCount,
352
+ );
353
+ this.replaceChildren();
354
+ this.style.display = "block";
355
+ dispatch(this, TYPE, "ready");
356
+ dispatchDone(
357
+ this,
358
+ isAsync,
359
+ (isAsync ? runAsync : run)(this.srcCode),
360
+ );
361
+ }
362
+ }
363
+ },
364
+ );
365
+ });
378
366
 
379
367
  // export the used config without allowing leaks through it
380
368
  exportedConfig[TYPE] = structuredClone(config);
@@ -139,7 +139,10 @@ if RUNNING_IN_WORKER:
139
139
  "This requires SharedArrayBuffer support. "
140
140
  "See: https://docs.pyscript.net/latest/faq/#sharedarraybuffer"
141
141
  )
142
- js.console.warn(sab_error_message)
142
+
143
+ if not config.get("sync_main_only", False):
144
+ js.console.warn(sab_error_message)
145
+
143
146
  window = NotSupported("pyscript.window", sab_error_message)
144
147
  document = NotSupported("pyscript.document", sab_error_message)
145
148
 
@@ -2,7 +2,7 @@
2
2
  export default {
3
3
  "pyscript": {
4
4
  "__init__.py": "from polyscript import lazy_py_modules as py_import\nfrom pyscript.context import RUNNING_IN_WORKER,PyWorker,config,current_target,document,js_import,js_modules,sync,window\nfrom pyscript.display import HTML,display\nfrom pyscript.fetch import fetch\nfrom pyscript.storage import Storage,storage\nfrom pyscript.websocket import WebSocket\nfrom pyscript.events import when,Event\nif not RUNNING_IN_WORKER:from pyscript.workers import create_named_worker,workers",
5
- "context.py": "_A=None\nimport json,sys,js\nfrom polyscript import config as _polyscript_config,js_modules\nfrom pyscript.util import NotSupported\nRUNNING_IN_WORKER=not hasattr(js,'document')\nconfig=json.loads(js.JSON.stringify(_polyscript_config))\nif isinstance(config,str):config={}\njs_import=_A\nwindow=_A\ndocument=_A\nsync=_A\nif'MicroPython'in sys.version:config['type']='mpy'\nelse:config['type']='py'\nclass _JSModuleProxy:\n\tdef __init__(A,name):A.name=name\n\tdef __getattr__(B,field):\n\t\tA=field\n\t\tif not A.startswith('_'):return getattr(getattr(js_modules,B.name),A)\nfor module_name in js.Reflect.ownKeys(js_modules):sys.modules[f\"pyscript.js_modules.{module_name}\"]=_JSModuleProxy(module_name)\nsys.modules['pyscript.js_modules']=js_modules\nif RUNNING_IN_WORKER:\n\timport polyscript;PyWorker=NotSupported('pyscript.PyWorker','pyscript.PyWorker works only when running in the main thread')\n\ttry:window=polyscript.xworker.window;document=window.document;js.document=document;js_import=window.Function('return (...urls) => Promise.all(urls.map((url) => import(url)))')()\n\texcept:sab_error_message='Unable to use `window` or `document` in worker. This requires SharedArrayBuffer support. See: https://docs.pyscript.net/latest/faq/#sharedarraybuffer';js.console.warn(sab_error_message);window=NotSupported('pyscript.window',sab_error_message);document=NotSupported('pyscript.document',sab_error_message)\n\tsync=polyscript.xworker.sync\n\tdef current_target():return polyscript.target\nelse:\n\timport _pyscript;from _pyscript import PyWorker as _PyWorker;from pyscript.ffi import to_js;js_import=_pyscript.js_import\n\tdef PyWorker(url,**A):return _PyWorker(url,to_js(A))\n\twindow=js;document=js.document;sync=NotSupported('pyscript.sync','pyscript.sync works only when running in a worker')\n\tdef current_target():return _pyscript.target",
5
+ "context.py": "_A=None\nimport json,sys,js\nfrom polyscript import config as _polyscript_config,js_modules\nfrom pyscript.util import NotSupported\nRUNNING_IN_WORKER=not hasattr(js,'document')\nconfig=json.loads(js.JSON.stringify(_polyscript_config))\nif isinstance(config,str):config={}\njs_import=_A\nwindow=_A\ndocument=_A\nsync=_A\nif'MicroPython'in sys.version:config['type']='mpy'\nelse:config['type']='py'\nclass _JSModuleProxy:\n\tdef __init__(A,name):A.name=name\n\tdef __getattr__(B,field):\n\t\tA=field\n\t\tif not A.startswith('_'):return getattr(getattr(js_modules,B.name),A)\nfor module_name in js.Reflect.ownKeys(js_modules):sys.modules[f\"pyscript.js_modules.{module_name}\"]=_JSModuleProxy(module_name)\nsys.modules['pyscript.js_modules']=js_modules\nif RUNNING_IN_WORKER:\n\timport polyscript;PyWorker=NotSupported('pyscript.PyWorker','pyscript.PyWorker works only when running in the main thread')\n\ttry:window=polyscript.xworker.window;document=window.document;js.document=document;js_import=window.Function('return (...urls) => Promise.all(urls.map((url) => import(url)))')()\n\texcept:\n\t\tsab_error_message='Unable to use `window` or `document` in worker. This requires SharedArrayBuffer support. See: https://docs.pyscript.net/latest/faq/#sharedarraybuffer'\n\t\tif not config.get('sync_main_only',False):js.console.warn(sab_error_message)\n\t\twindow=NotSupported('pyscript.window',sab_error_message);document=NotSupported('pyscript.document',sab_error_message)\n\tsync=polyscript.xworker.sync\n\tdef current_target():return polyscript.target\nelse:\n\timport _pyscript;from _pyscript import PyWorker as _PyWorker;from pyscript.ffi import to_js;js_import=_pyscript.js_import\n\tdef PyWorker(url,**A):return _PyWorker(url,to_js(A))\n\twindow=js;document=js.document;sync=NotSupported('pyscript.sync','pyscript.sync works only when running in a worker')\n\tdef current_target():return _pyscript.target",
6
6
  "display.py": "_I='__repr__'\n_H='savefig'\n_G='application/json'\n_F='image/svg+xml'\n_E='application/javascript'\n_D='image/jpeg'\n_C='text/html'\n_B='image/png'\n_A='text/plain'\nimport base64,html,io\nfrom collections import OrderedDict\nfrom pyscript.context import current_target,document,window\nfrom pyscript.ffi import is_none\ndef _render_image(mime,value,meta):\n\tA=value\n\tif isinstance(A,bytes):A=base64.b64encode(A).decode('utf-8')\n\tB=''.join([f' {A}=\"{B}\"'for(A,B)in meta.items()]);return f'<img src=\"data:{mime};base64,{A}\"{B}>'\n_MIME_TO_RENDERERS={_A:lambda v,m:html.escape(v),_C:lambda v,m:v,_B:lambda v,m:_render_image(_B,v,m),_D:lambda v,m:_render_image(_D,v,m),_F:lambda v,m:v,_G:lambda v,m:v,_E:lambda v,m:f\"<script>{v}<\\\\/script>\"}\n_METHOD_TO_MIME=OrderedDict([(_H,_B),('_repr_png_',_B),('_repr_jpeg_',_D),('_repr_svg_',_F),('_repr_html_',_C),('_repr_json_',_G),('_repr_javascript_',_E),(_I,_A)])\nclass HTML:\n\tdef __init__(A,html):A._html=html\n\tdef _repr_html_(A):return A._html\ndef _get_representation(obj,method):\n\tB=method;A=obj\n\tif B==_I:return repr(A)\n\tif not hasattr(A,B):return\n\tif B==_H:C=io.BytesIO();A.savefig(C,format='png');C.seek(0);return base64.b64encode(C.read()).decode('utf-8')\n\treturn getattr(A,B)()\ndef _get_content_and_mime(obj):\n\tC=obj\n\tif isinstance(C,str):return html.escape(C),_A\n\tE=_get_representation(C,'_repr_mimebundle_')\n\tif E:\n\t\tif isinstance(E,tuple):F,G=E\n\t\telse:F,G=E,{}\n\t\tfor(B,A)in F.items():\n\t\t\tif B in _MIME_TO_RENDERERS:\n\t\t\t\tD=G.get(B,{})\n\t\t\t\tif isinstance(A,tuple):A,H=A;D.update(H)\n\t\t\t\treturn _MIME_TO_RENDERERS[B](A,D),B\n\tfor(I,B)in _METHOD_TO_MIME.items():\n\t\tif B not in _MIME_TO_RENDERERS:continue\n\t\tA=_get_representation(C,I)\n\t\tif A is None:continue\n\t\tD={}\n\t\tif isinstance(A,tuple):A,D=A\n\t\treturn _MIME_TO_RENDERERS[B](A,D),B\n\twindow.console.warn(f\"Object {type(C).__name__} has no supported representation method. Using __repr__ as fallback.\");A=repr(C);return html.escape(A),_A\ndef _write_to_dom(element,value,append):\n\tC=element;B,D=_get_content_and_mime(value)\n\tif not B.strip():return\n\tif append:A=document.createElement('div');C.append(A)\n\telse:A=C\n\tif D in(_E,_C):A.append(document.createRange().createContextualFragment(B))\n\telse:A.innerHTML=B\ndef display(*D,target=None,append=True):\n\tC=append;A=target\n\tif isinstance(A,str):A=A[1:]if A.startswith('#')else A\n\telif is_none(A):A=current_target()\n\tB=document.getElementById(A)\n\tif is_none(B):raise ValueError(f\"Cannot find element with id='{A}' in the page.\")\n\tif B.tagName=='SCRIPT'and hasattr(B,'target'):B=B.target\n\tif not C:B.replaceChildren()\n\tfor E in D:_write_to_dom(B,E,C)",
7
7
  "events.py": "import asyncio,inspect\nfrom functools import wraps\nfrom pyscript.context import document\nfrom pyscript.ffi import create_proxy,to_js\nfrom pyscript.util import is_awaitable\nclass Event:\n\tdef __init__(A):A._listeners=[]\n\tdef trigger(C,result):\n\t\tB=result\n\t\tfor A in C._listeners:\n\t\t\tif is_awaitable(A):asyncio.create_task(A(B))\n\t\t\telse:A(B)\n\tdef add_listener(B,listener):\n\t\tA=listener\n\t\tif not callable(A):C='Listener must be callable.';raise ValueError(C)\n\t\tif A not in B._listeners:B._listeners.append(A)\n\tdef remove_listener(A,*B):\n\t\tif B:\n\t\t\tfor C in B:\n\t\t\t\ttry:A._listeners.remove(C)\n\t\t\t\texcept ValueError:pass\n\t\telse:A._listeners=[]\ndef when(event_type,selector=None,**C):\n\tB=selector;A=event_type\n\tif isinstance(A,str):\n\t\tif not B:raise ValueError('Selector required for DOM event handling.')\n\t\tD=_get_elements(B)\n\t\tif not D:raise ValueError(f\"No elements found for selector: {B}\")\n\tdef E(func):\n\t\tB=_create_wrapper(func)\n\t\tif isinstance(A,Event):A.add_listener(B)\n\t\telif isinstance(A,list)and all(isinstance(A,Event)for A in A):\n\t\t\tfor E in A:E.add_listener(B)\n\t\telse:\n\t\t\tfor F in D:F.addEventListener(A,create_proxy(B),to_js(C)if C else False)\n\t\treturn B\n\treturn E\ndef _get_elements(selector):\n\tA=selector;from pyscript.web import Element as B,ElementCollection as C\n\tif isinstance(A,str):return list(document.querySelectorAll(A))\n\telif isinstance(A,B):return[A._dom_element]\n\telif isinstance(A,C):return[A._dom_element for A in A]\n\telif isinstance(A,list):return A\n\telse:return[A]\ndef _create_wrapper(func):\n\tA=func;B=A\n\twhile hasattr(B,'__wrapped__'):B=B.__wrapped__\n\tE=inspect.signature(B);D=bool(E.parameters)\n\tif is_awaitable(A):\n\t\tif D:\n\t\t\tasync def C(event):return await A(event)\n\t\telse:\n\t\t\tasync def C(*B,**C):return await A()\n\telif D:\n\t\tdef C(event):return A(event)\n\telse:\n\t\tdef C(*B,**C):return A()\n\treturn wraps(A)(C)",
8
8
  "fetch.py": "import json,js\nfrom pyscript.util import as_bytearray\nclass _FetchResponse:\n\tdef __init__(A,response):A._response=response\n\tdef __getattr__(A,attr):return getattr(A._response,attr)\n\tasync def arrayBuffer(B):\n\t\tA=await B._response.arrayBuffer()\n\t\tif hasattr(A,'to_py'):return A.to_py()\n\t\treturn memoryview(as_bytearray(A))\n\tasync def blob(A):return await A._response.blob()\n\tasync def bytearray(A):B=await A._response.arrayBuffer();return as_bytearray(B)\n\tasync def json(A):return json.loads(await A.text())\n\tasync def text(A):return await A._response.text()\nclass _FetchPromise:\n\tdef __init__(B,promise):A=promise;B._promise=A;A._response=None;A.arrayBuffer=B.arrayBuffer;A.blob=B.blob;A.bytearray=B.bytearray;A.json=B.json;A.text=B.text\n\t@staticmethod\n\tdef setup(promise,response):A=promise;A._response=_FetchResponse(response);return A._response\n\tasync def _get_response(A):\n\t\tif not A._promise._response:await A._promise\n\t\treturn A._promise._response\n\tasync def arrayBuffer(A):B=await A._get_response();return await B.arrayBuffer()\n\tasync def blob(A):B=await A._get_response();return await B.blob()\n\tasync def bytearray(A):B=await A._get_response();return await B.bytearray()\n\tasync def json(A):B=await A._get_response();return await B.json()\n\tasync def text(A):B=await A._get_response();return await B.text()\ndef fetch(url,**B):\n\tC=js.JSON.parse(json.dumps(B))\n\tdef D(response,*B):return _FetchPromise.setup(A,response)\n\tA=js.fetch(url,C).then(D);_FetchPromise(A);return A",