diff --git a/docs/source/_output/api/contents/all.json b/docs/source/_output/api/contents/all.json new file mode 100644 index 00000000..974339cc --- /dev/null +++ b/docs/source/_output/api/contents/all.json @@ -0,0 +1,57 @@ +{ + "content": [ + { + "content": null, + "created": "2024-06-08T20:05:21.613117Z", + "format": null, + "hash": null, + "hash_algorithm": null, + "last_modified": "2024-06-08T20:05:21.613117Z", + "mimetype": null, + "name": "data", + "path": "data", + "size": null, + "type": "directory", + "writable": true + }, + { + "content": null, + "created": "2024-06-08T20:05:21.660358Z", + "format": null, + "hash": null, + "hash_algorithm": null, + "last_modified": "2024-06-05T11:08:14.341755Z", + "mimetype": null, + "name": "intro_tutorial.ipynb", + "path": "intro_tutorial.ipynb", + "size": 16806, + "type": "notebook", + "writable": true + }, + { + "content": null, + "created": "2024-06-08T20:05:21.660358Z", + "format": null, + "hash": null, + "hash_algorithm": null, + "last_modified": "2024-06-04T23:37:27.794057Z", + "mimetype": "text/markdown", + "name": "overview.md", + "path": "overview.md", + "size": 1318, + "type": "file", + "writable": true + } + ], + "created": "2024-06-08T20:05:21.613117Z", + "format": "json", + "hash": null, + "hash_algorithm": null, + "last_modified": "2024-06-08T20:05:21.660358Z", + "mimetype": null, + "name": "", + "path": "", + "size": null, + "type": "directory", + "writable": true +} \ No newline at end of file diff --git a/docs/source/_output/api/contents/data/all.json b/docs/source/_output/api/contents/data/all.json new file mode 100644 index 00000000..ec595695 --- /dev/null +++ b/docs/source/_output/api/contents/data/all.json @@ -0,0 +1,29 @@ +{ + "content": [ + { + "content": null, + "created": "2024-06-08T20:05:21.613117Z", + "format": null, + "hash": null, + "hash_algorithm": null, + "last_modified": "2024-05-27T12:03:04.558105Z", + "mimetype": null, + "name": "nuts_rg_60M_2013_lvl_2.geojson", + "path": "data/nuts_rg_60M_2013_lvl_2.geojson", + "size": 327461, + "type": "file", + "writable": true + } + ], + "created": "2024-06-08T20:05:21.613117Z", + "format": "json", + "hash": null, + "hash_algorithm": null, + "last_modified": "2024-06-08T20:05:21.613117Z", + "mimetype": null, + "name": "data", + "path": "data", + "size": null, + "type": "directory", + "writable": true +} \ No newline at end of file diff --git a/docs/source/_output/api/translations/all.json b/docs/source/_output/api/translations/all.json new file mode 100644 index 00000000..0f1a90ee --- /dev/null +++ b/docs/source/_output/api/translations/all.json @@ -0,0 +1,9 @@ +{ + "data": { + "en": { + "displayName": "English", + "nativeName": "English" + } + }, + "message": "" +} \ No newline at end of file diff --git a/docs/source/_output/api/translations/en.json b/docs/source/_output/api/translations/en.json new file mode 100644 index 00000000..2d378ee6 --- /dev/null +++ b/docs/source/_output/api/translations/en.json @@ -0,0 +1,4 @@ +{ + "data": {}, + "message": "" +} \ No newline at end of file diff --git a/docs/source/_output/bootstrap.js b/docs/source/_output/bootstrap.js new file mode 100644 index 00000000..917b4f59 --- /dev/null +++ b/docs/source/_output/bootstrap.js @@ -0,0 +1,93 @@ +/*----------------------------------------------------------------------------- +| Copyright (c) Jupyter Development Team. +| Distributed under the terms of the Modified BSD License. +|----------------------------------------------------------------------------*/ + +// We copy some of the pageconfig parsing logic in @jupyterlab/coreutils +// below, since this must run before any other files are loaded (including +// @jupyterlab/coreutils). + +/** + * Get global configuration data for the Jupyter application. + * + * @param name - The name of the configuration option. + * + * @returns The config value or an empty string if not found. + * + * #### Notes + * All values are treated as strings. For browser based applications, it is + * assumed that the page HTML includes a script tag with the id + * `jupyter-config-data` containing the configuration as valid JSON. + */ + +let _CONFIG_DATA = null; +function getOption(name) { + if (_CONFIG_DATA === null) { + let configData = {}; + // Use script tag if available. + if (typeof document !== 'undefined' && document) { + const el = document.getElementById('jupyter-config-data'); + + if (el) { + configData = JSON.parse(el.textContent || '{}'); + } + } + _CONFIG_DATA = configData; + } + + return _CONFIG_DATA[name] || ''; +} + +// eslint-disable-next-line no-undef +__webpack_public_path__ = getOption('fullStaticUrl') + '/'; + +function loadScript(url) { + return new Promise((resolve, reject) => { + const newScript = document.createElement('script'); + newScript.onerror = reject; + newScript.onload = resolve; + newScript.async = true; + document.head.appendChild(newScript); + newScript.src = url; + }); +} + +async function loadComponent(url, scope) { + await loadScript(url); + + // From https://webpack.js.org/concepts/module-federation/#dynamic-remote-containers + await __webpack_init_sharing__('default'); + const container = window._JUPYTERLAB[scope]; + // Initialize the container, it may provide shared modules and may need ours + await container.init(__webpack_share_scopes__.default); +} + +void (async function bootstrap() { + // This is all the data needed to load and activate plugins. This should be + // gathered by the server and put onto the initial page template. + const extension_data = getOption('federated_extensions'); + + // We first load all federated components so that the shared module + // deduplication can run and figure out which shared modules from all + // components should be actually used. We have to do this before importing + // and using the module that actually uses these components so that all + // dependencies are initialized. + let labExtensionUrl = getOption('fullLabextensionsUrl'); + const extensions = await Promise.allSettled( + extension_data.map(async data => { + await loadComponent(`${labExtensionUrl}/${data.name}/${data.load}`, data.name); + }) + ); + + extensions.forEach(p => { + if (p.status === 'rejected') { + // There was an error loading the component + console.error(p.reason); + } + }); + + // Now that all federated containers are initialized with the main + // container, we can import the main function. + let main = (await import('./index.js')).main; + void main(); +})(); diff --git a/docs/source/_output/config-utils.js b/docs/source/_output/config-utils.js new file mode 100644 index 00000000..cfbb51a1 --- /dev/null +++ b/docs/source/_output/config-utils.js @@ -0,0 +1,267 @@ +/** + * configuration utilities for jupyter-lite + * + * this file may not import anything else, and exposes no API + */ + +/* + * An `index.html` should `await import('../config-utils.js')` after specifying + * the key `script` tags... + * + * ```html + * + * ``` + */ +const JUPYTER_CONFIG_ID = 'jupyter-config-data'; + +/* + * The JS-mangled name for `data-jupyter-lite-root` + */ +const LITE_ROOT_ATTR = 'jupyterLiteRoot'; + +/** + * The well-known filename that contains `#jupyter-config-data` and other goodies + */ +const LITE_FILES = ['jupyter-lite.json', 'jupyter-lite.ipynb']; + +/** + * And this link tag, used like so to load a bundle after configuration. + * + * ```html + * + * ``` + */ +const LITE_MAIN = 'jupyter-lite-main'; + +/** + * The current page, with trailing server junk stripped + */ +const HERE = `${window.location.origin}${window.location.pathname.replace( + /(\/|\/index.html)?$/, + '', +)}/`; + +/** + * The computed composite configuration + */ +let _JUPYTER_CONFIG; + +/** + * A handle on the config script, must exist, and will be overridden + */ +const CONFIG_SCRIPT = document.getElementById(JUPYTER_CONFIG_ID); + +/** + * The relative path to the root of this JupyterLite + */ +const RAW_LITE_ROOT = CONFIG_SCRIPT.dataset[LITE_ROOT_ATTR]; + +/** + * The fully-resolved path to the root of this JupyterLite + */ +const FULL_LITE_ROOT = new URL(RAW_LITE_ROOT, HERE).toString(); + +/** + * Paths that are joined with baseUrl to derive full URLs + */ +const UNPREFIXED_PATHS = ['licensesUrl', 'themesUrl']; + +/* a DOM parser for reading html files */ +const parser = new DOMParser(); + +/** + * Merge `jupyter-config-data` on the current page with: + * - the contents of `.jupyter-lite#/jupyter-config-data` + * - parent documents, and their `.jupyter-lite#/jupyter-config-data` + * ...up to `jupyter-lite-root`. + */ +async function jupyterConfigData() { + /** + * Return the value if already cached for some reason + */ + if (_JUPYTER_CONFIG != null) { + return _JUPYTER_CONFIG; + } + + let parent = new URL(HERE).toString(); + let promises = [getPathConfig(HERE)]; + while (parent != FULL_LITE_ROOT) { + parent = new URL('..', parent).toString(); + promises.unshift(getPathConfig(parent)); + } + + const configs = (await Promise.all(promises)).flat(); + + let finalConfig = configs.reduce(mergeOneConfig); + + // apply any final patches + finalConfig = dedupFederatedExtensions(finalConfig); + + // hoist to cache + _JUPYTER_CONFIG = finalConfig; + + return finalConfig; +} + +/** + * Merge a new configuration on top of the existing config + */ +function mergeOneConfig(memo, config) { + for (const [k, v] of Object.entries(config)) { + switch (k) { + // this list of extension names is appended + case 'disabledExtensions': + case 'federated_extensions': + memo[k] = [...(memo[k] || []), ...v]; + break; + // these `@org/pkg:plugin` are merged at the first level of values + case 'litePluginSettings': + case 'settingsOverrides': + if (!memo[k]) { + memo[k] = {}; + } + for (const [plugin, defaults] of Object.entries(v || {})) { + memo[k][plugin] = { ...(memo[k][plugin] || {}), ...defaults }; + } + break; + default: + memo[k] = v; + } + } + return memo; +} + +function dedupFederatedExtensions(config) { + const originalList = Object.keys(config || {})['federated_extensions'] || []; + const named = {}; + for (const ext of originalList) { + named[ext.name] = ext; + } + let allExtensions = [...Object.values(named)]; + allExtensions.sort((a, b) => a.name.localeCompare(b.name)); + return config; +} + +/** + * Load jupyter config data from (this) page and merge with + * `jupyter-lite.json#jupyter-config-data` + */ +async function getPathConfig(url) { + let promises = [getPageConfig(url)]; + for (const fileName of LITE_FILES) { + promises.unshift(getLiteConfig(url, fileName)); + } + return Promise.all(promises); +} + +/** + * The current normalized location + */ +function here() { + return window.location.href.replace(/(\/|\/index.html)?$/, '/'); +} + +/** + * Maybe fetch an `index.html` in this folder, which must contain the trailing slash. + */ +export async function getPageConfig(url = null) { + let script = CONFIG_SCRIPT; + + if (url != null) { + const text = await (await window.fetch(`${url}index.html`)).text(); + const doc = parser.parseFromString(text, 'text/html'); + script = doc.getElementById(JUPYTER_CONFIG_ID); + } + return fixRelativeUrls(url, JSON.parse(script.textContent)); +} + +/** + * Fetch a jupyter-lite JSON or Notebook in this folder, which must contain the trailing slash. + */ +export async function getLiteConfig(url, fileName) { + let text = '{}'; + let config = {}; + const liteUrl = `${url || HERE}${fileName}`; + try { + text = await (await window.fetch(liteUrl)).text(); + const json = JSON.parse(text); + const liteConfig = fileName.endsWith('.ipynb') + ? json['metadata']['jupyter-lite'] + : json; + config = liteConfig[JUPYTER_CONFIG_ID] || {}; + } catch (err) { + console.warn(`failed get ${JUPYTER_CONFIG_ID} from ${liteUrl}`); + } + return fixRelativeUrls(url, config); +} + +export function fixRelativeUrls(url, config) { + let urlBase = new URL(url || here()).pathname; + for (const [k, v] of Object.entries(config)) { + config[k] = fixOneRelativeUrl(k, v, url, urlBase); + } + return config; +} + +export function fixOneRelativeUrl(key, value, url, urlBase) { + if (key === 'litePluginSettings' || key === 'settingsOverrides') { + // these are plugin id-keyed objects, fix each plugin + return Object.entries(value || {}).reduce((m, [k, v]) => { + m[k] = fixRelativeUrls(url, v); + return m; + }, {}); + } else if ( + !UNPREFIXED_PATHS.includes(key) && + key.endsWith('Url') && + value.startsWith('./') + ) { + // themesUrls, etc. are joined in code with baseUrl, leave as-is: otherwise, clean + return `${urlBase}${value.slice(2)}`; + } else if (key.endsWith('Urls') && Array.isArray(value)) { + return value.map((v) => (v.startsWith('./') ? `${urlBase}${v.slice(2)}` : v)); + } + return value; +} + +/** + * Update with the as-configured favicon + */ +function addFavicon(config) { + const favicon = document.createElement('link'); + favicon.rel = 'icon'; + favicon.type = 'image/x-icon'; + favicon.href = config.faviconUrl; + document.head.appendChild(favicon); +} + +/** + * The main entry point. + */ +async function main() { + const config = await jupyterConfigData(); + if (config.baseUrl === new URL(here()).pathname) { + window.location.href = config.appUrl.replace(/\/?$/, '/index.html'); + return; + } + // rewrite the config + CONFIG_SCRIPT.textContent = JSON.stringify(config, null, 2); + addFavicon(config); + const preloader = document.getElementById(LITE_MAIN); + const bundle = document.createElement('script'); + bundle.src = preloader.href; + bundle.main = preloader.attributes.main; + document.head.appendChild(bundle); +} + +/** + * TODO: consider better pattern for invocation. + */ +await main(); diff --git a/docs/source/_output/consoles/favicon.ico b/docs/source/_output/consoles/favicon.ico new file mode 100644 index 00000000..97fcfd54 Binary files /dev/null and b/docs/source/_output/consoles/favicon.ico differ diff --git a/docs/source/_output/consoles/index.html b/docs/source/_output/consoles/index.html new file mode 100644 index 00000000..314c34ff --- /dev/null +++ b/docs/source/_output/consoles/index.html @@ -0,0 +1,37 @@ + + +
+[Open Browser Console for more detailed log - Double click to close this message]\n${e}\n${t}\n `,s.style.height=`${o}px`,s.style.width=`${n}px`,s.classList.add("text-error"))},this.el.ondblclick=()=>{s.classList.contains("text-error")&&(s.classList.remove("text-error"),s.innerHTML=f,s.append(i),s.classList.add("icon-error"))}}}function F(e,t){return class extends q{generateErrorMessage(){return{msg:t,stack:String(e instanceof Error?e.stack:e)}}}}}}]); \ No newline at end of file diff --git a/docs/source/_output/extensions/@jupyter-widgets/jupyterlab-manager/static/651.fe40a967a60b543cf15c.js b/docs/source/_output/extensions/@jupyter-widgets/jupyterlab-manager/static/651.fe40a967a60b543cf15c.js new file mode 100644 index 00000000..d4000827 --- /dev/null +++ b/docs/source/_output/extensions/@jupyter-widgets/jupyterlab-manager/static/651.fe40a967a60b543cf15c.js @@ -0,0 +1,2 @@ +/*! For license information please see 651.fe40a967a60b543cf15c.js.LICENSE.txt */ +(self.webpackChunk_jupyter_widgets_jupyterlab_manager=self.webpackChunk_jupyter_widgets_jupyterlab_manager||[]).push([[651],{4651:function(e,t){var n;!function(t,n){"use strict";"object"==typeof e.exports?e.exports=t.document?n(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return n(e)}:n(t)}("undefined"!=typeof window?window:this,(function(r,i){"use strict";var o=[],a=Object.getPrototypeOf,s=o.slice,u=o.flat?function(e){return o.flat.call(e)}:function(e){return o.concat.apply([],e)},l=o.push,c=o.indexOf,f={},p=f.toString,d=f.hasOwnProperty,h=d.toString,g=h.call(Object),v={},y=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},m=function(e){return null!=e&&e===e.window},x=r.document,b={type:!0,src:!0,nonce:!0,noModule:!0};function w(e,t,n){var r,i,o=(n=n||x).createElement("script");if(o.text=e,t)for(r in b)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function T(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?f[p.call(e)]||"object":typeof e}var C="3.7.1",k=/HTML$/i,S=function(e,t){return new S.fn.init(e,t)};function E(e){var t=!!e&&"length"in e&&e.length,n=T(e);return!y(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function j(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}S.fn=S.prototype={jquery:C,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(e){return this.pushStack(S.map(this,(function(t,n){return e.call(t,n,t)})))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(S.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n
0&&Ne(a,!u&&De(e,"script")),s},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(oe(n)){if(t=n[se.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[se.expando]=void 0}n[ue.expando]&&(n[ue.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Ve(this,e,!0)},remove:function(e){return Ve(this,e)},text:function(e){return ee(this,(function(e){return void 0===e?S.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return Ue(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||$e(this,e).appendChild(e)}))},prepend:function(){return Ue(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=$e(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return Ue(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return Ue(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(De(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return S.clone(this,e,t)}))},html:function(e){return ee(this,(function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ie.test(e)&&!Ae[(Ee.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n