diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2019-10-10 17:39:11 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2019-10-10 17:39:11 +0000 |
| commit | 91546d12919736b08567d7174bf1063cab0838f0 (patch) | |
| tree | f5afc5c801a5038fba21b44f117538956a2a64a7 /root/static | |
| parent | make fileders load just-in-time (diff) | |
| download | mmm-91546d12919736b08567d7174bf1063cab0838f0.tar.gz mmm-91546d12919736b08567d7174bf1063cab0838f0.zip | |
add WebStore, fix Browser
Diffstat (limited to 'root/static')
| -rw-r--r-- | root/static/mmm/application$lua.lua | 2701 | ||||
| -rw-r--r-- | root/static/style/text$css.css | 411 |
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'\ - }),\ - '​',\ - '.s‑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; } |
