@saltcorn/mobile-builder 1.6.0-rc.1 → 1.6.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,71 @@
1
+ /*
2
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
3
+ * This devtool is neither made for production nor for readable output files.
4
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
5
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
6
+ * or disable the default devtool with "devtool: false".
7
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
8
+ */
9
+ (function webpackUniversalModuleDefinition(root, factory) {
10
+ if(typeof exports === 'object' && typeof module === 'object')
11
+ module.exports = factory();
12
+ else if(typeof define === 'function' && define.amd)
13
+ define([], factory);
14
+ else if(typeof exports === 'object')
15
+ exports["saltcorn"] = factory();
16
+ else
17
+ root["saltcorn"] = root["saltcorn"] || {}, root["saltcorn"]["any-bootstrap-theme"] = factory();
18
+ })(self, () => {
19
+ return (self["webpackChunksaltcorn"] = self["webpackChunksaltcorn"] || []).push([["any-bootstrap-theme"],{
20
+
21
+ /***/ "../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/build_theme_utils.js"
22
+ /*!***********************************************************************************************************************!*\
23
+ !*** ../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/build_theme_utils.js ***!
24
+ \***********************************************************************************************************************/
25
+ (module, __unused_webpack_exports, __webpack_require__) {
26
+
27
+ eval("{var __webpack_dirname__ = \"/\";\nconst fs = (__webpack_require__(/*! fs */ \"../saltcorn-data/dist/mobile-mocks/node/fs.js\").promises);\nconst { spawn } = __webpack_require__(/*! child_process */ \"../saltcorn-data/dist/mobile-mocks/node/child_process.js\");\nconst { join } = __webpack_require__(/*! path */ \"../../node_modules/path-browserify/index.js\");\nconst { getState } = __webpack_require__(/*! @saltcorn/data/db/state */ \"../saltcorn-data/dist/db/state.js\");\nconst db = __webpack_require__(/*! @saltcorn/data/db */ \"../saltcorn-data/dist/db/index.js\");\n\nconst bsColors = [\n \"primary\",\n \"secondary\",\n \"success\",\n \"info\",\n \"warning\",\n \"danger\",\n \"light\",\n \"dark\",\n];\n\nconst darkLightVars = [\n \"cardBackgroundColor\",\n \"cardBackgroundColorDark\",\n \"cardHeaderBg\",\n \"cardHeaderBgAlpha\",\n \"cardHeaderBgDark\",\n \"cardHeaderBgAlphaDark\",\n \"cardFooterBg\",\n \"cardFooterBgAlpha\",\n \"cardFooterBgDark\",\n \"cardFooterBgAlphaDark\",\n \"cardHeaderText\",\n \"cardHeaderTextDark\",\n \"cardFooterText\",\n \"cardFooterTextDark\",\n \"linkColor\",\n \"linkColorDark\",\n];\n\nconst copyThemeFiles = async ({ theme }) => {\n const themeDir = theme === \"bootstrap\" ? \"lux\" : theme;\n await fs.copyFile(\n join(__webpack_dirname__, \"public\", \"bootswatch\", themeDir, \"_variables.scss\"),\n join(__webpack_dirname__, \"scss\", \"build\", \"_variables.scss\")\n );\n await fs.copyFile(\n join(__webpack_dirname__, \"public\", \"bootswatch\", themeDir, \"_bootswatch.scss\"),\n join(__webpack_dirname__, \"scss\", \"build\", \"_bootswatch.scss\")\n );\n};\n\nconst applyCustomColors = async (ctx, isDark) => {\n let content = await fs.readFile(\n join(__webpack_dirname__, \"scss\", \"build\", \"_variables.scss\"),\n \"utf8\"\n );\n for (const bsColor of bsColors) {\n const regExp = new RegExp(`^\\\\$${bsColor}:.*;`, \"gm\");\n const colorVal =\n isDark && ![\"light\", \"dark\"].includes(bsColor)\n ? ctx[`${bsColor}Dark`]\n : ctx[bsColor];\n content = content.replace(regExp, `$${bsColor}: ${colorVal} !default;`);\n }\n await fs.writeFile(\n join(__webpack_dirname__, \"scss\", \"build\", \"_variables.scss\"),\n content\n );\n};\n\nconst calcAlphaFromDecimal = (decimal) => {\n const alpha = Math.round(decimal * 255);\n return alpha.toString(16).padStart(2, \"0\");\n};\n\nconst writeDarkLightFile = async (ctx) => {\n const content = `\n@include color-mode(dark) {\n .card-body {\n background-color: ${ctx.cardBackgroundColorDark || \"#212529\"};\n }\n\n .card-header, .card-header *, .modal-title, .modal-title * {\n color: ${ctx.cardHeaderTextDark || ctx.primaryDark || \"#2c3e50\"} !important;\n }\n\n .card-header {\n background-color: ${\n ctx.cardHeaderBgDark || \"#212529\"\n }${calcAlphaFromDecimal(ctx.cardHeaderBgAlphaDark || 0.03)};\n }\n\n .card-footer, .card-footer *:not(.btn, .btn *, a, a *, .btn-link, .btn-link *) {\n color: ${ctx.cardFooterTextDark || ctx.primaryDark || \"#2c3e50\"} !important;\n }\n\n .card-footer {\n background-color: ${\n ctx.cardFooterBgDark || \"#212529\"\n }${calcAlphaFromDecimal(ctx.cardFooterBgAlphaDark || 0.03)};\n }\n\n h1, h2, h3, h4, h5, h6, \n :is(h1, h2, h3, h4, h5, h6) * {\n color: ${ctx.primaryDark || \"#2c3e50\"};\n }\n\n a:not(.btn, .btn *, .nav, .nav *:not(.breadcrumb *, .plugin-section *), nav, nav *:not(.breadcrumb *, .plugin-section *)),\n .btn-link:not(.nav, .nav *, nav, nav *) {\n color: ${ctx.linkColorDark || ctx.primaryDark || \"#2c3e50\"} !important;\n }\n}\n\n@include color-mode(light) {\n .card-body {\n background-color: ${ctx.cardBackgroundColor || \"#FFFFFF\"};\n }\n\n .card-header, .card-header *, .modal-title, .modal-title * {\n color: ${ctx.cardHeaderText || ctx.primary || \"#2c3e50\"} !important;\n }\n\n .card-header {\n background-color: ${ctx.cardHeaderBg || \"#FFFFFF\"}${calcAlphaFromDecimal(\n ctx.cardHeaderBgAlpha || 0.03\n )};\n }\n\n .card-footer, .card-footer *:not(.btn, .btn *, a, a * .btn-link, .btn-link *) {\n color: ${ctx.cardFooterText || ctx.primary || \"#2c3e50\"} !important;\n }\n\n .card-footer {\n background-color: ${ctx.cardFooterBg || \"#FFFFFF\"}${calcAlphaFromDecimal(\n ctx.cardFooterBgAlpha || 0.03\n )};\n }\n\n h1, h2, h3, h4, h5, h6, \n :is(h1, h2, h3, h4, h5, h6) * {\n color: ${ctx.primary || \"#2c3e50\"};\n }\n\n a:not(.btn, .btn *, .nav, .nav *:not(.breadcrumb *, .plugin-section *), nav, nav *:not(.breadcrumb *, .plugin-section *)),\n .btn-link:not(.nav, .nav *, nav, nav *) {\n color: ${ctx.linkColor || ctx.primary || \"#2c3e50\"} !important;\n }\n}`;\n await fs.writeFile(\n join(__webpack_dirname__, \"scss\", \"build\", \"my_dark_light_vars.scss\"),\n content\n );\n};\n\nconst buildBootstrapMin = async () => {\n getState().log(5, \"Building bootstrap.min.css\");\n const child = spawn(\"npm\", [\"run\", \"build_theme\"], {\n cwd: __webpack_dirname__,\n });\n return new Promise((resolve, reject) => {\n child.stdout.on(\"data\", (data) => {\n getState().log(5, data.toString());\n });\n child.stderr?.on(\"data\", (data) => {\n getState().log(2, data.toString());\n });\n child.on(\"exit\", function (code, signal) {\n getState().log(5, `child process exited with code ${code}`);\n resolve(code);\n });\n child.on(\"error\", (msg) => {\n getState().log(2, `child process failed: ${msg.code}`);\n reject(msg.code);\n });\n });\n};\n\nconst copyBootstrapMin = async (ctx, isDark) => {\n const themeDir = ctx.theme === \"bootstrap\" ? \"lux\" : ctx.theme;\n await fs.copyFile(\n join(__webpack_dirname__, \"scss\", \"build\", \"bootstrap.min.css\"),\n join(\n __webpack_dirname__,\n \"public\",\n \"bootswatch\",\n themeDir,\n !isDark ? ctx.sass_file_name : ctx.sass_file_name_dark\n )\n );\n};\n\nconst buildTheme = async (ctx) => {\n const builder = async (isDark) => {\n await copyThemeFiles(ctx);\n await applyCustomColors(ctx, isDark);\n await writeDarkLightFile(ctx);\n const code = await buildBootstrapMin();\n if (code === 0) await copyBootstrapMin(ctx, isDark);\n else throw new Error(`Failed to build theme, please check your logs`);\n };\n const lockFile = join(\n __webpack_dirname__,\n \"public\",\n \"bootswatch\",\n ctx.theme === \"bootstrap\" ? \"lux\" : ctx.theme,\n `lock_${ctx.sass_file_name}`\n );\n try {\n await fs.access(lockFile);\n getState().log(5, `Lock file exists for ${ctx.sass_file_name}`);\n return;\n } catch (e) {\n await fs.writeFile(lockFile, \"\");\n }\n try {\n await builder(false);\n await builder(true);\n } finally {\n await fs.rm(lockFile);\n }\n};\n\nconst extractColorDefaults = async () => {\n const dirs = await fs.readdir(join(__webpack_dirname__, \"public\", \"bootswatch\"));\n const result = {};\n for (const dir of dirs) {\n const content = await fs.readFile(\n join(__webpack_dirname__, \"public\", \"bootswatch\", dir, \"bootstrap.css\"),\n \"utf8\"\n );\n const colors = {};\n for (const bsColor of bsColors) {\n const match = content.match(new RegExp(`--bs-${bsColor}: #(.*);`, \"m\"));\n if (match) {\n colors[bsColor] = match[1];\n }\n }\n const lightAndDarkBg = Array.from(\n content.matchAll(new RegExp(\"--bs-body-bg: #(.*);\", \"gm\"))\n );\n if (lightAndDarkBg.length === 2) {\n colors.lightBg = lightAndDarkBg[0][1];\n colors.darkBg = lightAndDarkBg[1][1];\n }\n // bs-link-color\n const linkLightAndDark = Array.from(\n content.matchAll(new RegExp(\"--bs-link-color: #(.*);\", \"gm\"))\n );\n if (linkLightAndDark.length === 2) {\n colors.linkColor = linkLightAndDark[0][1];\n colors.linkColorDark = linkLightAndDark[1][1];\n }\n // header footer bg\n const headerFooterBg = Array.from(\n content.matchAll(new RegExp(\"--bs-body-bg: #(.*);\", \"gm\"))\n );\n if (headerFooterBg.length === 2) {\n colors.cardHeaderBg = headerFooterBg[0][1];\n colors.cardHeaderBgDark = headerFooterBg[1][1];\n colors.cardFooterBg = headerFooterBg[0][1];\n colors.cardFooterBgDark = headerFooterBg[1][1];\n }\n result[dir] = colors;\n }\n return result;\n};\n\nconst buildNeeded = (oldCtx, newCtx) => {\n for (const bsColor of [...bsColors, ...darkLightVars]) {\n if (\n oldCtx[bsColor] !== newCtx[bsColor] ||\n oldCtx[`${bsColor}Dark`] !== newCtx[`${bsColor}Dark`]\n )\n return true;\n }\n};\n\nconst deleteOldFiles = async ({ sass_file_name, sass_file_name_dark }) => {\n const dirs = await fs.readdir(join(__webpack_dirname__, \"public\", \"bootswatch\"));\n const tenantSchema = db.getTenantSchema();\n for (const dir of dirs) {\n const files = await fs.readdir(\n join(__webpack_dirname__, \"public\", \"bootswatch\", dir)\n );\n const fileDelPrefix = `bootstrap.min.${tenantSchema}`;\n for (const file of files) {\n if (\n file.startsWith(fileDelPrefix) &&\n ![sass_file_name, sass_file_name_dark, \"bootstrap.min.css\"].includes(\n file\n )\n )\n await fs.unlink(join(__webpack_dirname__, \"public\", \"bootswatch\", dir, file));\n }\n }\n};\nmodule.exports = {\n buildTheme,\n extractColorDefaults,\n buildNeeded,\n deleteOldFiles,\n};\n\n\n//# sourceURL=webpack://saltcorn/../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/build_theme_utils.js?\n}");
28
+
29
+ /***/ },
30
+
31
+ /***/ "../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/index.js"
32
+ /*!***********************************************************************************************************!*\
33
+ !*** ../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/index.js ***!
34
+ \***********************************************************************************************************/
35
+ (module, __unused_webpack_exports, __webpack_require__) {
36
+
37
+ eval("{var __webpack_dirname__ = \"/\";\nconst {\n div,\n text,\n p,\n footer,\n section,\n a,\n style,\n h1,\n ul,\n img,\n li,\n form,\n input,\n nav,\n button,\n i,\n hr,\n} = __webpack_require__(/*! @saltcorn/markup/tags */ \"../saltcorn-markup/dist/tags.js\");\nconst {\n navbar,\n navbarSolidOnScroll,\n mobileBottomNavBar,\n activeChecker,\n} = __webpack_require__(/*! @saltcorn/markup/layout_utils */ \"../saltcorn-markup/dist/layout_utils.js\");\nconst renderLayout = __webpack_require__(/*! @saltcorn/markup/layout */ \"../saltcorn-markup/dist/layout.js\");\nconst db = __webpack_require__(/*! @saltcorn/data/db */ \"../saltcorn-data/dist/db/index.js\");\nconst Field = __webpack_require__(/*! @saltcorn/data/models/field */ \"../saltcorn-data/dist/models/field.js\");\nconst Table = __webpack_require__(/*! @saltcorn/data/models/table */ \"../saltcorn-data/dist/models/table.js\");\nconst Form = __webpack_require__(/*! @saltcorn/data/models/form */ \"../saltcorn-data/dist/models/form.js\");\nconst View = __webpack_require__(/*! @saltcorn/data/models/view */ \"../saltcorn-data/dist/models/view.js\");\nconst File = __webpack_require__(/*! @saltcorn/data/models/file */ \"../saltcorn-data/dist/models/file.js\");\nconst Workflow = __webpack_require__(/*! @saltcorn/data/models/workflow */ \"../saltcorn-data/dist/models/workflow.js\");\nconst Plugin = __webpack_require__(/*! @saltcorn/data/models/plugin */ \"../saltcorn-data/dist/models/plugin.js\");\nconst User = __webpack_require__(/*! @saltcorn/data/models/user */ \"../saltcorn-data/dist/models/user.js\");\nconst { renderForm, link } = __webpack_require__(/*! @saltcorn/markup */ \"../saltcorn-markup/dist/index.js\");\nconst {\n alert,\n headersInHead,\n headersInBody,\n} = __webpack_require__(/*! @saltcorn/markup/layout_utils */ \"../saltcorn-markup/dist/layout_utils.js\");\nconst { features } = __webpack_require__(/*! @saltcorn/data/db/state */ \"../saltcorn-data/dist/db/state.js\");\nconst {\n buildTheme,\n extractColorDefaults,\n buildNeeded,\n deleteOldFiles,\n} = __webpack_require__(/*! ./build_theme_utils */ \"../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/build_theme_utils.js\");\nconst { sleep } = __webpack_require__(/*! @saltcorn/data/utils */ \"../saltcorn-data/dist/utils.js\");\nconst { getState } = __webpack_require__(/*! @saltcorn/data/db/state */ \"../saltcorn-data/dist/db/state.js\");\n\nconst { join } = __webpack_require__(/*! path */ \"../../node_modules/path-browserify/index.js\");\nconst { pathExists } = __webpack_require__(/*! fs-extra */ \"../saltcorn-data/dist/mobile-mocks/node/fs-extra.js\");\n\nconst isNode = typeof window === \"undefined\";\nlet hasCapacitor = false;\ntry {\n hasCapacitor =\n (__webpack_require__(/*! @saltcorn/plugins-loader/stable_versioning */ \"../plugins-loader/stable_versioning.js\").isEngineSatisfied)(\n \">=1.1.0-beta.11\"\n );\n} catch {\n getState().log(5, \"stable_versioning not available, assuming no Capacitor\");\n}\n\n// when the function from base is not yet available\nconst _activeChecker = activeChecker\n ? activeChecker\n : (link, currentUrl) => new RegExp(`^${link}(\\\\/|\\\\?|#|$)`).test(currentUrl);\n\nconst blockDispatch = (config) => ({\n pageHeader: ({ title, blurb }) =>\n div(\n h1({ class: \"h3 mb-0 mt-2 text-gray-800\" }, title),\n blurb && p({ class: \"mb-0 text-gray-800\" }, blurb)\n ),\n footer: ({ contents }) =>\n div(\n { class: \"container\" },\n footer(\n { id: \"footer\" },\n div({ class: \"row\" }, div({ class: \"col-sm-12\" }, contents))\n )\n ),\n hero: ({ caption, blurb, cta, backgroundImage }) =>\n section(\n {\n class:\n \"jumbotron text-center m-0 bg-info d-flex flex-column justify-content-center\",\n },\n div(\n { class: \"container\" },\n h1({ class: \"jumbotron-heading\" }, caption),\n p({ class: \"lead\" }, blurb),\n cta\n ),\n backgroundImage &&\n style(`.jumbotron {\n background-image: url(\"${backgroundImage}\");\n background-size: cover;\n min-height: 75vh !important;\n }`)\n ),\n noBackgroundAtTop: () => true,\n wrapTop: (segment, ix, s) =>\n [\"hero\", \"footer\"].includes(segment.type) || segment.noWrapTop\n ? s\n : section(\n {\n class: [\n \"page-section\",\n ix === 0 && `pt-${config.toppad || 0}`,\n ix === 0 && config.fixedTop && isNode && \"mt-5\",\n ix === 0 && config.fixedTop && !isNode && \"mt-6\",\n segment.class,\n segment.invertColor && \"bg-primary\",\n ],\n style: `${\n segment.bgType === \"Color\"\n ? `background-color: ${segment.bgColor};`\n : \"\"\n }`,\n },\n div(\n { class: [config.fluid ? \"container-fluid\" : \"container\"] },\n segment.textStyle && segment.textStyle === \"h1\" ? h1(s) : s\n )\n ),\n});\n\nconst buildHints = (config = {}) => {\n if (config.mode === \"dark\")\n return {\n cardTitleClass: \"m-0 fw-bold d-inline\",\n };\n else\n return {\n cardTitleClass: \"m-0 fw-bold d-inline\",\n };\n};\n\nconst renderBody = (title, body, alerts, config, role, req) =>\n renderLayout({\n blockDispatch: blockDispatch(config),\n role,\n req,\n layout:\n typeof body === \"string\" && config.in_card\n ? { type: \"card\", title, contents: body }\n : body,\n alerts,\n hints: buildHints(config),\n });\nconst includeBS4css = (config) => {\n if (!config || !config.theme) return false;\n if (config.theme === \"Other\") return false;\n if (config.theme === \"File\") return false;\n if (themes[config.theme]) return !!themes[config.theme].includeBS4css;\n};\nconst includeBS5css = (config) => {\n if (!config || !config.theme) return false;\n if (config.theme === \"Other\") return false;\n if (config.theme === \"File\") return config.include_std_bs5;\n if (themes[config.theme]) return !!themes[config.theme].includeBS5css;\n};\nconst buildBgColor = (config = {}) => {\n return bs5BootswatchThemes.indexOf(config?.theme || \"flatly\") >= 0\n ? config.mode === \"light\" && config.backgroundColor\n ? ` style=\"background-color: ${config.backgroundColor}\"`\n : config.backgroundColorDark\n ? ` style=\"background-color: ${config.backgroundColorDark}\"`\n : \"\"\n : config.backgroundColor\n ? ` style=\"background-color: ${config.backgroundColor}\"`\n : \"\";\n};\n/**\n * omit '/' in a mobile deployment (needed for ios)\n */\nconst safeSlash = () => (isNode ? \"/\" : \"\");\n\nconst linkPrefix = () =>\n isNode ? \"/plugins\" : hasCapacitor ? \"sc_plugins\" : \"plugins\";\n\nconst wrapIt = (config, bodyAttr, headers, title, body) => {\n const integrity = get_css_integrity(config);\n return `<!doctype html>\n<html lang=\"en\" data-bs-theme=\"${config.mode || \"light\"}\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n ${\n includeBS4css(config)\n ? `<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css\" integrity=\"sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2\" crossorigin=\"anonymous\">`\n : \"\"\n }\n ${\n includeBS5css(config)\n ? `<link rel=\"stylesheet\" href=\"${base_public_serve}/bootstrap.min.css\">`\n : \"\"\n }\n <link href=\"${get_css_url(config)}\" rel=\"stylesheet\"${\n integrity ? ` integrity=\"${integrity}\" crossorigin=\"anonymous\"` : \"\"\n }>\n <link rel=\"stylesheet\" href=\"${base_public_serve}/sidebar-3.css\" />\n ${custom_css_link(config)}\n ${themes[config.theme]?.in_header || \"\"}\n ${headersInHead(headers, config?.mode === \"dark\")} \n <title>${text(title)}</title>\n </head>\n <body ${bodyAttr}${buildBgColor(config)}>\n ${body}\n ${\n features && features.deep_public_plugin_serve\n ? `<link rel=\"stylesheet\" href=\"${base_public_serve}/fontawesome/fontawesome.min.css\" />`\n : '<script defer src=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/js/all.min.js\" integrity=\"sha512-F5QTlBqZlvuBEs9LQPqc1iZv2UMxcVXezbHzomzS6Df4MZMClge/8+gXrKw2fl5ysdk4rWjR0vKS7NNkfymaBQ==\" crossorigin=\"anonymous\"></script><link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/fontawesome.min.css\" integrity=\"sha512-kJ30H6g4NGhWopgdseRb8wTsyllFUYIx3hiUwmGAkgA9B/JbzUBDQVr2VVlWGde6sdBVOG7oU8AL35ORDuMm8g==\" crossorigin=\"anonymous\" />'\n }\n <script src=\"${safeSlash()}static_assets/${\n db.connectObj.version_tag\n }/jquery-3.6.0.min.js\"></script>\n ${\n features && features.bootstrap5\n ? `<script src=\"${base_public_serve}/bootstrap.bundle.min.js\"></script>`\n : `\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js\" integrity=\"sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49\" crossorigin=\"anonymous\"></script>\n <script src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js\" integrity=\"sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV\" crossorigin=\"anonymous\"></script>`\n } ${headersInBody(headers)}\n ${config.colorscheme === \"navbar-light\" ? navbarSolidOnScroll : \"\"}\n </body>\n</html>`;\n};\n\nconst active = (currentUrl, item, originalUrl) =>\n (item.link &&\n (_activeChecker(item.link, currentUrl) ||\n (originalUrl && _activeChecker(item.link, originalUrl)))) ||\n (item.altlinks &&\n item.altlinks.some(\n (l) =>\n _activeChecker(l, currentUrl) ||\n (originalUrl && _activeChecker(l, originalUrl))\n )) ||\n (item.subitems &&\n item.subitems.some(\n (si) =>\n si.link &&\n (_activeChecker(si.link, currentUrl) ||\n (originalUrl && _activeChecker(si.link, originalUrl)) ||\n (si.altlinks &&\n si.altlinks.some((l) => _activeChecker(l, currentUrl))))\n ));\n\nconst verticalMenu = ({ menu, currentUrl, originalUrl, brand }) => {\n const brandLogo = a(\n { class: \"navbar-brand mt-1 ms-3 mb-2\", href: \"/\" },\n brand.logo &&\n img({\n src: brand.logo,\n width: \"30\",\n height: \"30\",\n class: \"me-2 d-inline-block align-top\",\n alt: \"Logo\",\n loading: \"lazy\",\n }),\n brand.name\n );\n const vertNavSubItemsIterator = (subitem) =>\n subitem.type === \"Separator\"\n ? hr({ class: \"mx-4 my-0\" })\n : subitem?.subitems\n ? li(\n {\n class: [\"nav-item\"],\n },\n div(\n { class: \"dropdown-item btn-group dropend\" },\n a(\n {\n type: \"button\",\n class: \"nav-link sublink dropdown-item dropdown-toggle\",\n \"data-bs-toggle\": \"dropdown\",\n \"aria-expanded\": \"false\",\n },\n subitem.label\n ),\n ul(\n { class: \"dropdown-menu\" },\n subitem?.subitems.map((si1) => li(vertNavSubItemsIterator(si1)))\n )\n )\n )\n : li(\n {\n class: [\n \"nav-item\",\n active(currentUrl, subitem, originalUrl) && \"active\",\n ],\n },\n a(\n {\n class: \"nav-link sublink\",\n href: subitem.link,\n target: subitem.target_blank ? \"_blank\" : undefined,\n },\n subitem.icon ? i({ class: `fa-fw me-1 ${subitem.icon}` }) : \"\",\n subitem.label\n )\n );\n\n let items = [];\n menu.forEach((m, ix) => {\n if (m.items && m.items.length > 0) {\n m.items.forEach((item, ix1) => {\n if (item.location === \"Mobile Bottom\") return;\n if (item.subitems) {\n items.push(\n li(\n {\n class: [\n \"nav-item\",\n active(currentUrl, item, originalUrl) && \"active\",\n ],\n },\n a(\n {\n href: `#menuCollapse${ix}_${ix1}`,\n \"aria-expanded\": false,\n class: \"dropdown-toggle nav-link\",\n ...(features && features.bootstrap5\n ? { \"data-bs-toggle\": \"collapse\" }\n : { \"data-toggle\": \"collapse\" }),\n },\n item.icon ? i({ class: `fa-fw me-1 ${item.icon}` }) : \"\",\n item.label\n ),\n ul(\n {\n class: [\n active(currentUrl, item, originalUrl)\n ? \"collapse.show\"\n : \"collapse\",\n \"list-unstyled\",\n ],\n id: `menuCollapse${ix}_${ix1}`,\n },\n item.subitems.map(vertNavSubItemsIterator)\n )\n )\n );\n } else if (item.link)\n items.push(\n li(\n {\n class: [\n \"nav-item\",\n active(currentUrl, item, originalUrl) && \"active\",\n ],\n },\n a(\n {\n class: \"nav-link\",\n href: item.link,\n target: item.target_blank ? \"_blank\" : undefined,\n },\n item.icon ? i({ class: `fa-fw me-1 ${item.icon}` }) : \"\",\n item.label\n )\n )\n );\n else if (item.type === \"Separator\")\n items.push(hr({ class: \"mx-4 my-0\" }));\n else if (item.type === \"Search\")\n items.push(\n li(\n form(\n {\n action: \"/search\",\n class: \"menusearch\",\n method: \"get\",\n },\n div(\n { class: \"input-group search-bar\" },\n\n input({\n type: \"search\",\n class: \"form-control search-bar ps-2 hasbl\",\n placeholder: item.label,\n id: \"inputq\",\n name: \"q\",\n \"aria-label\": \"Search\",\n \"aria-describedby\": \"button-search-submit\",\n }),\n\n button(\n {\n class: \"btn btn-outline-secondary search-bar\",\n type: \"submit\",\n },\n i({ class: \"fas fa-search\" })\n )\n )\n )\n )\n );\n });\n }\n });\n const toggler =\n hr({ class: \"mx-4 my-0\" }) +\n div(\n { class: \"text-center\" },\n button({\n class: \"rounded-circle border-0\",\n id: \"sidebarToggle\",\n \"data-sidebar-toggler\": true,\n onclick: \"$('#wrapper').toggleClass('narrowed')\",\n })\n );\n return (\n brandLogo +\n ul({ class: \"navbar-nav list-unstyled components\" }, items) +\n toggler\n );\n};\n\nconst authBrand = (config, { name, logo }) =>\n logo\n ? `<img class=\"mb-4\" src=\"${logo}\" alt=\"Logo\" width=\"72\" height=\"72\">`\n : \"\";\nconst menuWrap = ({\n brand,\n menu,\n config,\n currentUrl,\n originalUrl,\n body,\n req,\n}) => {\n const colschm = (config.colorscheme || \"\").split(\" \");\n const navbarCol = colschm[0];\n const bg = colschm[1];\n const txt = (colschm[0] || \"\").includes(\"dark\") ? \"text-light\" : \"\";\n\n const mobileNav = mobileBottomNavBar\n ? mobileBottomNavBar(currentUrl, menu, bg, txt)\n : \"\";\n const role = !req ? 1 : req.user ? req.user.role_id : 100;\n if ((config.menu_style === \"No Menu\" && role > 1) || (!menu && !brand))\n return div({ id: \"wrapper\" }, div({ id: \"page-inner-content\" }, body));\n else if (config.menu_style === \"Side Navbar\" && isNode) {\n return (\n navbar(brand, menu, currentUrl, { class: \"d-md-none\", ...config }) +\n div(\n { id: \"wrapper\", class: \"d-flex with-sidebar\" },\n\n nav(\n {\n class: [\n \"d-none d-md-flex flex-column align-center d-print-none\",\n navbarCol,\n bg,\n txt,\n ],\n id: \"sidebar\",\n },\n\n verticalMenu({ brand, menu, currentUrl, originalUrl })\n ),\n div(\n { id: \"content-wrapper\", class: \"d-flex flex-column\" },\n div({ id: \"content\" }, div({ id: \"page-inner-content\" }, body))\n )\n ) +\n mobileNav\n );\n } else\n return (\n div(\n { id: \"wrapper\" },\n navbar(brand, menu, currentUrl, config),\n div({ id: \"page-inner-content\" }, body)\n ) + mobileNav\n );\n};\nconst layout = (config) => ({\n hints: buildHints(config),\n renderBody: ({ title, body, alerts, role, req }) =>\n renderBody(title, body, alerts, config, role, req),\n wrap: ({\n title,\n menu,\n brand,\n alerts,\n currentUrl,\n originalUrl,\n body,\n headers,\n role,\n req,\n bodyClass,\n requestFluidLayout,\n }) =>\n wrapIt(\n config,\n `id=\"page-top\" class=\"${bodyClass || \"\"}\"`,\n headers,\n title,\n menuWrap({\n brand,\n menu,\n config,\n currentUrl,\n originalUrl,\n body: renderBody(\n title,\n body,\n alerts,\n requestFluidLayout ? { ...config, fluid: true } : config,\n role,\n req\n ),\n req,\n })\n ),\n authWrap: ({\n title,\n alerts, //TODO\n form,\n afterForm,\n headers,\n brand,\n csrfToken,\n authLinks,\n bodyClass,\n req,\n }) =>\n wrapIt(\n config,\n `class=\"text-center ${bodyClass || \"\"}\"`,\n headers,\n title,\n `\n <div class=\"form-signin\">\n ${alerts.map((a) => alert(a.type, a.msg)).join(\"\")}\n ${authBrand(config, brand)}\n <h3>\n ${title}\n </h3>\n ${renderForm(formModify(form), csrfToken)}\n ${renderAuthLinks(authLinks, req)}\n ${afterForm}\n <style>\n html,\nbody {\n min-height: 100%;\n}\n\nbody {\n display: -ms-flexbox;\n display: -webkit-box;\n display: flex;\n -ms-flex-align: center;\n -ms-flex-pack: center;\n -webkit-box-align: center;\n align-items: center;\n -webkit-box-pack: center;\n justify-content: center;\n padding-top: 40px;\n padding-bottom: 40px;\n background-color: #f5f5f5;\n}\n\n.form-signin {\n width: 100%;\n max-width: 330px;\n padding: 15px;\n margin: 0 auto;\n}\n.form-signin .checkbox {\n font-weight: 400;\n}\n.form-signin .form-control {\n position: relative;\n box-sizing: border-box;\n height: auto;\n padding: 10px;\n font-size: 16px;\n}\n.form-signin .form-control:focus {\n z-index: 2;\n}\n.form-signin input[type=\"email\"] {\n margin-bottom: -1px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.form-signin input[type=\"password\"] {\n margin-bottom: 10px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n </style>\n </div>\n `\n ),\n});\nconst renderAuthLinks = (authLinks, req) => {\n var links = [];\n const __ = req?.__ || ((s) => s);\n if (authLinks.login)\n links.push(link(authLinks.login, __(\"Already have an account? Login!\")));\n if (authLinks.forgot)\n links.push(link(authLinks.forgot, __(\"Forgot password?\")));\n if (authLinks.signup)\n links.push(link(authLinks.signup, __(\"Create an account!\")));\n const meth_links = (authLinks.methods || [])\n .map(({ url, icon, label }) =>\n a(\n { href: url, class: \"btn btn-secondary btn-user btn-block\" },\n icon || \"\",\n `&nbsp;Login with ${label}`\n )\n )\n .join(\"\");\n\n return (\n meth_links + links.map((l) => div({ class: \"text-center\" }, l)).join(\"\")\n );\n};\n\nconst formModify = (form) => {\n form.formStyle = \"vert\";\n form.submitButtonClass = \"btn-primary btn-user btn-block\";\n return form;\n};\n\nconst themes = __webpack_require__(/*! ./themes.json */ \"../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/themes.json\");\n\nconst base_public_serve = `${linkPrefix()}/public/any-bootstrap-theme${\n features?.version_plugin_serve_path\n ? \"@\" + (__webpack_require__(/*! ./package.json */ \"../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/package.json\").version)\n : \"\"\n}`;\n\nconst get_css_url = (config) => {\n const def = isNode\n ? \"/plugins/public/any-bootstrap-theme/bootswatch/flatly/bootstrap.min.css\"\n : `${base_public_serve}/bootswatch/flatly/bootstrap.min.css`;\n if (!config || !config.theme) return def;\n if (config.theme === \"File\") return `/files/serve/${config.css_file}`;\n if (config.theme === \"Other\") return config.css_url || def;\n if (\n features &&\n features.bootstrap5 &&\n themes[config.theme] &&\n themes[config.theme].source === \"Bootswatch\"\n )\n return `${base_public_serve}/bootswatch/${config.theme}/bootstrap.min.css`;\n if (themes[config.theme]?.local_css_file)\n return `${base_public_serve}/${themes[config.theme]?.local_css_file}`;\n if (themes[config.theme]) return themes[config.theme].css_url;\n else return def;\n};\n\nconst custom_css_link = (config) => {\n if (\n features &&\n features.bootstrap5 &&\n themes[config.theme] &&\n themes[config.theme].source === \"Bootswatch\" &&\n config.sass_file_name &&\n config.sass_file_name.indexOf(\n config.theme === \"bootstrap\" ? \"lux\" : config.theme\n ) > 0\n )\n return `<link href=\"${base_public_serve}/bootswatch/${\n config.theme === \"bootstrap\" ? \"lux\" : config.theme\n }/${\n config.mode !== \"dark\"\n ? config.sass_file_name\n : config.sass_file_name_dark\n }\" rel=\"stylesheet\">`;\n else return \"\";\n};\n\nconst get_css_integrity = (config) => {\n const def = themes.flatly.get_css_integrity;\n if (!config || !config.theme) return def;\n if (config.theme === \"File\") return null;\n if (themes[config.theme]?.local_css_file) return null;\n if (config.theme === \"Other\") return config.css_integrity || def;\n if (\n features &&\n features.bootstrap5 &&\n themes[config.theme] &&\n themes[config.theme].source === \"Bootswatch\"\n )\n return null;\n if (themes[config.theme]) return themes[config.theme].css_integrity;\n else return def;\n};\n\nconst themeSelectOptions = Object.entries(themes).map(([k, v]) => ({\n label: `${k[0].toUpperCase()}${k.slice(1)} from ${v.source}`,\n name: k,\n}));\n\nconst bs5BootswatchThemes = Object.entries(themes)\n .filter(([k, v]) => !v.includeBS4css && v.source === \"Bootswatch\")\n .map(([k, v]) => k);\n\nconst configuration_workflow = () =>\n new Workflow({\n onDone: async (context) => {\n return {\n context,\n cleanup: async () => {\n if (context.sass_file_name) await deleteOldFiles(context);\n },\n };\n },\n onStepSuccess: async (step, ctx) => {\n try {\n if (bs5BootswatchThemes.indexOf(ctx.theme) >= 0) await buildTheme(ctx);\n } catch (error) {\n const msg = error.message || \"Failed to build theme\";\n getState().log(2, `onStepSuccess failed: ${msg}`);\n }\n },\n onStepSave: async (step, ctx, formVals) => {\n const state = getState();\n const oldCfg = state?.plugin_cfgs[\"any-bootstrap-theme\"] || {};\n if (\n bs5BootswatchThemes.indexOf(formVals.theme) >= 0 &&\n buildNeeded(oldCfg, formVals)\n ) {\n try {\n await buildTheme(formVals);\n } catch (error) {\n const msg = error.message || \"Failed to build theme\";\n getState().log(2, `onStepSave failed: ${msg}`);\n return {\n savingErrors: msg,\n };\n }\n }\n },\n steps: [\n {\n name: \"stylesheet\",\n form: async (ctx) => {\n const cssfiles = await File.find({\n mime_super: \"text\",\n mime_sub: \"css\",\n });\n const themeColors = await extractColorDefaults();\n const form = new Form({\n additionalHeaders: [\n {\n headerTag: `<script>\nvar currentTheme = \"${\n (ctx.theme === \"bootstrap\" ? \"lux\" : ctx.theme) || \"flatly\"\n }\";\nvar tenantSchema = \"${db.getTenantSchema()}\";\nvar themeColors = ${JSON.stringify(themeColors)}</script>`,\n },\n {\n script: `${linkPrefix()}/public/any-bootstrap-theme/theme_helpers.js`,\n },\n {\n headerTag: `<style>\n #inputcardFooterBg, #inputcardFooterBgDark, #inputcardHeaderBg, #inputcardHeaderBgDark {\n opacity: 0.3 !important;\n }\n /* hide arrows, or we need a debounce only on the float inputs */\n :is(#inputcardHeaderBgAlpha, #inputcardHeaderBgAlphaDark, #inputcardFooterBgAlpha, #inputcardFooterBgAlphaDark)::-webkit-outer-spin-button,\n :is(#inputcardHeaderBgAlpha, #inputcardHeaderBgAlphaDark, #inputcardFooterBgAlpha, #inputcardFooterBgAlphaDark)::-webkit-inner-spin-button {\n -webkit-appearance: none;\n margin: 0;\n }\n :is(#inputcardHeaderBgAlpha, #inputcardHeaderBgAlphaDark, #inputcardFooterBgAlpha, #inputcardFooterBgAlphaDark) {\n -moz-appearance: textfield;\n }\n </style>`,\n },\n ],\n saveAndContinueOption: true,\n fields: [\n {\n name: \"theme\",\n label: \"Theme\",\n type: \"String\",\n class: \"theme\",\n required: true,\n default: \"flatly\",\n attributes: {\n options: [\n ...themeSelectOptions,\n { name: \"File\", label: \"Uploaded file\" },\n { name: \"Other\", label: \"Other - specify URL\" },\n ],\n onChange: \"themeHelpers.changeTheme(this)\",\n },\n },\n {\n name: \"css_url\",\n label: \"CSS stylesheet URL\",\n type: \"String\",\n showIf: { \".theme\": \"Other\" },\n },\n {\n name: \"css_integrity\",\n label: \"CSS stylesheet integrity\",\n type: \"String\",\n showIf: { \".theme\": \"Other\" },\n },\n {\n name: \"css_file\",\n label: \"CSS stylesheet file\",\n type: \"String\",\n showIf: { \".theme\": \"File\" },\n attributes: {\n options: cssfiles.map((fl) => ({\n label: fl.filename,\n name: fl.path_to_serve,\n })),\n },\n },\n {\n name: \"include_std_bs5\",\n label: \"Needs standard BS5 CSS\",\n type: \"Bool\",\n showIf: { \".theme\": \"File\" },\n },\n {\n name: \"in_card\",\n label: \"Default content in card?\",\n type: \"Bool\",\n required: true,\n },\n {\n name: \"menu_style\",\n label: \"Menu style\",\n type: \"String\",\n required: true,\n //fieldview: \"radio_group\",\n attributes: {\n inline: true,\n options: [\"Top Navbar\", \"Side Navbar\", \"No Menu\"],\n },\n },\n {\n name: \"colorscheme\",\n label: \"Navbar color scheme\",\n type: \"String\",\n required: true,\n default: \"navbar-light\",\n attributes: {\n options: [\n { name: \"navbar-dark bg-dark\", label: \"Dark\" },\n {\n name: \"navbar-dark bg-primary\",\n label: \"Dark Primary\",\n },\n {\n name: \"navbar-dark bg-secondary\",\n label: \"Dark Secondary\",\n },\n { name: \"navbar-light bg-light\", label: \"Light\" },\n { name: \"navbar-light bg-white\", label: \"White\" },\n { name: \"navbar-light\", label: \"Transparent Light\" },\n ],\n },\n },\n {\n name: \"fixedTop\",\n label: \"Navbar Fixed Top\",\n type: \"Bool\",\n required: true,\n },\n {\n name: \"toppad\",\n label: \"Top padding\",\n sublabel: \"0-5 depending on Navbar height and configuration\",\n type: \"Integer\",\n required: true,\n default: 2,\n attributes: {\n max: 5,\n min: 0,\n },\n },\n {\n name: \"fluid\",\n label: \"Fluid full-width container\",\n type: \"Bool\",\n },\n {\n name: \"mode\",\n label: \"Mode\",\n type: \"String\",\n showIf: { theme: bs5BootswatchThemes },\n required: true,\n default: \"light\",\n attributes: {\n options: [\n { name: \"light\", label: \"Light\" },\n { name: \"dark\", label: \"Dark\" },\n ],\n },\n },\n {\n name: \"backgroundColor\",\n label: \"Background Color </br>(Light mode)\",\n type: \"Color\",\n default: \"#ffffff\",\n },\n {\n name: \"backgroundColorDark\",\n label: \"Dark\",\n sublabel: \"background color in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#212529\",\n },\n {\n name: \"cardBackgroundColor\",\n label: \"Card Background </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#ffffff\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"cardBackgroundColorDark\",\n label: \"Dark\",\n sublabel: \"card background in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#212529\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"cardHeaderText\",\n label: \"Card Header text </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#2c3e50\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"cardHeaderTextDark\",\n label: \"Dark\",\n sublabel: \"Card Header text in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#2c3e50\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"cardHeaderBg\",\n label: \"Card Header background color </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#2c3e50\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"cardHeaderBgDark\",\n label: \"Dark\",\n sublabel: \"Card Header background color in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#2c3e50\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"cardHeaderBgAlpha\",\n label: \"Card Header background alpha </br>(Light mode)\",\n type: \"Float\",\n default: 0.03,\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n decimal_places: 2,\n min: 0,\n max: 1,\n },\n },\n {\n name: \"cardHeaderBgAlphaDark\",\n label: \"Dark\",\n type: \"Float\",\n default: 0.03,\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n decimal_places: 2,\n min: 0,\n max: 1,\n },\n },\n\n {\n name: \"cardFooterText\",\n label: \"Card Footer text </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#2c3e50\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"cardFooterTextDark\",\n label: \"Dark\",\n sublabel: \"Card Footer text in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#2c3e50\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"cardFooterBg\",\n label: \"Card Footer background color </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#2c3e50\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"cardFooterBgDark\",\n label: \"Dark\",\n sublabel: \"Card Footer background color in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#2c3e50\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"cardFooterBgAlpha\",\n label: \"Card Footer background alpha </br>(Light mode)\",\n type: \"Float\",\n default: 0.03,\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n decimal_places: 2,\n min: 0,\n max: 1,\n },\n },\n {\n name: \"cardFooterBgAlphaDark\",\n label: \"Dark\",\n type: \"Float\",\n default: 0.03,\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n decimal_places: 2,\n min: 0,\n max: 1,\n },\n },\n {\n name: \"linkColor\",\n label: \"Link color </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#007bff\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"linkColorDark\",\n label: \"Dark\",\n sublabel: \"Link color in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#007bff\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"primary\",\n label: \"Primary color </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#2c3e50\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"primaryDark\",\n label: \"Dark\",\n sublabel: \"Primary color in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#2c3e50\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"secondary\",\n label: \"Secondary </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#95a5a6\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"secondaryDark\",\n label: \"Dark\",\n sublabel: \"Secondary color in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#95a5a6\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"success\",\n label: \"Success </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#18bc9c\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"successDark\",\n label: \"Dark\",\n sublabel: \"Success color in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#18bc9c\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"info\",\n label: \"Info </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#3498db\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"infoDark\",\n label: \"Dark\",\n sublabel: \"Info color in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#3498db\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"warning\",\n label: \"Warning </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#f39c12\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"warningDark\",\n label: \"Dark\",\n sublabel: \"Warning color in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#f39c12\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"danger\",\n label: \"Danger </br>(Light mode)\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#e74c3c\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"dangerDark\",\n label: \"Dark\",\n sublabel: \"Danger color in Dark mode\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#e74c3c\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"light\",\n label: \"Light\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#ecf0f1\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"dark\",\n label: \"Dark\",\n type: \"Color\",\n showIf: { theme: bs5BootswatchThemes },\n default: \"#7b8a8b\",\n attributes: {\n onChange: \"themeHelpers.bsColorChanged(this)\",\n },\n },\n {\n name: \"sass_file_name\",\n input_type: \"hidden\",\n },\n {\n name: \"sass_file_name_dark\",\n input_type: \"hidden\",\n },\n ],\n });\n const now = new Date().valueOf();\n form.values.sass_file_name =\n ctx.sass_file_name ||\n `bootstrap.min.${db.getTenantSchema()}.${\n ctx.theme || \"flatly\"\n }.${now}.css`;\n form.values.sass_file_name_dark =\n ctx.sass_file_name_dark ||\n `bootstrap.min.${db.getTenantSchema()}.${\n ctx.theme || \"flatly\"\n }.${now}.dark.css`;\n return form;\n },\n },\n ],\n });\n\nconst userConfigForm = async (ctx) => {\n if (bs5BootswatchThemes.indexOf(ctx?.theme || \"flatly\") >= 0)\n return new Form({\n fields: [\n {\n name: \"mode\",\n label: \"Mode\",\n type: \"String\",\n required: true,\n default: ctx.mode || \"light\",\n attributes: {\n options: [\n { name: \"light\", label: \"Light\" },\n { name: \"dark\", label: \"Dark\" },\n ],\n },\n },\n ],\n });\n else return null;\n};\n\nmodule.exports = {\n sc_plugin_api_version: 1,\n plugin_name: \"any-bootstrap-theme\",\n user_config_form: userConfigForm,\n layout,\n fonts: (config) => themes[config.theme]?.fonts || {},\n configuration_workflow,\n exposed_configs: [\"mode\"],\n onLoad: async (configuration) => {\n if (!configuration || !configuration.sass_file_name || !configuration.theme)\n return;\n try {\n if (\n bs5BootswatchThemes.indexOf(configuration.theme) >= 0 &&\n !(await pathExists(\n join(\n __webpack_dirname__,\n \"public\",\n \"bootswatch\",\n configuration.theme === \"bootstrap\" ? \"lux\" : configuration.theme,\n configuration.sass_file_name\n )\n ))\n )\n await buildTheme(configuration);\n } catch (error) {\n const msg = error.message || \"Failed to build theme\";\n getState().log(2, `any-bootstrap-theme onLoad failed: ${msg}`);\n if (getState().logLevel > 5) console.error(error);\n }\n },\n actions: () => ({\n toggle_dark_mode: {\n description: \"Switch between dark and light mode\",\n configFields: [],\n run: async ({ user, req }) => {\n let plugin = await Plugin.findOne({ name: \"any-bootstrap-theme\" });\n if (!plugin) {\n plugin = await Plugin.findOne({\n name: \"@saltcorn/any-bootstrap-theme\",\n });\n }\n const dbUser = await User.findOne({ id: user.id });\n const attrs = dbUser._attributes || {};\n const userLayout = attrs.layout || {\n config: {},\n };\n userLayout.plugin = plugin.name;\n const currentMode = userLayout.config.mode\n ? userLayout.config.mode\n : plugin.configuration?.mode\n ? plugin.configuration.mode\n : \"light\";\n userLayout.config.mode = currentMode === \"dark\" ? \"light\" : \"dark\";\n userLayout.config.is_user_config = true;\n attrs.layout = userLayout;\n await dbUser.update({ _attributes: attrs });\n getState().userLayouts[user.email] = layout({\n ...(plugin.configuration ? plugin.configuration : {}),\n ...userLayout.config,\n });\n const sessionUser = req.session?.passport?.user;\n if (sessionUser) {\n const pluginName = \"any-bootstrap-theme\";\n if (sessionUser.attributes) {\n const oldAttrs = sessionUser.attributes[pluginName] || {};\n sessionUser.attributes[pluginName] = {\n ...oldAttrs,\n mode: userLayout.config.mode,\n is_user_config: true,\n };\n } else\n sessionUser.attributes = {\n [pluginName]: {\n mode: userLayout.config.mode,\n is_user_config: true,\n },\n };\n }\n //await db.commitAndBeginNewTransaction?.();\n await getState().refreshUserLayouts?.();\n await dbUser.relogin(req);\n return { reload_page: true };\n },\n },\n }),\n ready_for_mobile: true,\n};\n\n\n//# sourceURL=webpack://saltcorn/../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/index.js?\n}");
38
+
39
+ /***/ },
40
+
41
+ /***/ "../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/package.json"
42
+ /*!***************************************************************************************************************!*\
43
+ !*** ../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/package.json ***!
44
+ \***************************************************************************************************************/
45
+ (module) {
46
+
47
+ "use strict";
48
+ eval("{module.exports = /*#__PURE__*/JSON.parse('{\"name\":\"@saltcorn/any-bootstrap-theme\",\"version\":\"0.6.10\",\"description\":\"Configurable bootstrap layout plugin\",\"main\":\"index.js\",\"scripts\":{\"test\":\"jest\",\"build_theme\":\"sass --style=compressed scss/build/my_theme.scss scss/build/bootstrap.min.css\"},\"dependencies\":{\"sass\":\"^1.72.0\",\"fs-extra\":\"11.3.5\"},\"author\":\"Tom Nielsen\",\"license\":\"MIT\",\"devDependencies\":{},\"jest\":{\"testEnvironment\":\"node\"},\"eslintConfig\":{\"extends\":\"eslint:recommended\",\"parserOptions\":{\"ecmaVersion\":2020},\"env\":{\"node\":true,\"es6\":true},\"rules\":{\"no-unused-vars\":\"off\",\"no-case-declarations\":\"off\",\"no-empty\":\"warn\",\"no-fallthrough\":\"warn\"}}}');\n\n//# sourceURL=webpack://saltcorn/../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/package.json?\n}");
49
+
50
+ /***/ },
51
+
52
+ /***/ "../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/themes.json"
53
+ /*!**************************************************************************************************************!*\
54
+ !*** ../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/themes.json ***!
55
+ \**************************************************************************************************************/
56
+ (module) {
57
+
58
+ "use strict";
59
+ eval("{module.exports = /*#__PURE__*/JSON.parse('{\"cerulean\":{\"source\":\"Bootswatch\",\"css_url\":\"https://cdn.jsdelivr.net/npm/bootswatch@4.5.2/dist/cerulean/bootstrap.min.css\",\"css_integrity\":\"sha384-3fdgwJw17Bi87e1QQ4fsLn4rUFqWw//KU0g8TvV6quvahISRewev6/EocKNuJmEw\"},\"cosmo\":{\"source\":\"Bootswatch\",\"css_url\":\"https://cdn.jsdelivr.net/npm/bootswatch@4.5.2/dist/cosmo/bootstrap.min.css\",\"css_integrity\":\"sha384-5QFXyVb+lrCzdN228VS3HmzpiE7ZVwLQtkt+0d9W43LQMzz4HBnnqvVxKg6O+04d\"},\"cyborg\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/cyborg/bootstrap.min.css\",\"css_integrity\":\"sha384-GKugkVcT8wqoh3M8z1lqHbU+g6j498/ZT/zuXbepz7Dc09/otQZxTimkEMTkRWHP\"},\"darkly\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/darkly/bootstrap.min.css\",\"css_integrity\":\"sha384-Bo21yfmmZuXwcN/9vKrA5jPUMhr7znVBBeLxT9MA4r2BchhusfJ6+n8TLGUcRAtL\"},\"flatly\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/flatly/bootstrap.min.css\",\"css_integrity\":\"sha384-mhpbKVUOPCSocLzx2ElRISIORFRwr1ZbO9bAlowgM5kO7hnpRBe+brVj8NNPUiFs\"},\"journal\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/journal/bootstrap.min.css\",\"css_integrity\":\"sha384-vjBZc/DqIqR687k5rf6bUQ6IVSOxQUi9TcwtvULstA7+YGi//g3oT2qkh8W1Drx9\"},\"litera\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/litera/bootstrap.min.css\",\"css_integrity\":\"sha384-Gr51humlTz50RfCwdBYgT+XvbSZqkm8Loa5nWlNrvUqCinoe6C6WUZKHS2WIRx5o\"},\"lumen\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/lumen/bootstrap.min.css\",\"css_integrity\":\"sha384-VMuWne6iwiifi8iEWNZMw8sDatgb6ntBpBIr67q0rZAyOQwfu/VKpnFntQrjxB5W\"},\"bootstrap\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/lux/bootstrap.min.css\",\"css_integrity\":\"sha384-smnSwzHqW1zKbeuSMsAM/fMQpkk7HY11LuHiwT8snL/W2QBoZtVCT4H5x1CEcJCs\"},\"materia\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/materia/bootstrap.min.css\",\"css_integrity\":\"sha384-uKLgCN8wZ+yo4RygxUNFhjywpL/l065dVTzvLuxys7LAIMmhZoLWb/1yP6+mF925\"},\"minty\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/minty/bootstrap.min.css\",\"css_integrity\":\"sha384-HqaYdAE26lgFCJsUF9TBdbZf7ygr9yPHtxtg37JshqVQi6CCAo6Qvwmgc5xclIiV\"},\"pulse\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/pulse/bootstrap.min.css\",\"css_integrity\":\"sha384-t87SWLASAVDfD3SOypT7WDQZv9X6r0mq1lMEc6m1/+tAVfCXosegm1BvaIiQm3zB\"},\"sandstone\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/sandstone/bootstrap.min.css\",\"css_integrity\":\"sha384-ztQCCdmKhYHBDMV3AyR4QGZ2/z6veowJBbsmvDJW/sTuMpB9lpoubJuD0ODGSbjh\"},\"simplex\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/simplex/bootstrap.min.css\",\"css_integrity\":\"sha384-6ge4b1Lr1zrvyGvm5pdAkc3NMa97XYhFPBWsZsT6O3eOU+hqURR1bQEMm11Grf3a\"},\"sketchy\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/sketchy/bootstrap.min.css\",\"css_integrity\":\"sha384-NkI/Nlr1DZ5rUXWWdnuZb97FQRgCCcwC66DC+HUCY0oVx6BgBHUfPcwL1vwp93JZ\"},\"slate\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/slate/bootstrap.min.css\",\"css_integrity\":\"sha384-idNH3UIOiZbCf8jxqu4iExnH34y5UovfW/Mg8T5WfNvoJolDvknoNqR69V2OexgF\"},\"solar\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/solar/bootstrap.min.css\",\"css_integrity\":\"sha384-iDw+DjLp94cdk+ODAgTY4IZ6d9aaRpG9KHr168TPxrfQ9wv/DTVC+cWyojoxjHBT\"},\"spacelab\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/spacelab/bootstrap.min.css\",\"css_integrity\":\"sha384-sIQOcNYer0kt7oTyFe/YrGzKMFP/qxsJbXTxq0/uiZQgpwXwEu41sVz2M61lWbai\"},\"superhero\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/superhero/bootstrap.min.css\",\"css_integrity\":\"sha384-rvwYMW9Z/bbxZfgxHQEKx6D91KwffWAG+XnsoYNCGWi/qL1P9dIVYm1HBiHFqQEt\"},\"united\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/united/bootstrap.min.css\",\"css_integrity\":\"sha384-Uga2yStKRHUWCS7ORqIZhJ9LIAv4i7gZuEdoR1QAmw6H+ffhcf7yCOd0CvSoNwoz\"},\"yeti\":{\"source\":\"Bootswatch\",\"css_url\":\"https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/yeti/bootstrap.min.css\",\"css_integrity\":\"sha384-chJtTd1EMa6hQI40eyJWF6829eEk4oIe7b3nNtUni7VxA3uHc/uIM/8ppyjrggfV\"},\"wizardry\":{\"source\":\"HackerThemes\",\"css_url\":\"https://cdn.jsdelivr.net/npm/theme-machine@1.0.1/dist/wizardry/css/bootstrap4-wizardry.min.css\",\"css_integrity\":\"sha256-qzbIfL45JO+RLfTh3pTXGYVaeHLYNiPwPmrik16f6w4=\"},\"vibrant-sea\":{\"source\":\"HackerThemes\",\"css_url\":\"https://cdn.jsdelivr.net/npm/theme-machine@1.0.1/dist/vibrant-sea/css/bootstrap4-vibrant-sea.min.css\",\"css_integrity\":\"sha256-JwWHOtKYsT7H38+ud0LdVnruD3Q5ZSthwFcsC3+8EYU=\"},\"retro\":{\"source\":\"HackerThemes\",\"css_url\":\"https://cdn.jsdelivr.net/npm/theme-machine@1.0.1/dist/retro/css/bootstrap4-retro.min.css\",\"css_integrity\":\"sha256-JIygeLSf9weplj4GwLyfTKysZmJVL4Aeljs6gnXOjkI=\"},\"pleasant\":{\"source\":\"HackerThemes\",\"css_url\":\"https://cdn.jsdelivr.net/npm/theme-machine@1.0.1/dist/pleasant/css/bootstrap4-pleasant.min.css\",\"css_integrity\":\"sha256-Ge1pC+rdGqSQeqjYvG56h64NHY4kU7ecBdhTikF8U7k=\"},\"neon-glow\":{\"source\":\"HackerThemes\",\"css_url\":\"https://cdn.jsdelivr.net/npm/theme-machine@1.0.1/dist/neon-glow/css/bootstrap4-neon-glow.min.css\",\"css_integrity\":\"sha256-efQSfCrlBRBXT4oo4S4ENO49jEjOumekblSZV3EtGdY=\"},\"hello-world\":{\"source\":\"HackerThemes\",\"css_url\":\"https://cdn.jsdelivr.net/npm/theme-machine@1.0.1/dist/hello-world/css/bootstrap4-hello-world.min.css\",\"css_integrity\":\"sha256-T/SdIMO9vhVrkjVftsw/Ug1MXlKG8KmNz0YUIZR93E4=\"},\"harbor\":{\"source\":\"HackerThemes\",\"css_url\":\"https://cdn.jsdelivr.net/npm/theme-machine@1.0.1/dist/harbor/css/bootstrap4-harbor.min.css\",\"css_integrity\":\"sha256-H1TZuo7QqPq3eizTWwf6S9ZW6hIz2YEE1LrIPO/mO14=\"},\"growth\":{\"source\":\"HackerThemes\",\"css_url\":\"https://cdn.jsdelivr.net/npm/theme-machine@1.0.1/dist/growth/css/bootstrap4-growth.min.css\",\"css_integrity\":\"sha256-+CiofRWvEbcx3A5I7umqFQjRteAJU63j2IQwvFhBBFg=\"},\"good-news\":{\"source\":\"HackerThemes\",\"css_url\":\"https://cdn.jsdelivr.net/npm/theme-machine@1.0.1/dist/good-news/css/bootstrap4-good-news.min.css\",\"css_integrity\":\"sha256-EU7BH1xQ6ZMHOpUKr4GZv1BuuHraaUxndRptLrxzpgY=\"},\"executive-suite\":{\"source\":\"HackerThemes\",\"css_url\":\"https://cdn.jsdelivr.net/npm/theme-machine@1.0.1/dist/executive-suite/css/bootstrap4-executive-suite.min.css\",\"css_integrity\":\"sha256-fatBtcL6U/lzN+d8WQ/kp2svKuP1vTlIte4lVdxTDmQ=\"},\"deeply\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/deeply/theme.min.css\",\"css_integrity\":\"sha384-d2wvOrnpQB4zifB3/x5sf7HYrUfQo6Lp1AedKCmahd2L0VMG5Co6Dftzc/qfmzWN\",\"includeBS4css\":true},\"electro\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/electro/theme.min.css\",\"css_integrity\":\"sha384-vjKKCvNBDytbeiKQrgVZJQ6yuXEwRFsiNXfngwLbESX2uIUJAJ0UOHW+1XCbYfCE\",\"includeBS4css\":true},\"graymor\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/graymor/theme.min.css\",\"css_integrity\":\"sha384-BpfdSzW0kF9h6mYDnNHgtpEh0FHi1fxRnDhCZbuf/HrqLxZ5K3FwJwnrfRu2+0ED\",\"includeBS4css\":true},\"hollar\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/hollar/theme.min.css\",\"css_integrity\":\"sha384-XTX6UARS60yRXsvHf049FGbU8gQ7FDQ60J8t33ozlLIm2W6Q9c4IY0feFEqCgaM2\",\"includeBS4css\":true},\"lymcha\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/lymcha/theme.min.css\",\"css_integrity\":\"sha384-DeSqkOX0VYx4Q1qcGz3oLDM3EAq2I63z/r/a9MEQZ9LzH3dLjW5raHyorKsLw7TK\",\"includeBS4css\":true},\"mickie\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/mickie/theme.min.css\",\"css_integrity\":\"sha384-+EmsurWpPwJut/2oX59Xb6qVWGHF1rTTwjH2vGPER1nIBnNykUeV375gcMaya5zZ\",\"includeBS4css\":true},\"minco\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/minco/theme.min.css\",\"css_integrity\":\"sha384-fAD0S+5D+lyDo7OahYHpMV93k0loAE9bDpL8yuYQ6YA3+VVV7dtNfnj+1q30dgT4\",\"includeBS4css\":true},\"monotone\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/monotone/theme.min.css\",\"css_integrity\":\"sha384-Sh/5tbsiTfVkxykG1i2fj0io0WqNNa8529bSWgMVD9SlXdpbpUEmfpaYHq1qW4qK\",\"includeBS4css\":true},\"preptor\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/preptor/theme.min.css\",\"css_integrity\":\"sha384-iteL5PaUsmJhIynOKbgZd8B0fPokn6J/cgOaAlZV/uHQ5qYs/3Tuj99wEfWUah0U\",\"includeBS4css\":true},\"skeeblu\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/skeeblu/theme.min.css\",\"css_integrity\":\"sha384-89guOBvYarSfEUZx0cbk/G3c1DeHu67XbSjdaflMlEJHA0qrHAvkyspHl3Q4q1OR\",\"includeBS4css\":true},\"sunset\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/sunset/theme.min.css\",\"css_integrity\":\"sha384-jWRGSXf+cIpXGEfML+65G56j7/qjltXjcc7PwNkiR5+16uHytfZEZ4bZUxp4QUIF\",\"includeBS4css\":true},\"wandoo\":{\"source\":\"TopHat\",\"css_url\":\"https://unpkg.com/top-hat-themes@0.1.0/dist/wandoo/theme.min.css\",\"css_integrity\":\"sha384-knFmJrpbzGYqIKI3TcX3kcoMB466WTj4vqMSUhfEKnkKx6d8QzPr+x+K9FKBmJS2\",\"includeBS4css\":true},\"furni\":{\"source\":\"Untree.co\",\"includeBS5css\":true,\"fonts\":{\"Inter\":\"Inter, sans-serif\"},\"local_css_file\":\"themewagon/furni.css\"},\"villa-agency\":{\"source\":\"TemplateMo\",\"includeBS5css\":true,\"in_header\":\"<link href=\\\\\"https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap\\\\\" rel=\\\\\"stylesheet\\\\\">\",\"fonts\":{\"Poppins\":\"Poppins, sans-serif\"},\"local_css_file\":\"themewagon/templatemo-villa-agency.css\"},\"food-wagon\":{\"source\":\"ThemeWagon\",\"includeBS5css\":false,\"in_header\":\"<link href=\\\\\"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@200;300;400;600;700;900&amp;display=swap\\\\\" rel=\\\\\"stylesheet\\\\\">\",\"fonts\":{\"Source Sans Pro\":\"\\\\\"Source Sans Pro\\\\\",\\\\\"Open Sans\\\\\",-apple-system,BlinkMacSystemFont,\\\\\"Segoe UI\\\\\",\\\\\"Helvetica Neue\\\\\",Arial,sans-serif,\\\\\"Apple Color Emoji\\\\\",\\\\\"Segoe UI Emoji\\\\\",\\\\\"Segoe UI Symbol\\\\\";\"},\"local_css_file\":\"themewagon/foodwagon.min.css\"},\"carserv\":{\"source\":\"HTML Codex\",\"local_css_file\":\"themewagon/carserv.css\",\"fonts\":{\"Barlow\":\"Barlow, sans-serif\",\"Ubuntu\":\"Ubuntu, sans-serif\"},\"in_header\":\"<link href=\\\\\"https://fonts.googleapis.com/css2?family=Barlow:wght@600;700&family=Ubuntu:wght@400;500&display=swap\\\\\" rel=\\\\\"stylesheet\\\\\">\"},\"agency\":{\"source\":\"StartBootstrap\",\"includeBS5css\":false,\"in_header\":\"<link href=\\\\\"https://fonts.googleapis.com/css?family=Montserrat:400,700\\\\\" rel=\\\\\"stylesheet\\\\\" type=\\\\\"text/css\\\\\" /><link href=\\\\\"https://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700\\\\\" rel=\\\\\"stylesheet\\\\\" type=\\\\\"text/css\\\\\" />\",\"fonts\":{\"Montserrat\":\"\\\\\"Montserrat\\\\\", -apple-system, BlinkMacSystemFont, \\\\\"Segoe UI\\\\\", Roboto, \\\\\"Helvetica Neue\\\\\", Arial, sans-serif, \\\\\"Apple Color Emoji\\\\\", \\\\\"Segoe UI Emoji\\\\\", \\\\\"Segoe UI Symbol\\\\\", \\\\\"Noto Color Emoji\\\\\"\",\"Roberto Slab\":\"\\\\\"Roboto Slab\\\\\", -apple-system, BlinkMacSystemFont, \\\\\"Segoe UI\\\\\", Roboto, \\\\\"Helvetica Neue\\\\\", Arial, sans-serif, \\\\\"Apple Color Emoji\\\\\", \\\\\"Segoe UI Emoji\\\\\", \\\\\"Segoe UI Symbol\\\\\", \\\\\"Noto Color Emoji\\\\\"\"},\"local_css_file\":\"themewagon/agency.css\"},\"HighTechIT\":{\"source\":\"HTML Codex\",\"includeBS5css\":true,\"local_css_file\":\"themewagon/hightechit.css\",\"in_header\":\"<link href=\\\\\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Saira:wght@500;600;700&display=swap\\\\\" rel=\\\\\"stylesheet\\\\\">\",\"fonts\":{\"Inter\":\"Inter, sans-serif\",\"Saira\":\"Inter, sans-serif\"}}}');\n\n//# sourceURL=webpack://saltcorn/../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/themes.json?\n}");
60
+
61
+ /***/ }
62
+
63
+ },
64
+ /******/ __webpack_require__ => { // webpackRuntimeModules
65
+ /******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
66
+ /******/ __webpack_require__.O(0, ["common_chunks","data"], () => (__webpack_exec__("../../../.local/share/saltcorn-plugins/plugins_folder/@saltcorn/any-bootstrap-theme/0.6.10/index.js")));
67
+ /******/ var __webpack_exports__ = __webpack_require__.O();
68
+ /******/ return __webpack_exports__;
69
+ /******/ }
70
+ ]);
71
+ });