aboutsummaryrefslogtreecommitdiffstats
path: root/root/static
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2019-10-10 17:39:11 +0000
committers-ol <s-ol@users.noreply.github.com>2019-10-10 17:39:11 +0000
commit91546d12919736b08567d7174bf1063cab0838f0 (patch)
treef5afc5c801a5038fba21b44f117538956a2a64a7 /root/static
parentmake fileders load just-in-time (diff)
downloadmmm-91546d12919736b08567d7174bf1063cab0838f0.tar.gz
mmm-91546d12919736b08567d7174bf1063cab0838f0.zip
add WebStore, fix Browser
Diffstat (limited to 'root/static')
-rw-r--r--root/static/mmm/application$lua.lua2701
-rw-r--r--root/static/style/text$css.css411
2 files changed, 0 insertions, 3112 deletions
diff --git a/root/static/mmm/application$lua.lua b/root/static/mmm/application$lua.lua
deleted file mode 100644
index 5a6dc53..0000000
--- a/root/static/mmm/application$lua.lua
+++ /dev/null
@@ -1,2701 +0,0 @@
-local p = package.preload
-if not p["mmm.canvasapp"] then p["mmm.canvasapp"] = load("local window = js.global\
-local js = require('js')\
-local a, canvas, div, button, script\
-do\
- local _obj_0 = require('mmm.dom')\
- a, canvas, div, button, script = _obj_0.a, _obj_0.canvas, _obj_0.div, _obj_0.button, _obj_0.script\
-end\
-local CanvasApp\
-do\
- local _class_0\
- local _base_0 = {\
- width = 500,\
- height = 400,\
- update = function(self, dt)\
- self.time = self.time + dt\
- if self.length and self.time > self.length then\
- self.time = self.time - self.length\
- return true\
- end\
- end,\
- render = function(self, fps)\
- if fps == nil then\
- fps = 60\
- end\
- assert(self.length, 'cannot render CanvasApp without length set')\
- self.paused = true\
- local actual_render\
- actual_render = function()\
- local writer = js.new(window.Whammy.Video, fps)\
- local doFrame\
- doFrame = function()\
- local done = self:update(1 / fps)\
- self.ctx:resetTransform()\
- self:draw()\
- writer:add(self.canvas)\
- if done or self.time >= self.length then\
- local blob = writer:compile()\
- local name = tostring(self.__class.__name) .. \"_\" .. tostring(fps) .. \"fps.webm\"\
- return self.node.lastChild:appendChild(a(name, {\
- download = name,\
- href = window.URL:createObjectURL(blob)\
- }))\
- else\
- return window:setTimeout(doFrame)\
- end\
- end\
- self.time = 0\
- return doFrame()\
- end\
- if window.Whammy then\
- return actual_render()\
- else\
- window.global = window.global or window\
- return document.body:appendChild(script({\
- onload = actual_render,\
- src = 'https://cdn.jsdelivr.net/npm/whammy@0.0.1/whammy.min.js'\
- }))\
- end\
- end\
- }\
- _base_0.__index = _base_0\
- _class_0 = setmetatable({\
- __init = function(self, show_menu, paused)\
- if show_menu == nil then\
- show_menu = false\
- end\
- self.paused = paused\
- self.canvas = canvas({\
- width = self.width,\
- height = self.height\
- })\
- self.ctx = self.canvas:getContext('2d')\
- self.time = 0\
- self.canvas.tabIndex = 0\
- self.canvas:addEventListener('click', function(_, e)\
- return self.click and self:click(e.offsetX, e.offsetY, e.button)\
- end)\
- self.canvas:addEventListener('keydown', function(_, e)\
- return self.keydown and self:keydown(e.key, e.code)\
- end)\
- local lastMillis = window.performance:now()\
- local animationFrame\
- animationFrame = function(_, millis)\
- self:update((millis - lastMillis) / 1000)\
- self.ctx:resetTransform()\
- self:draw()\
- lastMillis = millis\
- if not self.paused then\
- return window:setTimeout((function()\
- return window:requestAnimationFrame(animationFrame)\
- end), 0)\
- end\
- end\
- window:requestAnimationFrame(animationFrame)\
- if show_menu then\
- self.node = div({\
- className = 'canvas_app',\
- self.canvas,\
- div({\
- className = 'overlay',\
- button('render 30fps', {\
- onclick = function()\
- return self:render(30)\
- end\
- }),\
- button('render 60fps', {\
- onclick = function()\
- return self:render(60)\
- end\
- })\
- })\
- })\
- else\
- self.node = self.canvas\
- end\
- end,\
- __base = _base_0,\
- __name = \"CanvasApp\"\
- }, {\
- __index = _base_0,\
- __call = function(cls, ...)\
- local _self_0 = setmetatable({}, _base_0)\
- cls.__init(_self_0, ...)\
- return _self_0\
- end\
- })\
- _base_0.__class = _class_0\
- CanvasApp = _class_0\
-end\
-return {\
- CanvasApp = CanvasApp\
-}\
-", "mmm/canvasapp.client.lua") end
-if not p["mmm.color"] then p["mmm.color"] = load("local rgb\
-rgb = function(r, g, b)\
- if 'table' == type(r) then\
- r, g, b = table.unpack(r)\
- end\
- return \"rgb(\" .. tostring(r * 255) .. \", \" .. tostring(g * 255) .. \", \" .. tostring(b * 255) .. \")\"\
-end\
-local rgba\
-rgba = function(r, g, b, a)\
- if 'table' == type(r) then\
- r, g, b, a = table.unpack(r)\
- end\
- return \"rgba(\" .. tostring(r * 255) .. \", \" .. tostring(g * 255) .. \", \" .. tostring(b * 255) .. \", \" .. tostring(a or 1) .. \")\"\
-end\
-local hsl\
-hsl = function(h, s, l)\
- if 'table' == type(h) then\
- h, s, l = table.unpack(h)\
- end\
- return \"hsl(\" .. tostring(h * 360) .. \", \" .. tostring(s * 100) .. \"%, \" .. tostring(l * 100) .. \"%)\"\
-end\
-local hsla\
-hsla = function(h, s, l, a)\
- if 'table' == type(h) then\
- h, s, l, a = table.unpack(h)\
- end\
- return \"hsla(\" .. tostring(h * 360) .. \", \" .. tostring(s * 100) .. \"%, \" .. tostring(l * 100) .. \"%, \" .. tostring(a or 1) .. \")\"\
-end\
-return {\
- rgb = rgb,\
- rgba = rgba,\
- hsl = hsl,\
- hsla = hsla\
-}\
-", "mmm/color.lua") end
-if not p["mmm.highlighting"] then p["mmm.highlighting"] = load("local code\
-code = require('mmm.dom').code\
-local highlight\
-local trim\
-trim = function(str)\
- return str:match('^ *(..-) *$')\
-end\
-if MODE == 'SERVER' then\
- highlight = function(lang, str)\
- assert(str, 'no string to highlight')\
- return code((trim(str)), {\
- class = \"hljs lang-\" .. tostring(lang)\
- })\
- end\
-else\
- highlight = function(lang, str)\
- assert(str, 'no string to highlight')\
- local result = window.hljs:highlight(lang, (trim(str)), true)\
- do\
- local _with_0 = code({\
- class = \"hljs lang-\" .. tostring(lang)\
- })\
- _with_0.innerHTML = result.value\
- return _with_0\
- end\
- end\
-end\
-local languages = setmetatable({ }, {\
- __index = function(self, name)\
- do\
- local val\
- val = function(str)\
- return highlight(name, str)\
- end\
- self[name] = val\
- return val\
- end\
- end\
-})\
-return {\
- highlight = highlight,\
- languages = languages\
-}\
-", "mmm/highlighting.lua") end
-if not p["mmm"] then p["mmm"] = load("window = js.global\
-local console\
-document, console = window.document, window.console\
-MODE = 'CLIENT'\
-local deep_tostring\
-deep_tostring = function(tbl, space)\
- if space == nil then\
- space = ''\
- end\
- if 'userdata' == type(tbl) then\
- return tbl\
- end\
- local buf = space .. tostring(tbl)\
- if not ('table' == type(tbl)) then\
- return buf\
- end\
- buf = buf .. ' {\\n'\
- for k, v in pairs(tbl) do\
- buf = buf .. tostring(space) .. \" [\" .. tostring(k) .. \"]: \" .. tostring(deep_tostring(v, space .. ' ')) .. \"\\n\"\
- end\
- buf = buf .. tostring(space) .. \"}\"\
- return buf\
-end\
-print = function(...)\
- local contents\
- do\
- local _accum_0 = { }\
- local _len_0 = 1\
- local _list_0 = {\
- ...\
- }\
- for _index_0 = 1, #_list_0 do\
- local v = _list_0[_index_0]\
- _accum_0[_len_0] = deep_tostring(v)\
- _len_0 = _len_0 + 1\
- end\
- contents = _accum_0\
- end\
- return console:log(table.unpack(contents))\
-end\
-warn = function(...)\
- local contents\
- do\
- local _accum_0 = { }\
- local _len_0 = 1\
- local _list_0 = {\
- ...\
- }\
- for _index_0 = 1, #_list_0 do\
- local v = _list_0[_index_0]\
- _accum_0[_len_0] = deep_tostring(v)\
- _len_0 = _len_0 + 1\
- end\
- contents = _accum_0\
- end\
- return console:warn(table.unpack(contents))\
-end\
-package.path = '/?.lua;/?/init.lua'\
-do\
- local _require = require\
- relative = function(base, sub)\
- if not ('number' == type(sub)) then\
- sub = 0\
- end\
- for i = 1, sub do\
- base = base:match('^(.*)%.%w+$')\
- end\
- return function(name, x)\
- if '.' == name:sub(1, 1) then\
- name = base .. name\
- end\
- return _require(name)\
- end\
- end\
-end\
-if on_load then\
- for _index_0 = 1, #on_load do\
- local f = on_load[_index_0]\
- f()\
- end\
-end\
-on_load = setmetatable({ }, {\
- __newindex = function(t, k, v)\
- rawset(t, k, v)\
- return v()\
- end\
-})\
-", "mmm/init.client.lua") end
-if not p["mmm.ordered"] then p["mmm.ordered"] = load("local sort\
-sort = function(t, order_fn, only_strings)\
- do\
- local index\
- do\
- local _accum_0 = { }\
- local _len_0 = 1\
- for k, v in pairs(t) do\
- if (not only_strings) or 'string' == type(k) then\
- _accum_0[_len_0] = k\
- _len_0 = _len_0 + 1\
- end\
- end\
- index = _accum_0\
- end\
- table.sort(index, order_fn)\
- return index\
- end\
-end\
-local onext\
-onext = function(state, key)\
- state.i = state.i + state.step\
- local t, index, i\
- t, index, i = state.t, state.index, state.i\
- do\
- key = index[i]\
- if key then\
- return key, t[key]\
- end\
- end\
-end\
-local opairs\
-opairs = function(t, order_fn, only_strings)\
- if only_strings == nil then\
- only_strings = false\
- end\
- local state = {\
- t = t,\
- i = 0,\
- step = 1,\
- index = sort(t, order_fn, only_strings)\
- }\
- return onext, state, nil\
-end\
-local ropairs\
-ropairs = function(t, order_fn, only_strings)\
- if only_strings == nil then\
- only_strings = false\
- end\
- local index = sort(t, order_fn, only_strings)\
- local state = {\
- t = t,\
- index = index,\
- i = #index + 1,\
- step = -1\
- }\
- return onext, state, nil\
-end\
-return {\
- onext = onext,\
- opairs = opairs,\
- ropairs = ropairs\
-}\
-", "mmm/ordered.lua") end
-if not p["mmm.mmmfs.browser"] then p["mmm.mmmfs.browser"] = load("local require = relative(..., 1)\
-local Key\
-Key = require('.fileder').Key\
-local converts, get_conversions, apply_conversions\
-do\
- local _obj_0 = require('.conversion')\
- converts, get_conversions, apply_conversions = _obj_0.converts, _obj_0.get_conversions, _obj_0.apply_conversions\
-end\
-local ReactiveVar, get_or_create, text, elements\
-do\
- local _obj_0 = require('mmm.component')\
- ReactiveVar, get_or_create, text, elements = _obj_0.ReactiveVar, _obj_0.get_or_create, _obj_0.text, _obj_0.elements\
-end\
-local pre, div, nav, span, button, a, code, select, option\
-pre, div, nav, span, button, a, code, select, option = elements.pre, elements.div, elements.nav, elements.span, elements.button, elements.a, elements.code, elements.select, elements.option\
-local languages\
-languages = require('mmm.highlighting').languages\
-local keep\
-keep = function(var)\
- local last = var:get()\
- return var:map(function(val)\
- last = val or last\
- return last\
- end)\
-end\
-local code_cast\
-code_cast = function(lang)\
- return {\
- inp = \"text/\" .. tostring(lang) .. \".*\",\
- out = 'mmm/dom',\
- transform = function(val)\
- return languages[lang](val)\
- end\
- }\
-end\
-local casts = {\
- code_cast('javascript'),\
- code_cast('moonscript'),\
- code_cast('lua'),\
- code_cast('markdown'),\
- code_cast('html'),\
- {\
- inp = 'text/plain',\
- out = 'mmm/dom',\
- transform = function(val)\
- return text(val)\
- end\
- },\
- {\
- inp = 'URL.*',\
- out = 'mmm/dom',\
- transform = function(href)\
- return span(a((code(href)), {\
- href = href\
- }))\
- end\
- }\
-}\
-for _index_0 = 1, #converts do\
- local convert = converts[_index_0]\
- table.insert(casts, convert)\
-end\
-local Browser\
-do\
- local _class_0\
- local err_and_trace, default_convert\
- local _base_0 = {\
- get_content = function(self, prop, err, convert)\
- if err == nil then\
- err = self.error\
- end\
- if convert == nil then\
- convert = default_convert\
- end\
- local clear_error\
- clear_error = function()\
- if MODE == 'CLIENT' then\
- return err:set()\
- end\
- end\
- local disp_error\
- disp_error = function(msg)\
- if MODE == 'CLIENT' then\
- err:set(pre(msg))\
- end\
- warn(\"ERROR rendering content: \" .. tostring(msg))\
- return nil\
- end\
- local active = self.active:get()\
- if not (active) then\
- return disp_error(\"fileder not found!\")\
- end\
- if not (prop) then\
- return disp_error(\"facet not found!\")\
- end\
- local ok, res = xpcall(convert, err_and_trace, active, prop)\
- if MODE == 'CLIENT' then\
- document.body.classList:remove('loading')\
- end\
- if ok and res then\
- clear_error()\
- return res\
- elseif ok then\
- return div(\"[no conversion path to \" .. tostring(prop.type) .. \"]\")\
- elseif res and res.msg.match and res.msg:match('%[nossr%]$') then\
- return div(\"[this page could not be pre-rendered on the server]\")\
- else\
- res = tostring(res.msg) .. \"\\n\" .. tostring(res.trace)\
- return disp_error(res)\
- end\
- end,\
- get_inspector = function(self)\
- self.inspect_prop = self.facet:map(function(prop)\
- local active = self.active:get()\
- local key = active and active:find(prop)\
- if key and key.original then\
- key = key.original\
- end\
- return key\
- end)\
- self.inspect_err = ReactiveVar()\
- do\
- local _with_0 = div({\
- class = 'view inspector'\
- })\
- _with_0:append(nav({\
- span('inspector'),\
- self.inspect_prop:map(function(current)\
- current = current and current:tostring()\
- local fileder = self.active:get()\
- local onchange\
- onchange = function(_, e)\
- if e.target.value == '' then\
- return \
- end\
- local name\
- name = self.facet:get().name\
- return self.inspect_prop:set(Key(e.target.value))\
- end\
- do\
- local _with_1 = select({\
- onchange = onchange\
- })\
- _with_1:append(option('(none)', {\
- value = '',\
- disabled = true,\
- selected = not value\
- }))\
- if fileder then\
- for key, _ in pairs(fileder.facets) do\
- local value = key:tostring()\
- _with_1:append(option(value, {\
- value = value,\
- selected = value == current\
- }))\
- end\
- end\
- return _with_1\
- end\
- end),\
- self.inspect:map(function(enabled)\
- if enabled then\
- return button('close', {\
- onclick = function(_, e)\
- return self.inspect:set(false)\
- end\
- })\
- end\
- end)\
- }))\
- _with_0:append((function()\
- do\
- local _with_1 = div({\
- class = self.inspect_err:map(function(e)\
- if e then\
- return 'error-wrap'\
- else\
- return 'error-wrap empty'\
- end\
- end)\
- })\
- _with_1:append(span(\"an error occured while rendering this view:\"))\
- _with_1:append(self.inspect_err)\
- return _with_1\
- end\
- end)())\
- _with_0:append((function()\
- do\
- local _with_1 = pre({\
- class = 'content'\
- })\
- _with_1:append(keep(self.inspect_prop:map(function(prop, old)\
- return self:get_content(prop, self.inspect_err, function(self, prop)\
- local value, key = self:get(prop)\
- assert(key, \"couldn't @get \" .. tostring(prop))\
- local conversions = get_conversions('mmm/dom', key.type, casts)\
- assert(conversions, \"cannot cast '\" .. tostring(key.type) .. \"'\")\
- return apply_conversions(conversions, value, self, prop)\
- end)\
- end)))\
- return _with_1\
- end\
- end)())\
- return _with_0\
- end\
- end,\
- navigate = function(self, new)\
- return self.path:set(new)\
- end\
- }\
- _base_0.__index = _base_0\
- _class_0 = setmetatable({\
- __init = function(self, root, path, rehydrate)\
- if rehydrate == nil then\
- rehydrate = false\
- end\
- self.root = root\
- assert(self.root, 'root fileder is nil')\
- self.path = ReactiveVar(path or '')\
- if MODE == 'CLIENT' then\
- local logo = document:querySelector('header h1 > svg')\
- local spin\
- spin = function()\
- logo.classList:add('spin')\
- local _ = logo.parentElement.offsetWidth\
- return logo.classList:remove('spin')\
- end\
- self.path:subscribe(function(path)\
- document.body.classList:add('loading')\
- spin()\
- if self.skip then\
- return \
- end\
- local vis_path = path .. ((function()\
- if '/' == path:sub(-1) then\
- return ''\
- else\
- return '/'\
- end\
- end)())\
- return window.history:pushState(path, '', vis_path)\
- end)\
- window.onpopstate = function(_, event)\
- if event.state and not event.state == js.null then\
- self.skip = true\
- self.path:set(event.state)\
- self.skip = nil\
- end\
- end\
- end\
- self.active = self.path:map((function()\
- local _base_1 = self.root\
- local _fn_0 = _base_1.walk\
- return function(...)\
- return _fn_0(_base_1, ...)\
- end\
- end)())\
- self.facet = self.active:map(function(fileder)\
- if not (fileder) then\
- return \
- end\
- local last = self.facet and self.facet:get()\
- return Key((function()\
- if last then\
- return last.type\
- else\
- return 'mmm/dom'\
- end\
- end)())\
- end)\
- self.inspect = ReactiveVar((MODE == 'CLIENT' and window.location.search:match('[?&]inspect')))\
- local main = get_or_create('div', 'browser-root', {\
- class = 'main view'\
- })\
- if MODE == 'SERVER' then\
- main:append(nav({\
- id = 'browser-navbar',\
- span('please stand by... interactivity loading :)')\
- }))\
- else\
- main:prepend((function()\
- do\
- local _with_0 = get_or_create('nav', 'browser-navbar')\
- _with_0.node.innerHTML = ''\
- _with_0:append(span('path: ', self.path:map(function(path)\
- do\
- local _with_1 = div({\
- class = 'path',\
- style = {\
- display = 'inline-block'\
- }\
- })\
- local path_segment\
- path_segment = function(name, href)\
- return a(name, {\
- href = href,\
- onclick = function(_, e)\
- e:preventDefault()\
- return self:navigate(href)\
- end\
- })\
- end\
- local href = ''\
- path = path:match('^/(.*)')\
- _with_1:append(path_segment('root', ''))\
- while path do\
- local name, rest = path:match('^([%w%-_%.]+)/(.*)')\
- if not name then\
- name = path\
- end\
- path = rest\
- href = tostring(href) .. \"/\" .. tostring(name)\
- _with_1:append('/')\
- _with_1:append(path_segment(name, href))\
- end\
- return _with_1\
- end\
- end)))\
- _with_0:append(span('view facet:', {\
- style = {\
- ['margin-right'] = '0'\
- }\
- }))\
- _with_0:append(self.active:map(function(fileder)\
- local onchange\
- onchange = function(_, e)\
- local type\
- type = self.facet:get().type\
- return self.facet:set(Key({\
- name = e.target.value,\
- type = type\
- }))\
- end\
- local current = self.facet:get()\
- current = current and current.name\
- do\
- local _with_1 = select({\
- onchange = onchange,\
- disabled = not fileder\
- })\
- local has_main = fileder and fileder:find(current.name, '.*')\
- _with_1:append(option('(main)', {\
- value = '',\
- disabled = not has_main,\
- selected = current == ''\
- }))\
- if fileder then\
- for i, value in ipairs(fileder:get_facets()) do\
- local _continue_0 = false\
- repeat\
- if value == '' then\
- _continue_0 = true\
- break\
- end\
- _with_1:append(option(value, {\
- value = value,\
- selected = value == current\
- }))\
- _continue_0 = true\
- until true\
- if not _continue_0 then\
- break\
- end\
- end\
- end\
- return _with_1\
- end\
- end))\
- _with_0:append(self.inspect:map(function(enabled)\
- if not enabled then\
- return button('inspect', {\
- onclick = function(_, e)\
- return self.inspect:set(true)\
- end\
- })\
- end\
- end))\
- return _with_0\
- end\
- end)())\
- end\
- self.error = ReactiveVar()\
- main:append((function()\
- do\
- local _with_0 = get_or_create('div', 'browser-error', {\
- class = self.error:map(function(e)\
- if e then\
- return 'error-wrap'\
- else\
- return 'error-wrap empty'\
- end\
- end)\
- })\
- _with_0:append((span(\"an error occured while rendering this view:\")), (rehydrate and _with_0.node.firstChild))\
- _with_0:append(self.error)\
- return _with_0\
- end\
- end)())\
- main:append((function()\
- do\
- local _with_0 = get_or_create('div', 'browser-content', {\
- class = 'content'\
- })\
- local content = ReactiveVar((function()\
- if rehydrate then\
- return _with_0.node.lastChild\
- else\
- return self:get_content(self.facet:get())\
- end\
- end)())\
- _with_0:append(keep(content))\
- if MODE == 'CLIENT' then\
- self.facet:subscribe(function(p)\
- return window:setTimeout((function()\
- return content:set(self:get_content(p))\
- end), 150)\
- end)\
- end\
- return _with_0\
- end\
- end)())\
- if rehydrate then\
- self.facet:set(self.facet:get())\
- end\
- local inspector = self.inspect:map(function(enabled)\
- if enabled then\
- return self:get_inspector()\
- end\
- end)\
- local wrapper = get_or_create('div', 'browser-wrapper', main, inspector, {\
- class = 'browser'\
- })\
- self.node = wrapper.node\
- do\
- local _base_1 = wrapper\
- local _fn_0 = _base_1.render\
- self.render = function(...)\
- return _fn_0(_base_1, ...)\
- end\
- end\
- end,\
- __base = _base_0,\
- __name = \"Browser\"\
- }, {\
- __index = _base_0,\
- __call = function(cls, ...)\
- local _self_0 = setmetatable({}, _base_0)\
- cls.__init(_self_0, ...)\
- return _self_0\
- end\
- })\
- _base_0.__class = _class_0\
- local self = _class_0\
- err_and_trace = function(msg)\
- return {\
- msg = msg,\
- trace = debug.traceback()\
- }\
- end\
- default_convert = function(self, key)\
- return self:get(key.name, 'mmm/dom')\
- end\
- default_convert = function(self, key)\
- return self:get(key.name, 'mmm/dom')\
- end\
- Browser = _class_0\
-end\
-return {\
- Browser = Browser\
-}\
-", "mmm/mmmfs/browser.lua") end
-if not p["mmm.mmmfs.conversion"] then p["mmm.mmmfs.conversion"] = load("local require = relative(..., 1)\
-local converts = require('.converts')\
-local count\
-count = function(base, pattern)\
- if pattern == nil then\
- pattern = '->'\
- end\
- return select(2, base:gsub(pattern, ''))\
-end\
-local escape_pattern\
-escape_pattern = function(inp)\
- return \"^\" .. tostring(inp:gsub('([^%w])', '%%%1')) .. \"$\"\
-end\
-local escape_inp\
-escape_inp = function(inp)\
- return \"^\" .. tostring(inp:gsub('([-/])', '%%%1')) .. \"$\"\
-end\
-local get_conversions\
-get_conversions = function(want, have, _converts, limit)\
- if _converts == nil then\
- _converts = converts\
- end\
- if limit == nil then\
- limit = 5\
- end\
- assert(have, 'need starting type(s)')\
- if 'string' == type(have) then\
- have = {\
- have\
- }\
- end\
- assert(#have > 0, 'need starting type(s) (list was empty)')\
- want = escape_pattern(want)\
- local iterations = limit + math.max(table.unpack((function()\
- local _accum_0 = { }\
- local _len_0 = 1\
- for _index_0 = 1, #have do\
- local type = have[_index_0]\
- _accum_0[_len_0] = count(type)\
- _len_0 = _len_0 + 1\
- end\
- return _accum_0\
- end)()))\
- do\
- local _accum_0 = { }\
- local _len_0 = 1\
- for _index_0 = 1, #have do\
- local start = have[_index_0]\
- _accum_0[_len_0] = {\
- start = start,\
- rest = start,\
- conversions = { }\
- }\
- _len_0 = _len_0 + 1\
- end\
- have = _accum_0\
- end\
- for i = 1, iterations do\
- local next_have, c = { }, 1\
- for _index_0 = 1, #have do\
- local _des_0 = have[_index_0]\
- local start, rest, conversions\
- start, rest, conversions = _des_0.start, _des_0.rest, _des_0.conversions\
- if rest:match(want) then\
- return conversions, start\
- else\
- for _index_1 = 1, #_converts do\
- local _continue_0 = false\
- repeat\
- local convert = _converts[_index_1]\
- local inp = escape_inp(convert.inp)\
- if not (rest:match(inp)) then\
- _continue_0 = true\
- break\
- end\
- local result = rest:gsub(inp, convert.out)\
- if result then\
- next_have[c] = {\
- start = start,\
- rest = result,\
- conversions = {\
- {\
- convert = convert,\
- from = rest,\
- to = result\
- },\
- table.unpack(conversions)\
- }\
- }\
- c = c + 1\
- end\
- _continue_0 = true\
- until true\
- if not _continue_0 then\
- break\
- end\
- end\
- end\
- end\
- have = next_have\
- if not (#have > 0) then\
- return \
- end\
- end\
-end\
-local apply_conversions\
-apply_conversions = function(conversions, value, ...)\
- for i = #conversions, 1, -1 do\
- local step = conversions[i]\
- value = step.convert.transform(step, value, ...)\
- end\
- return value\
-end\
-return {\
- converts = converts,\
- get_conversions = get_conversions,\
- apply_conversions = apply_conversions\
-}\
-", "mmm/mmmfs/conversion.lua") end
-if not p["mmm.mmmfs.fileder"] then p["mmm.mmmfs.fileder"] = load("local require = relative(..., 1)\
-local get_conversions, apply_conversions\
-do\
- local _obj_0 = require('.conversion')\
- get_conversions, apply_conversions = _obj_0.get_conversions, _obj_0.apply_conversions\
-end\
-local Key\
-do\
- local _class_0\
- local _base_0 = {\
- tostring = function(self)\
- if self.name == '' then\
- return self.type\
- else\
- return tostring(self.name) .. \": \" .. tostring(self.type)\
- end\
- end,\
- __tostring = function(self)\
- return self:tostring()\
- end\
- }\
- _base_0.__index = _base_0\
- _class_0 = setmetatable({\
- __init = function(self, opts, second)\
- if 'string' == type(second) then\
- self.name, self.type = (opts or ''), second\
- elseif 'string' == type(opts) then\
- self.name, self.type = opts:match('^([%w-_]+): *(.+)$')\
- if not self.name then\
- self.name = ''\
- self.type = opts\
- end\
- elseif 'table' == type(opts) then\
- self.name = opts.name\
- self.type = opts.type\
- self.original = opts.original\
- self.filename = opts.filename\
- else\
- return error(\"wrong argument type: \" .. tostring(type(opts)) .. \", \" .. tostring(type(second)))\
- end\
- end,\
- __base = _base_0,\
- __name = \"Key\"\
- }, {\
- __index = _base_0,\
- __call = function(cls, ...)\
- local _self_0 = setmetatable({}, _base_0)\
- cls.__init(_self_0, ...)\
- return _self_0\
- end\
- })\
- _base_0.__class = _class_0\
- Key = _class_0\
-end\
-local Fileder\
-do\
- local _class_0\
- local _base_0 = {\
- walk = function(self, path)\
- if path == '' then\
- return self\
- end\
- if '/' ~= path:sub(1, 1) then\
- path = tostring(self.path) .. \"/\" .. tostring(path)\
- end\
- if not (self.path == path:sub(1, #self.path)) then\
- return \
- end\
- if #path == #self.path then\
- return self\
- end\
- local _list_0 = self.children\
- for _index_0 = 1, #_list_0 do\
- local child = _list_0[_index_0]\
- do\
- local match = child:walk(path)\
- if match then\
- return match\
- end\
- end\
- end\
- end,\
- mount = function(self, path, mount_as)\
- if not mount_as then\
- path = path .. self:gett('name: alpha')\
- end\
- assert(not self.path or self.path == path, \"mounted twice: \" .. tostring(self.path) .. \" and now \" .. tostring(path))\
- self.path = path\
- local _list_0 = self.children\
- for _index_0 = 1, #_list_0 do\
- local child = _list_0[_index_0]\
- child:mount(self.path .. '/')\
- end\
- end,\
- iterate = function(self, depth)\
- if depth == nil then\
- depth = 0\
- end\
- coroutine.yield(self)\
- if depth == 1 then\
- return \
- end\
- local _list_0 = self.children\
- for _index_0 = 1, #_list_0 do\
- local child = _list_0[_index_0]\
- child:iterate(depth - 1)\
- end\
- end,\
- get_facets = function(self)\
- local names = { }\
- for key in pairs(self.facets) do\
- names[key.name] = true\
- end\
- local _accum_0 = { }\
- local _len_0 = 1\
- for name in pairs(names) do\
- _accum_0[_len_0] = name\
- _len_0 = _len_0 + 1\
- end\
- return _accum_0\
- end,\
- has = function(self, ...)\
- local want = Key(...)\
- for key in pairs(self.facets) do\
- local _continue_0 = false\
- repeat\
- if key.original then\
- _continue_0 = true\
- break\
- end\
- if key.name == want.name and key.type == want.type then\
- return key\
- end\
- _continue_0 = true\
- until true\
- if not _continue_0 then\
- break\
- end\
- end\
- end,\
- has_facet = function(self, want)\
- for key in pairs(self.facets) do\
- local _continue_0 = false\
- repeat\
- if key.original then\
- _continue_0 = true\
- break\
- end\
- if key.name == want then\
- return key\
- end\
- _continue_0 = true\
- until true\
- if not _continue_0 then\
- break\
- end\
- end\
- end,\
- find = function(self, ...)\
- local want = Key(...)\
- local matching\
- do\
- local _accum_0 = { }\
- local _len_0 = 1\
- for key in pairs(self.facets) do\
- if key.name == want.name then\
- _accum_0[_len_0] = key\
- _len_0 = _len_0 + 1\
- end\
- end\
- matching = _accum_0\
- end\
- if not (#matching > 0) then\
- return \
- end\
- local shortest_path, start = get_conversions(want.type, (function()\
- local _accum_0 = { }\
- local _len_0 = 1\
- for _index_0 = 1, #matching do\
- local key = matching[_index_0]\
- _accum_0[_len_0] = key.type\
- _len_0 = _len_0 + 1\
- end\
- return _accum_0\
- end)())\
- if start then\
- for _index_0 = 1, #matching do\
- local key = matching[_index_0]\
- if key.type == start then\
- return key, shortest_path\
- end\
- end\
- return error(\"couldn't find key after resolution?\")\
- end\
- end,\
- get = function(self, ...)\
- local want = Key(...)\
- local key, conversions = self:find(want)\
- if key then\
- local value = apply_conversions(conversions, self.facets[key], self, key)\
- return value, key\
- end\
- end,\
- gett = function(self, ...)\
- local want = Key(...)\
- local value, key = self:get(want)\
- assert(value, tostring(self) .. \" doesn't have value for '\" .. tostring(want) .. \"'\")\
- return value, key\
- end,\
- __tostring = function(self)\
- return \"Fileder:\" .. tostring(self.path)\
- end\
- }\
- _base_0.__index = _base_0\
- _class_0 = setmetatable({\
- __init = function(self, facets, children)\
- if not children then\
- do\
- local _accum_0 = { }\
- local _len_0 = 1\
- for i, child in ipairs(facets) do\
- facets[i] = nil\
- local _value_0 = child\
- _accum_0[_len_0] = _value_0\
- _len_0 = _len_0 + 1\
- end\
- children = _accum_0\
- end\
- end\
- self.children = setmetatable({ }, {\
- __index = function(t, k)\
- if not ('string' == type(k)) then\
- return rawget(t, k)\
- end\
- return self:walk(tostring(self.path) .. \"/\" .. tostring(k))\
- end,\
- __newindex = function(t, k, child)\
- rawset(t, k, child)\
- if self.path == '/' then\
- return child:mount('/')\
- elseif self.path then\
- return child:mount(self.path .. '/')\
- end\
- end\
- })\
- for i, child in ipairs(children) do\
- self.children[i] = child\
- end\
- self.facets = setmetatable({ }, {\
- __newindex = function(t, key, v)\
- return rawset(t, (Key(key)), v)\
- end\
- })\
- for k, v in pairs(facets) do\
- self.facets[k] = v\
- end\
- end,\
- __base = _base_0,\
- __name = \"Fileder\"\
- }, {\
- __index = _base_0,\
- __call = function(cls, ...)\
- local _self_0 = setmetatable({}, _base_0)\
- cls.__init(_self_0, ...)\
- return _self_0\
- end\
- })\
- _base_0.__class = _class_0\
- Fileder = _class_0\
-end\
-local dir_base\
-dir_base = function(path)\
- local dir, base = path:match('(.-)([^/]-)$')\
- if dir and #dir > 0 then\
- dir = dir:sub(1, #dir - 1)\
- end\
- return dir, base\
-end\
-local load_tree\
-load_tree = function(store, root)\
- if root == nil then\
- root = ''\
- end\
- local fileders = setmetatable({ }, {\
- __index = function(self, path)\
- do\
- local val = Fileder({ })\
- val.path = path\
- rawset(self, path, val)\
- return val\
- end\
- end\
- })\
- root = fileders[root]\
- root.facets['name: alpha'] = ''\
- for fn, ft in store:list_facets(root.path) do\
- local val = store:load_facet(root.path, fn, ft)\
- root.facets[Key(fn, ft)] = val\
- end\
- for path in store:list_all_fileders(root.path) do\
- local fileder = fileders[path]\
- local parent, name = dir_base(path)\
- fileder.facets['name: alpha'] = name\
- table.insert(fileders[parent].children, fileder)\
- for fn, ft in store:list_facets(path) do\
- local val = store:load_facet(path, fn, ft)\
- fileder.facets[Key(fn, ft)] = val\
- end\
- end\
- return root\
-end\
-return {\
- Key = Key,\
- Fileder = Fileder,\
- dir_base = dir_base,\
- load_tree = load_tree\
-}\
-", "mmm/mmmfs/fileder.lua") end
-if not p["mmm.mmmfs"] then p["mmm.mmmfs"] = load("local require = relative(...)\
-local Key, Fileder\
-do\
- local _obj_0 = require('.fileder')\
- Key, Fileder = _obj_0.Key, _obj_0.Fileder\
-end\
-local Browser\
-Browser = require('.browser').Browser\
-return {\
- Key = Key,\
- Fileder = Fileder,\
- Browser = Browser\
-}\
-", "mmm/mmmfs/init.lua") end
-if not p["mmm.mmmfs.util"] then p["mmm.mmmfs.util"] = load("local merge\
-merge = function(orig, extra)\
- if orig == nil then\
- orig = { }\
- end\
- do\
- local attr\
- do\
- local _tbl_0 = { }\
- for k, v in pairs(orig) do\
- _tbl_0[k] = v\
- end\
- attr = _tbl_0\
- end\
- for k, v in pairs(extra) do\
- attr[k] = v\
- end\
- return attr\
- end\
-end\
-local tourl\
-tourl = function(path)\
- if STATIC then\
- return path .. '/'\
- else\
- return path .. '/'\
- end\
-end\
-return function(elements)\
- local a, div, pre\
- a, div, pre = elements.a, elements.div, elements.pre\
- local find_fileder\
- find_fileder = function(fileder, origin)\
- if 'string' == type(fileder) then\
- assert(origin, \"cannot resolve path '\" .. tostring(fileder) .. \"' without origin!\")\
- return assert((origin:walk(fileder)), \"couldn't resolve path '\" .. tostring(fileder) .. \"' from \" .. tostring(origin))\
- else\
- return assert(fileder, \"no fileder passed.\")\
- end\
- end\
- local navigate_to\
- navigate_to = function(path, name, opts)\
- if opts == nil then\
- opts = { }\
- end\
- opts.href = tourl(path)\
- if MODE == 'CLIENT' then\
- opts.onclick = function(self, e)\
- e:preventDefault()\
- return BROWSER:navigate(path)\
- end\
- end\
- return a(name, opts)\
- end\
- local link_to\
- link_to = function(fileder, name, origin, attr)\
- fileder = find_fileder(fileder, origin)\
- name = name or fileder:get('title: mmm/dom')\
- name = name or fileder:gett('name: alpha')\
- do\
- local href = fileder:get('link: URL.*')\
- if href then\
- return a(name, merge(attr, {\
- href = href,\
- target = '_blank'\
- }))\
- else\
- return a(name, merge(attr, {\
- href = tourl(fileder.path),\
- onclick = (function()\
- if MODE == 'CLIENT' then\
- return function(self, e)\
- e:preventDefault()\
- return BROWSER:navigate(fileder.path)\
- end\
- end\
- end)()\
- }))\
- end\
- end\
- end\
- local embed\
- embed = function(fileder, name, origin, opts)\
- if name == nil then\
- name = ''\
- end\
- if opts == nil then\
- opts = { }\
- end\
- fileder = find_fileder(fileder, origin)\
- local ok, node = pcall(fileder.gett, fileder, name, 'mmm/dom')\
- if not ok then\
- return div(\"couldn't embed \" .. tostring(fileder) .. \" \" .. tostring(name), (pre(node)), {\
- style = {\
- background = 'var(--gray-fail)',\
- padding = '1em'\
- }\
- })\
- end\
- local klass = 'embed'\
- if opts.desc then\
- klass = klass .. ' desc'\
- end\
- if opts.inline then\
- klass = klass .. ' inline'\
- end\
- node = div({\
- class = klass,\
- node,\
- (function()\
- if opts.desc then\
- return div(opts.desc, {\
- class = 'description'\
- })\
- end\
- end)()\
- })\
- if opts.nolink then\
- return node\
- end\
- return link_to(fileder, node, nil, opts.attr)\
- end\
- return {\
- find_fileder = find_fileder,\
- link_to = link_to,\
- navigate_to = navigate_to,\
- embed = embed\
- }\
-end\
-", "mmm/mmmfs/util.lua") end
-if not p["mmm.mmmfs.converts"] then p["mmm.mmmfs.converts"] = load("local require = relative(..., 1)\
-local div, code, img, video, blockquote, a, span, source, iframe\
-do\
- local _obj_0 = require('mmm.dom')\
- div, code, img, video, blockquote, a, span, source, iframe = _obj_0.div, _obj_0.code, _obj_0.img, _obj_0.video, _obj_0.blockquote, _obj_0.a, _obj_0.span, _obj_0.source, _obj_0.iframe\
-end\
-local find_fileder, link_to, embed\
-do\
- local _obj_0 = (require('mmm.mmmfs.util'))(require('mmm.dom'))\
- find_fileder, link_to, embed = _obj_0.find_fileder, _obj_0.link_to, _obj_0.embed\
-end\
-local render\
-render = require('.layout').render\
-local tohtml\
-tohtml = require('mmm.component').tohtml\
-local js_fix\
-if MODE == 'CLIENT' then\
- js_fix = function(arg)\
- if arg == js.null then\
- return \
- end\
- return arg\
- end\
-end\
-local single\
-single = function(func)\
- return function(self, val)\
- return func(val)\
- end\
-end\
-local loadwith\
-loadwith = function(_load)\
- return function(self, val, fileder, key)\
- local func = assert(_load(val, tostring(fileder) .. \"#\" .. tostring(key)))\
- return func()\
- end\
-end\
-local converts = {\
- {\
- inp = 'fn -> (.+)',\
- out = '%1',\
- transform = function(self, val, fileder)\
- return val(fileder)\
- end\
- },\
- {\
- inp = 'mmm/component',\
- out = 'mmm/dom',\
- transform = single(tohtml)\
- },\
- {\
- inp = 'mmm/dom',\
- out = 'text/html+frag',\
- transform = function(self, node)\
- if MODE == 'SERVER' then\
- return node\
- else\
- return node.outerHTML\
- end\
- end\
- },\
- {\
- inp = 'mmm/dom',\
- out = 'text/html',\
- transform = function(self, html, fileder)\
- return render(html, fileder)\
- end\
- },\
- {\
- inp = 'text/html%+frag',\
- out = 'mmm/dom',\
- transform = (function()\
- if MODE == 'SERVER' then\
- return function(self, html, fileder)\
- html = html:gsub('<mmm%-link%s+(.-)>(.-)</mmm%-link>', function(attrs, text)\
- if #text == 0 then\
- text = nil\
- end\
- local path = ''\
- while attrs and attrs ~= '' do\
- local key, val, _attrs = attrs:match('^(%w+)=\"([^\"]-)\"%s*(.*)')\
- if not key then\
- key, _attrs = attrs:match('^(%w+)%s*(.*)$')\
- val = true\
- end\
- attrs = _attrs\
- local _exp_0 = key\
- if 'path' == _exp_0 then\
- path = val\
- else\
- warn(\"unkown attribute '\" .. tostring(key) .. \"=\\\"\" .. tostring(val) .. \"\\\"' in <mmm-link>\")\
- end\
- end\
- return link_to(path, text, fileder)\
- end)\
- html = html:gsub('<mmm%-embed%s+(.-)>(.-)</mmm%-embed>', function(attrs, desc)\
- local path, facet = '', ''\
- local opts = { }\
- if #desc ~= 0 then\
- opts.desc = desc\
- end\
- while attrs and attrs ~= '' do\
- local key, val, _attrs = attrs:match('^(%w+)=\"([^\"]-)\"%s*(.*)')\
- if not key then\
- key, _attrs = attrs:match('^(%w+)%s*(.*)$')\
- val = true\
- end\
- attrs = _attrs\
- local _exp_0 = key\
- if 'path' == _exp_0 then\
- path = val\
- elseif 'facet' == _exp_0 then\
- facet = val\
- elseif 'nolink' == _exp_0 then\
- opts.nolink = true\
- elseif 'inline' == _exp_0 then\
- opts.inline = true\
- else\
- warn(\"unkown attribute '\" .. tostring(key) .. \"=\\\"\" .. tostring(val) .. \"\\\"' in <mmm-embed>\")\
- end\
- end\
- return embed(path, facet, fileder, opts)\
- end)\
- return html\
- end\
- else\
- return function(self, html, fileder)\
- local parent\
- do\
- local _with_0 = document:createElement('div')\
- _with_0.innerHTML = html\
- local embeds = _with_0:getElementsByTagName('mmm-embed')\
- do\
- local _accum_0 = { }\
- local _len_0 = 1\
- for i = 0, embeds.length - 1 do\
- _accum_0[_len_0] = embeds[i]\
- _len_0 = _len_0 + 1\
- end\
- embeds = _accum_0\
- end\
- for _index_0 = 1, #embeds do\
- local element = embeds[_index_0]\
- local path = js_fix(element:getAttribute('path'))\
- local facet = js_fix(element:getAttribute('facet'))\
- local nolink = js_fix(element:getAttribute('nolink'))\
- local inline = js_fix(element:getAttribute('inline'))\
- local desc = js_fix(element.innerText)\
- element:replaceWith(embed(path or '', facet or '', fileder, {\
- nolink = nolink,\
- inline = inline,\
- desc = desc\
- }))\
- end\
- embeds = _with_0:getElementsByTagName('mmm-link')\
- do\
- local _accum_0 = { }\
- local _len_0 = 1\
- for i = 0, embeds.length - 1 do\
- _accum_0[_len_0] = embeds[i]\
- _len_0 = _len_0 + 1\
- end\
- embeds = _accum_0\
- end\
- for _index_0 = 1, #embeds do\
- local element = embeds[_index_0]\
- local text = js_fix(element.innerText)\
- local path = js_fix(element:getAttribute('path'))\
- element:replaceWith(link_to(path or '', text, fileder))\
- end\
- parent = _with_0\
- end\
- assert(1 == parent.childElementCount, \"text/html with more than one child!\")\
- return parent.firstElementChild\
- end\
- end\
- end)()\
- },\
- {\
- inp = 'text/lua -> (.+)',\
- out = '%1',\
- transform = loadwith(load or loadstring)\
- },\
- {\
- inp = 'mmm/tpl -> (.+)',\
- out = '%1',\
- transform = function(self, source, fileder)\
- return source:gsub('{{(.-)}}', function(expr)\
- local path, facet = expr:match('^([%w%-_%./]*)%+(.*)')\
- assert(path, \"couldn't match TPL expression '\" .. tostring(expr) .. \"'\")\
- return (find_fileder(path, fileder)):gett(facet)\
- end)\
- end\
- },\
- {\
- inp = 'time/iso8601-date',\
- out = 'time/unix',\
- transform = function(self, val)\
- local year, _, month, day = val:match('^%s*(%d%d%d%d)(%-?)([01]%d)%2([0-3]%d)%s*$')\
- assert(year, \"failed to parse ISO 8601 date: '\" .. tostring(val) .. \"'\")\
- return os.time({\
- year = year,\
- month = month,\
- day = day\
- })\
- end\
- },\
- {\
- inp = 'URL -> twitter/tweet',\
- out = 'mmm/dom',\
- transform = function(self, href)\
- local id = assert((href:match('twitter.com/[^/]-/status/(%d*)')), \"couldn't parse twitter/tweet URL: '\" .. tostring(href) .. \"'\")\
- if MODE == 'CLIENT' then\
- do\
- local parent = div()\
- window.twttr.widgets:createTweet(id, parent)\
- return parent\
- end\
- else\
- return div(blockquote({\
- class = 'twitter-tweet',\
- ['data-lang'] = 'en',\
- a('(linked tweet)', {\
- href = href\
- })\
- }))\
- end\
- end\
- },\
- {\
- inp = 'URL -> youtube/video',\
- out = 'mmm/dom',\
- transform = function(self, link)\
- local id = link:match('youtu%.be/([^/]+)')\
- id = id or link:match('youtube.com/watch.*[?&]v=([^&]+)')\
- id = id or link:match('youtube.com/[ev]/([^/]+)')\
- id = id or link:match('youtube.com/embed/([^/]+)')\
- assert(id, \"couldn't parse youtube URL: '\" .. tostring(link) .. \"'\")\
- return iframe({\
- width = 560,\
- height = 315,\
- frameborder = 0,\
- allowfullscreen = true,\
- frameBorder = 0,\
- src = \"//www.youtube.com/embed/\" .. tostring(id)\
- })\
- end\
- },\
- {\
- inp = 'URL -> image/.+',\
- out = 'mmm/dom',\
- transform = function(self, src, fileder)\
- return img({\
- src = src\
- })\
- end\
- },\
- {\
- inp = 'URL -> video/.+',\
- out = 'mmm/dom',\
- transform = function(self, src)\
- return video((source({\
- src = src\
- })), {\
- controls = true,\
- loop = true\
- })\
- end\
- },\
- {\
- inp = 'text/plain',\
- out = 'mmm/dom',\
- transform = function(self, val)\
- return span(val)\
- end\
- },\
- {\
- inp = 'alpha',\
- out = 'mmm/dom',\
- transform = single(code)\
- },\
- {\
- inp = '(.+)',\
- out = 'URL -> %1',\
- transform = function(self, _, fileder, key)\
- return tostring(fileder.path) .. \"/\" .. tostring(key.name) .. \":\" .. tostring(self.from)\
- end\
- }\
-}\
-if MODE == 'SERVER' then\
- local ok, moon = pcall(require, 'moonscript.base')\
- if ok then\
- local _load = moon.load or moon.loadstring\
- table.insert(converts, {\
- inp = 'text/moonscript -> (.+)',\
- out = '%1',\
- transform = loadwith(moon.load or moon.loadstring)\
- })\
- table.insert(converts, {\
- inp = 'text/moonscript -> (.+)',\
- out = 'text/lua -> %1',\
- transform = single(moon.to_lua)\
- })\
- end\
-else\
- table.insert(converts, {\
- inp = 'text/javascript -> (.+)',\
- out = '%1',\
- transform = function(self, source)\
- local f = js.new(window.Function, source)\
- return f()\
- end\
- })\
-end\
-do\
- local markdown\
- if MODE == 'SERVER' then\
- local success, discount = pcall(require, 'discount')\
- if not success then\
- warn(\"NO MARKDOWN SUPPORT!\", discount)\
- end\
- markdown = success and function(md)\
- local res = assert(discount.compile(md, 'githubtags'))\
- return res.body\
- end\
- else\
- markdown = window and window.marked and (function()\
- local _base_0 = window\
- local _fn_0 = _base_0.marked\
- return function(...)\
- return _fn_0(_base_0, ...)\
- end\
- end)()\
- end\
- if markdown then\
- table.insert(converts, {\
- inp = 'text/markdown',\
- out = 'text/html+frag',\
- transform = function(self, md)\
- return \"<div class=\\\"markdown\\\">\" .. tostring(markdown(md)) .. \"</div>\"\
- end\
- })\
- table.insert(converts, {\
- inp = 'text/markdown%+span',\
- out = 'mmm/dom',\
- transform = (function()\
- if MODE == 'SERVER' then\
- return function(self, source)\
- local html = markdown(source)\
- html = html:gsub('^<p', '<span')\
- return html:gsub('/p>$', '/span>')\
- end\
- else\
- return function(self, source)\
- local html = markdown(source)\
- html = html:gsub('^%s*<p>%s*', '')\
- html = html:gsub('%s*</p>%s*$', '')\
- do\
- local _with_0 = document:createElement('span')\
- _with_0.innerHTML = html\
- return _with_0\
- end\
- end\
- end\
- end)()\
- })\
- end\
-end\
-return converts\
-", "mmm/mmmfs/converts.lua") end
-if not p["mmm.mmmfs.layout"] then p["mmm.mmmfs.layout"] = load("local require = relative(..., 1)\
-local header, aside, footer, div, svg, script, g, circle, h1, span, b, a, img\
-do\
- local _obj_0 = require('mmm.dom')\
- header, aside, footer, div, svg, script, g, circle, h1, span, b, a, img = _obj_0.header, _obj_0.aside, _obj_0.footer, _obj_0.div, _obj_0.svg, _obj_0.script, _obj_0.g, _obj_0.circle, _obj_0.h1, _obj_0.span, _obj_0.b, _obj_0.a, _obj_0.img\
-end\
-local navigate_to\
-navigate_to = (require('mmm.mmmfs.util'))(require('mmm.dom')).navigate_to\
-local pick\
-pick = function(...)\
- local num = select('#', ...)\
- local i = math.ceil(math.random() * num)\
- return (select(i, ...))\
-end\
-local iconlink\
-iconlink = function(href, src, alt, style)\
- return a({\
- class = 'iconlink',\
- target = '_blank',\
- rel = 'me',\
- href = href,\
- img({\
- src = src,\
- alt = alt,\
- style = style\
- })\
- })\
-end\
-local logo = svg({\
- class = 'sun',\
- viewBox = '-0.75 -1 1.5 2',\
- xmlns = 'http://www.w3.org/2000/svg',\
- baseProfile = 'full',\
- version = '1.1',\
- g({\
- transform = 'translate(0 .18)',\
- g({\
- class = 'circle out',\
- circle({\
- r = '.6',\
- fill = 'none',\
- ['stroke-width'] = '.12'\
- })\
- }),\
- g({\
- class = 'circle in',\
- circle({\
- r = '.2',\
- stroke = 'none'\
- })\
- })\
- })\
-})\
-local gen_header\
-gen_header = function()\
- return header({\
- div({\
- h1({\
- navigate_to('', logo),\
- span({\
- span('mmm', {\
- class = 'bold'\
- }),\
- '&#8203;',\
- '.s&#8209;ol.nu'\
- })\
- }),\
- table.concat({\
- pick('fun', 'cool', 'weird', 'interesting', 'new', 'pleasant'),\
- pick('stuff', 'things', 'projects', 'experiments', 'visuals', 'ideas'),\
- pick(\"with\", 'and'),\
- pick('mostly code', 'code and wires', 'silicon', 'electronics', 'shaders', 'oscilloscopes', 'interfaces', 'hardware', 'FPGAs')\
- }, ' ')\
- }),\
- aside({\
- navigate_to('/about', 'about me'),\
- navigate_to('/games', 'games'),\
- navigate_to('/projects', 'other'),\
- a({\
- href = 'mailto:s%20[removethis]%20[at]%20s-ol.nu',\
- 'contact',\
- script(\"\\n var l = document.currentScript.parentElement;\\n l.href = l.href.replace('%20[at]%20', '@');\\n l.href = l.href.replace('%20[removethis]', '') + '?subject=Hey there :)';\\n \")\
- })\
- })\
- })\
-end\
-footer = footer({\
- span({\
- 'made with \\xe2\\x98\\xbd by ',\
- a('s-ol', {\
- href = 'https://twitter.com/S0lll0s'\
- }),\
- \", \" .. tostring(os.date('%Y'))\
- }),\
- div({\
- class = 'icons',\
- iconlink('https://github.com/s-ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/github.svg', 'github'),\
- iconlink('https://merveilles.town/@s_ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/mastodon.svg', 'mastodon'),\
- iconlink('https://twitter.com/S0lll0s', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/twitter.svg', 'twitter'),\
- iconlink('https://webring.xxiivv.com/#random', 'https://webring.xxiivv.com/icon.black.svg', 'webring', {\
- height = '1.3em',\
- ['margin-left'] = '.3em',\
- ['margin-top'] = '-0.12em'\
- })\
- })\
-})\
-local get_meta\
-get_meta = function(self)\
- local title = (self:get('title: text/plain')) or self:gett('name: alpha')\
- local l\
- l = function(str)\
- str = str:gsub('[%s\\\\n]+$', '')\
- return str:gsub('\\\\n', ' ')\
- end\
- local e\
- e = function(str)\
- return string.format('%q', l(str))\
- end\
- local meta = \"\\n <meta charset=\\\"UTF-8\\\">\\n <title>\" .. tostring(l(title)) .. \"</title>\\n \"\
- do\
- local page_meta = self:get('_meta: mmm/dom')\
- if page_meta then\
- meta = meta .. page_meta\
- else\
- meta = meta .. \"\\n <meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1\\\">\\n\\n <meta property=\\\"og:title\\\" content=\" .. tostring(e(title)) .. \" />\\n <meta property=\\\"og:type\\\" content=\\\"website\\\" />\\n <meta property=\\\"og:url\\\" content=\\\"https://mmm.s-ol.nu\" .. tostring(self.path) .. \"/\\\" />\\n <meta property=\\\"og:site_name\\\" content=\\\"mmm\\\" />\"\
- do\
- local desc = self:get('description: text/plain')\
- if desc then\
- meta = meta .. \"\\n <meta property=\\\"og:description\\\" content=\" .. tostring(e(desc)) .. \" />\"\
- end\
- end\
- end\
- end\
- return meta\
-end\
-local render\
-render = function(content, fileder, opts)\
- if opts == nil then\
- opts = { }\
- end\
- opts.meta = opts.meta or get_meta(fileder)\
- opts.scripts = opts.scripts or ''\
- if not (opts.noview) then\
- content = [[ <div class=\"view main\">\
- <div class=\"content\">\
- ]] .. content .. [[ </div>\
- </div>\
- ]]\
- end\
- local buf = [[<!DOCTYPE html>\
-<html>\
- <head>\
- <link rel=\"stylesheet\" type=\"text/css\" href=\"/static/style/:text/css\" />\
- <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,600\" />\
- ]]\
- buf = buf .. \"\\n \" .. tostring(get_meta(fileder)) .. \"\\n </head>\\n <body>\\n \" .. tostring(gen_header()) .. \"\\n\\n \" .. tostring(content) .. \"\\n\\n \" .. tostring(footer) .. \"\\n \"\
- buf = buf .. [[ <script type=\"application/javascript\" src=\"/static/highlight-pack/:application/javascript\"></script>\
- <script type=\"application/javascript\" src=\"//cdnjs.cloudflare.com/ajax/libs/marked/0.5.1/marked.min.js\"></script>\
- <script type=\"application/javascript\" src=\"//cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.6/svg.min.js\"></script>\
- <script type=\"application/javascript\" src=\"//platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>\
- <script type=\"application/javascript\" src=\"/static/fengari-web/:application/javascript\"></script>\
- <script type=\"application/lua\" src=\"/static/mmm/:application/lua\"></script>\
- <script type=\"application/lua\">require 'mmm'</script>\
- ]]\
- buf = buf .. opts.scripts\
- buf = buf .. \"\\n </body>\\n</html>\\n \"\
- return buf\
-end\
-return {\
- render = render\
-}\
-", "mmm/mmmfs/layout.lua") end
-if not p["mmm.mmmfs.stores.fs"] then p["mmm.mmmfs.stores.fs"] = load("local lfs = require('lfs')\
-local dir_base\
-dir_base = function(path)\
- local dir, base = path:match('(.-)([^/]-)$')\
- if dir and #dir > 0 then\
- dir = dir:sub(1, #dir - 1)\
- end\
- return dir, base\
-end\
-local FSStore\
-do\
- local _class_0\
- local _base_0 = {\
- log = function(self, ...)\
- return print(\"[DB]\", ...)\
- end,\
- list_fileders_in = function(self, path)\
- if path == nil then\
- path = ''\
- end\
- return coroutine.wrap(function()\
- for entry_name in lfs.dir(self.root .. path) do\
- local _continue_0 = false\
- repeat\
- if '.' == entry_name:sub(1, 1) then\
- _continue_0 = true\
- break\
- end\
- local entry_path = self.root .. tostring(path) .. \"/\" .. tostring(entry_name)\
- if 'directory' == lfs.attributes(entry_path, 'mode') then\
- coroutine.yield(tostring(path) .. \"/\" .. tostring(entry_name))\
- end\
- _continue_0 = true\
- until true\
- if not _continue_0 then\
- break\
- end\
- end\
- end)\
- end,\
- list_all_fileders = function(self, path)\
- if path == nil then\
- path = ''\
- end\
- return coroutine.wrap(function()\
- for path in self:list_fileders_in(path) do\
- coroutine.yield(path)\
- for p in self:list_all_fileders(path) do\
- coroutine.yield(p)\
- end\
- end\
- end)\
- end,\
- create_fileder = function(self, parent, name)\
- self:log(\"creating fileder \" .. tostring(path))\
- local path = tostring(parent) .. \"/\" .. tostring(name)\
- assert(lfs.mkdir(self.root .. path))\
- return path\
- end,\
- remove_fileder = function(self, path)\
- self:log(\"removing fileder \" .. tostring(path))\
- local rmdir\
- rmdir = function(path)\
- for file in lfs.dir(path) do\
- local _continue_0 = false\
- repeat\
- if '.' == file:sub(1, 1) then\
- _continue_0 = true\
- break\
- end\
- local file_path = tostring(path) .. \"/\" .. tostring(file)\
- local _exp_0 = lfs.attributes(file_path, 'mode')\
- if 'file' == _exp_0 then\
- assert(os.remove(file_path))\
- elseif 'directory' == _exp_0 then\
- assert(rmdir(file_path))\
- end\
- _continue_0 = true\
- until true\
- if not _continue_0 then\
- break\
- end\
- end\
- return lfs.rmdir(path)\
- end\
- return rmdir(self.root .. path)\
- end,\
- rename_fileder = function(self, path, next_name)\
- self:log(\"renaming fileder \" .. tostring(path) .. \" -> '\" .. tostring(next_name) .. \"'\")\
- local parent, name = dir_base(path)\
- return assert(os.rename(path, self.root .. tostring(parent) .. \"/\" .. tostring(next_name)))\
- end,\
- move_fileder = function(self, path, next_parent)\
- self:log(\"moving fileder \" .. tostring(path) .. \" -> \" .. tostring(next_parent) .. \"/\")\
- local parent, name = dir_base(path)\
- return assert(os.rename(self.root .. path, self.root .. tostring(next_parent) .. \"/\" .. tostring(name)))\
- end,\
- list_facets = function(self, path)\
- return coroutine.wrap(function()\
- for entry_name in lfs.dir(self.root .. path) do\
- local entry_path = tostring(self.root .. path) .. \"/\" .. tostring(entry_name)\
- if 'file' == lfs.attributes(entry_path, 'mode') then\
- entry_name = (entry_name:match('(.*)%.%w+')) or entry_name\
- entry_name = entry_name:gsub('%$', '/')\
- local name, type = entry_name:match('([%w-_]+): *(.+)')\
- if not name then\
- name = ''\
- type = entry_name\
- end\
- coroutine.yield(name, type)\
- end\
- end\
- end)\
- end,\
- tofp = function(self, path, name, type)\
- if #name > 0 then\
- type = tostring(name) .. \": \" .. tostring(type)\
- end\
- type = type:gsub('%/', '$')\
- return self.root .. tostring(path) .. \"/\" .. tostring(type)\
- end,\
- locate = function(self, path, name, type)\
- if not (lfs.attributes(self.root .. path, 'mode')) then\
- return \
- end\
- type = type:gsub('%/', '$')\
- if #name > 0 then\
- name = tostring(name) .. \": \"\
- end\
- name = name .. type\
- name = name:gsub('([^%w])', '%%%1')\
- local file_name\
- for entry_name in lfs.dir(self.root .. path) do\
- if (entry_name:match(\"^\" .. tostring(name) .. \"$\")) or entry_name:match(\"^\" .. tostring(name) .. \"%.%w+$\") then\
- if file_name then\
- error(\"two files match \" .. tostring(name) .. \": \" .. tostring(file_name) .. \" and \" .. tostring(entry_name) .. \"!\")\
- end\
- file_name = entry_name\
- end\
- end\
- return file_name and self.root .. tostring(path) .. \"/\" .. tostring(file_name)\
- end,\
- load_facet = function(self, path, name, type)\
- local filepath = self:locate(path, name, type)\
- if not (filepath) then\
- return \
- end\
- local file = assert((io.open(filepath, 'rb')), \"couldn't open facet file '\" .. tostring(filepath) .. \"'\")\
- do\
- local _with_0 = file:read('*all')\
- file:close()\
- return _with_0\
- end\
- end,\
- create_facet = function(self, path, name, type, blob)\
- self:log(\"creating facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\
- assert(blob, \"cant create facet without value!\")\
- local filepath = self:tofp(path, name, type)\
- if lfs.attributes(filepath, 'mode') then\
- error(\"facet file already exists!\")\
- end\
- local file = assert((io.open(filepath, 'wb')), \"couldn't open facet file '\" .. tostring(filepath) .. \"'\")\
- file:write(blob)\
- return file:close()\
- end,\
- remove_facet = function(self, path, name, type)\
- self:log(\"removing facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\
- local filepath = self:locate(path, name, type)\
- assert(filepath, \"couldn't locate facet!\")\
- return assert(os.remove(filepath))\
- end,\
- rename_facet = function(self, path, name, type, next_name)\
- self:log(\"renaming facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type) .. \" -> \" .. tostring(next_name))\
- local filepath = self:locate(path, name, type)\
- assert(filepath, \"couldn't locate facet!\")\
- return assert(os.rename(filepath, self:tofp(path, next_name, type)))\
- end,\
- update_facet = function(self, path, name, type, blob)\
- self:log(\"updating facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\
- local filepath = self:locate(path, name, type)\
- assert(filepath, \"couldn't locate facet!\")\
- local file = assert((io.open(filepath, 'wb')), \"couldn't open facet file '\" .. tostring(filepath) .. \"'\")\
- file:write(blob)\
- return file:close()\
- end\
- }\
- _base_0.__index = _base_0\
- _class_0 = setmetatable({\
- __init = function(self, opts)\
- if opts == nil then\
- opts = { }\
- end\
- opts.root = opts.root or 'root'\
- opts.verbose = opts.verbose or false\
- if not opts.verbose then\
- self.log = function() end\
- end\
- self.root = opts.root:match('^(.-)/?$')\
- return self:log(\"opening '\" .. tostring(opts.root) .. \"'...\")\
- end,\
- __base = _base_0,\
- __name = \"FSStore\"\
- }, {\
- __index = _base_0,\
- __call = function(cls, ...)\
- local _self_0 = setmetatable({}, _base_0)\
- cls.__init(_self_0, ...)\
- return _self_0\
- end\
- })\
- _base_0.__class = _class_0\
- FSStore = _class_0\
-end\
-return {\
- FSStore = FSStore\
-}\
-", "mmm/mmmfs/stores/fs.lua") end
-if not p["mmm.mmmfs.stores"] then p["mmm.mmmfs.stores"] = load("local require = relative(..., 0)\
-local get_store\
-get_store = function(args, opts)\
- if args == nil then\
- args = 'sql'\
- end\
- if opts == nil then\
- opts = {\
- verbose = true\
- }\
- end\
- local type, arg = args:match('(%w+):(.*)')\
- if not (type) then\
- type = args\
- end\
- local _exp_0 = type:lower()\
- if 'sql' == _exp_0 then\
- local SQLStore\
- SQLStore = require('.sql').SQLStore\
- if arg == 'MEMORY' then\
- opts.memory = true\
- else\
- opts.file = arg\
- end\
- return SQLStore(opts)\
- elseif 'fs' == _exp_0 then\
- local FSStore\
- FSStore = require('.fs').FSStore\
- opts.root = arg\
- return FSStore(opts)\
- else\
- warn(\"unknown or missing value for STORE: valid types values are sql, fs\")\
- return os.exit(1)\
- end\
-end\
-return {\
- get_store = get_store\
-}\
-", "mmm/mmmfs/stores/init.lua") end
-if not p["mmm.mmmfs.stores.sql"] then p["mmm.mmmfs.stores.sql"] = load("local sqlite = require('sqlite3')\
-local root = os.tmpname()\
-local SQLStore\
-do\
- local _class_0\
- local _base_0 = {\
- log = function(self, ...)\
- return print(\"[DB]\", ...)\
- end,\
- close = function(self)\
- return self.db:close()\
- end,\
- fetch = function(self, q, ...)\
- local stmt = assert(self.db:prepare(q))\
- if 0 < select('#', ...) then\
- stmt:bind(...)\
- end\
- return stmt:irows()\
- end,\
- fetch_one = function(self, q, ...)\
- local stmt = assert(self.db:prepare(q))\
- if 0 < select('#', ...) then\
- stmt:bind(...)\
- end\
- return stmt:first_irow()\
- end,\
- exec = function(self, q, ...)\
- local stmt = assert(self.db:prepare(q))\
- if 0 < select('#', ...) then\
- stmt:bind(...)\
- end\
- local res = assert(stmt:exec())\
- end,\
- list_fileders_in = function(self, path)\
- if path == nil then\
- path = ''\
- end\
- return coroutine.wrap(function()\
- for _des_0 in self:fetch('SELECT path\\n FROM fileder WHERE parent IS ?', path) do\
- path = _des_0[1]\
- coroutine.yield(path)\
- end\
- end)\
- end,\
- list_all_fileders = function(self, path)\
- if path == nil then\
- path = ''\
- end\
- return coroutine.wrap(function()\
- for path in self:list_fileders_in(path) do\
- coroutine.yield(path)\
- for p in self:list_all_fileders(path) do\
- coroutine.yield(p)\
- end\
- end\
- end)\
- end,\
- create_fileder = function(self, parent, name)\
- local path = tostring(parent) .. \"/\" .. tostring(name)\
- self:log(\"creating fileder \" .. tostring(path))\
- self:exec('INSERT INTO fileder (path, parent)\\n VALUES (:path, :parent)', {\
- path = path,\
- parent = parent\
- })\
- local changes = self:fetch_one('SELECT changes()')\
- assert(changes[1] == 1, \"couldn't create fileder - parent missing?\")\
- return path\
- end,\
- remove_fileder = function(self, path)\
- self:log(\"removing fileder \" .. tostring(path))\
- return self:exec('DELETE FROM fileder\\n WHERE path LIKE :path || \"/%\"\\n OR path = :path', path)\
- end,\
- rename_fileder = function(self, path, next_name)\
- self:log(\"renaming fileder \" .. tostring(path) .. \" -> '\" .. tostring(next_name) .. \"'\")\
- error('not implemented')\
- return self:exec('UPDATE fileder\\n SET path = parent || \"/\" || :next_name\\n WHERE path = :path', {\
- path = path,\
- next_name = next_name\
- })\
- end,\
- move_fileder = function(self, path, next_parent)\
- self:log(\"moving fileder \" .. tostring(path) .. \" -> \" .. tostring(next_parent) .. \"/\")\
- return error('not implemented')\
- end,\
- list_facets = function(self, path)\
- return coroutine.wrap(function()\
- for _des_0 in self:fetch('SELECT facet.name, facet.type\\n FROM facet\\n INNER JOIN fileder ON facet.fileder_id = fileder.id\\n WHERE fileder.path = ?', path) do\
- local name, type\
- name, type = _des_0[1], _des_0[2]\
- coroutine.yield(name, type)\
- end\
- end)\
- end,\
- load_facet = function(self, path, name, type)\
- local v = self:fetch_one('SELECT facet.value\\n FROM facet\\n INNER JOIN fileder ON facet.fileder_id = fileder.id\\n WHERE fileder.path = :path\\n AND facet.name = :name\\n AND facet.type = :type', {\
- path = path,\
- name = name,\
- type = type\
- })\
- return v and v[1]\
- end,\
- create_facet = function(self, path, name, type, blob)\
- self:log(\"creating facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\
- self:exec('INSERT INTO facet (fileder_id, name, type, value)\\n SELECT id, :name, :type, :blob\\n FROM fileder\\n WHERE fileder.path = :path', {\
- path = path,\
- name = name,\
- type = type,\
- blob = blob\
- })\
- local changes = self:fetch_one('SELECT changes()')\
- return assert(changes[1] == 1, \"couldn't create facet - fileder missing?\")\
- end,\
- remove_facet = function(self, path, name, type)\
- self:log(\"removing facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\
- self:exec('DELETE FROM facet\\n WHERE name = :name\\n AND type = :type\\n AND fileder_id = (SELECT id FROM fileder WHERE path = :path)', {\
- path = path,\
- name = name,\
- type = type\
- })\
- local changes = self:fetch_one('SELECT changes()')\
- return assert(changes[1] == 1, \"no such facet\")\
- end,\
- rename_facet = function(self, path, name, type, next_name)\
- self:log(\"renaming facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type) .. \" -> \" .. tostring(next_name))\
- self:exec('UPDATE facet\\n SET name = :next_name\\n WHERE name = :name\\n AND type = :type\\n AND fileder_id = (SELECT id FROM fileder WHERE path = :path)', {\
- path = path,\
- name = name,\
- next_name = next_name,\
- type = type\
- })\
- local changes = self:fetch_one('SELECT changes()')\
- return assert(changes[1] == 1, \"no such facet\")\
- end,\
- update_facet = function(self, path, name, type, blob)\
- self:log(\"updating facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\
- self:exec('UPDATE facet\\n SET value = :blob\\n WHERE facet.name = :name\\n AND facet.type = :type\\n AND facet.fileder_id = (SELECT id FROM fileder WHERE path = :path)', {\
- path = path,\
- name = name,\
- type = type,\
- blob = blob\
- })\
- local changes = self:fetch_one('SELECT changes()')\
- return assert(changes[1] == 1, \"no such facet\")\
- end\
- }\
- _base_0.__index = _base_0\
- _class_0 = setmetatable({\
- __init = function(self, opts)\
- if opts == nil then\
- opts = { }\
- end\
- opts.file = opts.file or 'db.sqlite3'\
- opts.verbose = opts.verbose or false\
- opts.memory = opts.memory or false\
- if not opts.verbose then\
- self.log = function() end\
- end\
- if opts.memory then\
- self:log(\"opening in-memory DB...\")\
- self.db = sqlite.open_memory()\
- else\
- self:log(\"opening '\" .. tostring(opts.file) .. \"'...\")\
- self.db = sqlite.open(opts.file)\
- end\
- return assert(self.db:exec([[ PRAGMA foreign_keys = ON;\
- PRAGMA case_sensitive_like = ON;\
- CREATE TABLE IF NOT EXISTS fileder (\
- id INTEGER NOT NULL PRIMARY KEY,\
- path TEXT NOT NULL UNIQUE,\
- parent TEXT REFERENCES fileder(path)\
- ON DELETE CASCADE\
- ON UPDATE CASCADE\
- );\
- INSERT OR IGNORE INTO fileder (path, parent) VALUES (\"\", NULL);\
-\
- CREATE TABLE IF NOT EXISTS facet (\
- fileder_id INTEGER NOT NULL\
- REFERENCES fileder\
- ON UPDATE CASCADE\
- ON DELETE CASCADE,\
- name TEXT NOT NULL,\
- type TEXT NOT NULL,\
- value BLOB NOT NULL,\
- PRIMARY KEY (fileder_id, name, type)\
- );\
- CREATE INDEX IF NOT EXISTS facet_fileder_id ON facet(fileder_id);\
- CREATE INDEX IF NOT EXISTS facet_name ON facet(name);\
- ]]))\
- end,\
- __base = _base_0,\
- __name = \"SQLStore\"\
- }, {\
- __index = _base_0,\
- __call = function(cls, ...)\
- local _self_0 = setmetatable({}, _base_0)\
- cls.__init(_self_0, ...)\
- return _self_0\
- end\
- })\
- _base_0.__class = _class_0\
- SQLStore = _class_0\
-end\
-return {\
- SQLStore = SQLStore\
-}\
-", "mmm/mmmfs/stores/sql.lua") end
-if not p["mmm.dom"] then p["mmm.dom"] = load("local element\
-element = function(element)\
- return function(...)\
- local children = {\
- ...\
- }\
- local attributes = children[#children]\
- if 'table' == (type(attributes)) and not attributes.node then\
- table.remove(children)\
- else\
- attributes = { }\
- end\
- do\
- local e = document:createElement(element)\
- for k, v in pairs(attributes) do\
- if k == 'class' then\
- k = 'className'\
- end\
- if k == 'style' and 'table' == type(v) then\
- for kk, vv in pairs(v) do\
- e.style[kk] = vv\
- end\
- elseif 'string' == type(k) then\
- e[k] = v\
- end\
- end\
- if #children == 0 then\
- children = attributes\
- end\
- for _index_0 = 1, #children do\
- local child = children[_index_0]\
- if 'string' == type(child) then\
- child = document:createTextNode(child)\
- end\
- e:appendChild(child)\
- end\
- return e\
- end\
- end\
-end\
-return setmetatable({ }, {\
- __index = function(self, name)\
- do\
- local val = element(name)\
- self[name] = val\
- return val\
- end\
- end\
-})\
-", "mmm/dom/init.client.lua") end
-if not p["mmm.component"] then p["mmm.component"] = load("local tohtml\
-tohtml = function(val)\
- if 'string' == type(val) then\
- return document:createTextNode(val)\
- end\
- if 'table' == type(val) then\
- assert(val.node, \"Table doesn't have .node\")\
- val = val.node\
- end\
- if 'userdata' == type(val) then\
- assert((js.instanceof(val, js.global.Node)), \"userdata is not a Node\")\
- return val\
- else\
- return error(\"not a Node: \" .. tostring(val) .. \", \" .. tostring(type(val)))\
- end\
-end\
-local text\
-text = function(str)\
- return document:createTextNode(tostring(str))\
-end\
-local ReactiveVar\
-do\
- local _class_0\
- local _base_0 = {\
- set = function(self, value)\
- local old = self.value\
- self.value = value\
- for k, callback in pairs(self.listeners) do\
- callback(self.value, old)\
- end\
- end,\
- get = function(self)\
- return self.value\
- end,\
- transform = function(self, transform)\
- return self:set(transform(self:get()))\
- end,\
- subscribe = function(self, callback)\
- do\
- local _with_0\
- _with_0 = function()\
- self.listeners[callback] = nil\
- end\
- self.listeners[callback] = callback\
- return _with_0\
- end\
- end,\
- map = function(self, transform)\
- do\
- local _with_0 = ReactiveVar(transform(self.value))\
- _with_0.upstream = self:subscribe(function(...)\
- return _with_0:set(transform(...))\
- end)\
- return _with_0\
- end\
- end\
- }\
- _base_0.__index = _base_0\
- _class_0 = setmetatable({\
- __init = function(self, value)\
- self.value = value\
- self.listeners = setmetatable({ }, {\
- __mode = 'kv'\
- })\
- end,\
- __base = _base_0,\
- __name = \"ReactiveVar\"\
- }, {\
- __index = _base_0,\
- __call = function(cls, ...)\
- local _self_0 = setmetatable({}, _base_0)\
- cls.__init(_self_0, ...)\
- return _self_0\
- end\
- })\
- _base_0.__class = _class_0\
- local self = _class_0\
- self.isinstance = function(val)\
- return 'table' == (type(val)) and val.subscribe\
- end\
- ReactiveVar = _class_0\
-end\
-local ReactiveElement\
-do\
- local _class_0\
- local _base_0 = {\
- destroy = function(self)\
- local _list_0 = self._subscriptions\
- for _index_0 = 1, #_list_0 do\
- local unsub = _list_0[_index_0]\
- unsub()\
- end\
- end,\
- set = function(self, attr, value)\
- if attr == 'class' then\
- attr = 'className'\
- end\
- if 'table' == (type(value)) and ReactiveVar.isinstance(value) then\
- table.insert(self._subscriptions, value:subscribe(function(...)\
- return self:set(attr, ...)\
- end))\
- value = value:get()\
- end\
- if attr == 'style' and 'table' == type(value) then\
- for k, v in pairs(value) do\
- self.node.style[k] = v\
- end\
- return \
- end\
- self.node[attr] = value\
- end,\
- prepend = function(self, child, last)\
- return self:append(child, last, 'prepend')\
- end,\
- append = function(self, child, last, mode)\
- if mode == nil then\
- mode = 'append'\
- end\
- if ReactiveVar.isinstance(child) then\
- table.insert(self._subscriptions, child:subscribe(function(...)\
- return self:append(...)\
- end))\
- child = child:get()\
- end\
- if 'string' == type(last) then\
- error('cannot replace string node')\
- end\
- if child == nil then\
- if last then\
- self:remove(last)\
- end\
- return \
- end\
- child = tohtml(child)\
- if last then\
- return self.node:replaceChild(child, tohtml(last))\
- else\
- local _exp_0 = mode\
- if 'append' == _exp_0 then\
- return self.node:appendChild(child)\
- elseif 'prepend' == _exp_0 then\
- return self.node:insertBefore(child, self.node.firstChild)\
- end\
- end\
- end,\
- remove = function(self, child)\
- self.node:removeChild(tohtml(child))\
- if 'table' == (type(child)) and child.destroy then\
- return child:destroy()\
- end\
- end\
- }\
- _base_0.__index = _base_0\
- _class_0 = setmetatable({\
- __init = function(self, element, ...)\
- if 'userdata' == type(element) then\
- self.node = element\
- else\
- self.node = document:createElement(element)\
- end\
- self._subscriptions = { }\
- local children = {\
- ...\
- }\
- local attributes = children[#children]\
- if 'table' == (type(attributes)) and (not ReactiveElement.isinstance(attributes)) and (not ReactiveVar.isinstance(attributes)) then\
- table.remove(children)\
- else\
- attributes = { }\
- end\
- for k, v in pairs(attributes) do\
- if 'string' == type(k) then\
- self:set(k, v)\
- end\
- end\
- if #children == 0 then\
- children = attributes\
- end\
- for _index_0 = 1, #children do\
- local child = children[_index_0]\
- self:append(child)\
- end\
- end,\
- __base = _base_0,\
- __name = \"ReactiveElement\"\
- }, {\
- __index = _base_0,\
- __call = function(cls, ...)\
- local _self_0 = setmetatable({}, _base_0)\
- cls.__init(_self_0, ...)\
- return _self_0\
- end\
- })\
- _base_0.__class = _class_0\
- local self = _class_0\
- self.isinstance = function(val)\
- return 'table' == (type(val)) and val.node\
- end\
- ReactiveElement = _class_0\
-end\
-local get_or_create\
-get_or_create = function(elem, id, ...)\
- elem = (document:getElementById(id)) or elem\
- do\
- local _with_0 = ReactiveElement(elem, ...)\
- _with_0:set('id', id)\
- return _with_0\
- end\
-end\
-local elements = setmetatable({ }, {\
- __index = function(self, name)\
- do\
- local val\
- val = function(...)\
- return ReactiveElement(name, ...)\
- end\
- self[name] = val\
- return val\
- end\
- end\
-})\
-return {\
- ReactiveVar = ReactiveVar,\
- ReactiveElement = ReactiveElement,\
- get_or_create = get_or_create,\
- tohtml = tohtml,\
- text = text,\
- elements = elements\
-}\
-", "mmm/component/init.client.lua") end
diff --git a/root/static/style/text$css.css b/root/static/style/text$css.css
deleted file mode 100644
index c0dc484..0000000
--- a/root/static/style/text$css.css
+++ /dev/null
@@ -1,411 +0,0 @@
-:root {
- --gray-bright: #eeeeee;
- --gray-dark: #303336;
- --gray-darker: #1d1f21;
- --gray-neutral: #b9bdc1;
- --gray-success: #bdddc1;
- --gray-fail: #ddbdc1;
- --margin-wide: 2rem; }
- @media only screen and (max-width: 425px) {
- :root {
- --margin-wide: 0.5rem; } }
-
-* {
- font-weight: inherit;
- font-style: inherit;
- font-family: inherit;
- color: inherit;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale; }
-
-body, html, h1, h2, h3, h4, h5, h6 {
- margin: 0;
- padding: 0; }
-
-h1, h2, h3, h4, h5, h6 {
- font-weight: bold; }
-
-input, select, button {
- color: initial; }
-
-tt, code, kbd, samp {
- font-family: monospace; }
-
-code {
- font-size: 0.8em; }
-
-b, strong {
- font-weight: bold; }
-
-em, i {
- font-style: italic; }
-
-a {
- font-size: 1em;
- cursor: pointer; }
-
-hr {
- clear: both; }
-
-ul {
- margin: 0; }
-
-body {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- background: #ffffff;
- font-family: sans-serif;
- min-height: 100vh; }
-
-a {
- display: inline-block;
- font-weight: bold;
- text-decoration: underline;
- text-decoration-color: transparent;
- transition: filter 500ms, text-decoration-color 500ms; }
- a:hover {
- filter: invert(40%);
- text-decoration-color: currentColor; }
-
-::selection {
- background: #303336;
- color: #eeeeee;
- padding: 1em; }
-
-/*
-
-vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid)
-
-*/
-/*background color*/
-.hljs {
- background: #1d1f21;
- border-radius: 6px;
- padding: 0.2em 0.5em;
- white-space: nowrap; }
-
-pre > .hljs {
- display: block;
- overflow-x: auto;
- padding: 1em;
- white-space: pre-wrap;
- margin: 0 2em; }
-
-/*selection color*/
-.hljs::selection,
-.hljs span::selection {
- background: #373b41; }
-
-.hljs::-moz-selection,
-.hljs span::-moz-selection {
- background: #373b41; }
-
-/*foreground color*/
-.hljs {
- color: #c5c8c6; }
-
-/*color: fg_yellow*/
-.hljs-title,
-.hljs-name {
- color: #f0c674; }
-
-/*color: fg_comment*/
-.hljs-comment,
-.hljs-meta,
-.hljs-meta .hljs-keyword {
- color: #707880; }
-
-/*color: fg_red*/
-.hljs-number,
-.hljs-symbol,
-.hljs-literal,
-.hljs-deletion,
-.hljs-link {
- color: #cc6666; }
-
-/*color: fg_green*/
-.hljs-string,
-.hljs-doctag,
-.hljs-addition,
-.hljs-regexp,
-.hljs-selector-attr,
-.hljs-selector-pseudo {
- color: #b5bd68; }
-
-/*color: fg_purple*/
-.hljs-attribute,
-.hljs-code,
-.hljs-selector-id {
- color: #b294bb; }
-
-/*color: fg_blue*/
-.hljs-keyword,
-.hljs-selector-tag,
-.hljs-bullet,
-.hljs-tag {
- color: #81a2be; }
-
-/*color: fg_aqua*/
-.hljs-subst,
-.hljs-variable,
-.hljs-template-tag,
-.hljs-template-variable {
- color: #8abeb7; }
-
-/*color: fg_orange*/
-.hljs-type,
-.hljs-built_in,
-.hljs-builtin-name,
-.hljs-quote,
-.hljs-section,
-.hljs-selector-class {
- color: #de935f; }
-
-.hljs-emphasis {
- font-style: italic; }
-
-.hljs-strong {
- font-weight: bold; }
-
-header > div {
- font-family: 'Source Sans Pro', sans-serif;
- padding: 1rem 2rem;
- text-align: right;
- color: #eeeeee;
- background: #303336; }
- header > div h1 {
- display: flex;
- justify-content: flex-end;
- align-items: center;
- flex-wrap: wrap;
- margin: 0;
- line-height: 5rem;
- font-size: 4rem;
- font-weight: 200; }
- header > div h1 > span {
- margin-left: auto; }
- header > div h1 .bold {
- font-weight: 400; }
- header > div h1 > a {
- height: 5rem; }
- header > div h1 .sun {
- height: 100%;
- stroke: currentColor;
- fill: currentColor; }
- header > div h1 .sun .out, header > div h1 .sun .in {
- animation: spin 2s;
- animation-iteration-count: 1;
- transform: scale(1); }
- header > div h1 .sun .in {
- animation: size 2s; }
- header > div h1 .sun.spin .circle {
- animation: none; }
-
-header aside {
- margin: 0;
- padding: 0 2rem;
- color: #eeeeee;
- background: #1d1f21;
- line-height: 3em; }
- header aside > a {
- margin-right: 2em; }
-
-@keyframes spin {
- 0% {
- transform: rotate3d(0.5, 1, 0, 0turn); }
- 100% {
- transform: rotate3d(0.5, 1, 0, 1turn); } }
-
-@keyframes size {
- 0%, 100% {
- transform: scale(1); }
- 40%, 60% {
- transform: scale(1.8); } }
-
-footer {
- display: flex;
- padding: 1rem 2rem;
- position: sticky;
- bottom: 0;
- color: #eeeeee;
- background: #303336; }
- footer .icons {
- flex: 1;
- display: flex;
- justify-content: flex-end; }
- footer .icons .iconlink {
- filter: invert(0.7); }
- footer .icons .iconlink:hover {
- filter: invert(1); }
- footer .icons .iconlink > img {
- height: 1em;
- margin-left: 0.5em;
- vertical-align: middle; }
-
-.browser {
- display: flex;
- flex: 1;
- border-top: 0.2rem solid #eeeeee; }
-
-.view {
- display: flex;
- flex-direction: column;
- flex: 1 1 0;
- min-width: 0; }
- .view.inspector {
- top: 0;
- position: sticky;
- max-height: 100vh;
- color: #c5c8c6;
- border-style: solid;
- border-width: 0 0 0 0.6rem;
- border-radius: 0 6px 6px 0;
- border-color: #303336;
- background: #303336; }
- .view.inspector nav {
- background: inherit; }
- .view.inspector .content {
- margin: 0;
- padding: 0;
- display: flex;
- background: #1d1f21; }
- .view.inspector .content > * {
- display: block;
- margin: 0;
- padding: 1em;
- border-radius: 0;
- border: 0;
- flex: 1; }
- .view nav {
- position: sticky;
- top: 0;
- display: flex;
- flex: 0 0 auto;
- flex-wrap: wrap;
- justify-content: space-between;
- background: #eeeeee;
- z-index: 1000; }
- .view nav > span:first-of-type {
- flex: 1 0 auto; }
- .view nav > * {
- margin: 1em;
- white-space: nowrap; }
- @media only screen and (max-width: 425px) {
- .view nav > .inspect-btn {
- display: none; } }
- .view .error-wrap {
- flex: 0 0 auto;
- padding: 1em 2em;
- overflow: hidden;
- background: #ddbdc1; }
- .view .error-wrap.empty {
- display: none; }
- .view .error-wrap > span {
- display: inline-block;
- margin-bottom: 0.5em;
- font-weight: bold;
- color: #f00; }
- .view .error-wrap > pre {
- margin: 0; }
- .view .content {
- flex: 1 1 auto;
- overflow: auto;
- padding: 1em 2em;
- position: relative; }
-
-.content {
- opacity: 1;
- transition: opacity 150ms; }
- body.loading .content {
- opacity: 0; }
-
-.content img, .content video {
- width: inherit;
- height: inherit; }
-
-.content .markdown > img, .content .markdown > video,
-.content .markdown > p > img,
-.content .markdown > p > video,
-.content .markdown > p > a > img,
-.content .markdown > p > a > video,
-.content .markdown > a > img,
-.content .markdown > a > video {
- display: block;
- max-width: 100%;
- max-height: 50vh;
- padding: 0 2em;
- box-sizing: border-box; }
-
-.content .embed {
- width: inherit;
- height: inherit; }
- .content .embed .description {
- text-align: center; }
- .content .embed.inline {
- display: inline-block; }
- .content .embed.desc {
- display: inline-block;
- padding: 0.5em;
- margin: 0.2em;
- background: #eeeeee; }
-
-.content pre > code {
- border-style: solid;
- border-width: 0 0 0 0.6rem;
- border-radius: 0 6px 6px 0;
- border-color: #303336;
- display: block;
- border-radius: 6px;
- margin: 0 var(--margin-wide);
- padding: 1em;
- white-space: pre-wrap;
- overflow-x: auto;
- background: #1d1f21;
- color: #c5c8c6; }
-
-.content pre.dual-code {
- display: flex;
- justify-content: space-between;
- padding: 0 2rem; }
- .content pre.dual-code > code {
- border-style: solid;
- border-width: 0 0.3rem 0 0;
- border-radius: 6px 0 0 6px;
- flex: 1;
- margin: 0; }
- .content pre.dual-code > code + code {
- border-style: solid;
- border-width: 0 0 0 0.3rem;
- border-radius: 0 6px 6px 0; }
-
-.content .example, .content .well {
- border-style: solid;
- border-width: 0 0 0 0.6rem;
- border-radius: 0 6px 6px 0;
- margin: 1rem var(--margin-wide);
- padding: 1rem;
- background: #eeeeee;
- border-color: #b9bdc1; }
-
-.canvas_app {
- position: relative;
- display: inline-block; }
- .canvas_app .overlay {
- position: absolute;
- padding: 1rem;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- opacity: 0;
- background: rgba(0, 0, 0, 0.7);
- transition: opacity 300ms; }
- .canvas_app .overlay:hover {
- opacity: 1; }
- .canvas_app .overlay > * {
- margin: 0.5em; }
- .canvas_app .overlay a {
- display: block;
- color: #eeeeee;
- font-family: inherit; }