mirror of
https://github.com/HeyPuter/puter.git
synced 2026-09-25 06:36:00 +00:00
Merge pull request #422 from HeyPuter/eric/gui-loading
GUI loading refactor + service-registered gui scripts
This commit is contained in:
@@ -213,6 +213,9 @@ const install = async ({ services, app }) => {
|
||||
|
||||
const { LockService } = require('./services/LockService');
|
||||
services.registerService('lock', LockService);
|
||||
|
||||
const { PuterHomepageService } = require('./services/PuterHomepageService');
|
||||
services.registerService('puter-homepage', PuterHomepageService);
|
||||
}
|
||||
|
||||
const install_legacy = async ({ services }) => {
|
||||
|
||||
@@ -79,6 +79,7 @@ config.puter_hosted_data = {
|
||||
const path_ = require('path');
|
||||
config.assets = {
|
||||
gui: path_.join(__dirname, '../../..'),
|
||||
gui_profile: 'development',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -174,9 +175,25 @@ const config_pointer = {};
|
||||
// We'd like to store values changed at runtime separately
|
||||
// for easier runtime debugging
|
||||
{
|
||||
const config_runtime_values = {};
|
||||
const config_runtime_values = {
|
||||
$: 'runtime-values'
|
||||
};
|
||||
config_runtime_values.__proto__ = config_to_export;
|
||||
config_to_export = config_runtime_values
|
||||
|
||||
// These can be difficult to find and cause painful
|
||||
// confusing issues, so we log any time this happens
|
||||
config_to_export = new Proxy(config_to_export, {
|
||||
set: (target, prop, value, receiver) => {
|
||||
console.log(
|
||||
'\x1B[36;1mCONFIGURATION MUTATED AT RUNTIME\x1B[0m',
|
||||
prop, 'to', value
|
||||
);
|
||||
// console.log(new Error('stack trace to find configuration mutation'));
|
||||
target[prop] = value;
|
||||
return true;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = config_to_export;
|
||||
module.exports = config_to_export;
|
||||
|
||||
@@ -23,7 +23,6 @@ const router = express.Router();
|
||||
const _path = require('path');
|
||||
const _fs = require('fs');
|
||||
const auth = require('../middleware/auth.js');
|
||||
const { generate_puter_page_html } = require('../temp/puter_page_loader');
|
||||
const { Context } = require('../util/context');
|
||||
const { DB_READ } = require('../services/database/consts');
|
||||
const { PathBuilder } = require('../util/pathutil.js');
|
||||
@@ -302,47 +301,14 @@ router.all('*', async function(req, res, next) {
|
||||
|
||||
// index.js
|
||||
if(path === '/'){
|
||||
const APP_ORIGIN = config.origin;
|
||||
const API_ORIGIN = config.api_base_url;
|
||||
return res.send(generate_puter_page_html({
|
||||
env: config.env,
|
||||
|
||||
app_origin: APP_ORIGIN,
|
||||
api_origin: API_ORIGIN,
|
||||
use_bundled_gui: config.use_bundled_gui,
|
||||
|
||||
manifest,
|
||||
gui_path: config.assets.gui,
|
||||
|
||||
// page meta
|
||||
meta: {
|
||||
title: app_title,
|
||||
description: description || config.short_description,
|
||||
short_description: config.short_description,
|
||||
company: 'Puter Technologies Inc.',
|
||||
canonical_url: canonical_url,
|
||||
},
|
||||
|
||||
// gui parameters
|
||||
gui_params: {
|
||||
app_name_regex: config.app_name_regex,
|
||||
app_name_max_length: config.app_name_max_length,
|
||||
app_title_max_length: config.app_title_max_length,
|
||||
subdomain_regex: config.subdomain_regex,
|
||||
subdomain_max_length: config.subdomain_max_length,
|
||||
domain: config.domain,
|
||||
protocol: config.protocol,
|
||||
env: config.env,
|
||||
api_base_url: config.api_base_url,
|
||||
thumb_width: config.thumb_width,
|
||||
thumb_height: config.thumb_height,
|
||||
contact_email: config.contact_email,
|
||||
max_fsentry_name_length: config.max_fsentry_name_length,
|
||||
require_email_verification_to_publish_website: config.require_email_verification_to_publish_website,
|
||||
short_description: config.short_description,
|
||||
long_description: config.long_description,
|
||||
},
|
||||
}));
|
||||
const svc_puterHomepage = Context.get('services').get('puter-homepage');
|
||||
return svc_puterHomepage.send(res, {
|
||||
title: app_title,
|
||||
description: description || config.short_description,
|
||||
short_description: config.short_description,
|
||||
company: 'Puter Technologies Inc.',
|
||||
canonical_url: canonical_url,
|
||||
});
|
||||
}
|
||||
|
||||
// /dist/...
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
const { PathBuilder } = require("../util/pathutil");
|
||||
const BaseService = require("./BaseService");
|
||||
|
||||
/**
|
||||
* PuterHomepageService serves the initial HTML page that loads the Puter GUI
|
||||
* and all of its assets.
|
||||
*/
|
||||
class PuterHomepageService extends BaseService {
|
||||
static MODULES = {
|
||||
fs: require('node:fs'),
|
||||
}
|
||||
|
||||
_construct () {
|
||||
this.service_scripts = [];
|
||||
}
|
||||
|
||||
async _init () {
|
||||
// Load manifest
|
||||
const config = this.global_config;
|
||||
const manifest_raw = this.modules.fs.readFileSync(
|
||||
PathBuilder
|
||||
.add(config.assets.gui, { allow_traversal: true })
|
||||
.add('puter-gui.json')
|
||||
.build(),
|
||||
'utf8'
|
||||
);
|
||||
const manifest_data = JSON.parse(manifest_raw);
|
||||
this.manifest = manifest_data[config.assets.gui_profile];
|
||||
}
|
||||
|
||||
register_script (url) {
|
||||
this.service_scripts.push(url);
|
||||
}
|
||||
|
||||
async send (res, meta) {
|
||||
const config = this.global_config;
|
||||
return res.send(this.generate_puter_page_html({
|
||||
env: config.env,
|
||||
|
||||
app_origin: config.origin,
|
||||
api_origin: config.api_base_url,
|
||||
use_bundled_gui: config.use_bundled_gui,
|
||||
|
||||
manifest: this.manifest,
|
||||
gui_path: config.assets.gui,
|
||||
|
||||
// page meta
|
||||
meta,
|
||||
|
||||
// gui parameters
|
||||
gui_params: {
|
||||
app_name_regex: config.app_name_regex,
|
||||
app_name_max_length: config.app_name_max_length,
|
||||
app_title_max_length: config.app_title_max_length,
|
||||
subdomain_regex: config.subdomain_regex,
|
||||
subdomain_max_length: config.subdomain_max_length,
|
||||
domain: config.domain,
|
||||
protocol: config.protocol,
|
||||
env: config.env,
|
||||
api_base_url: config.api_base_url,
|
||||
thumb_width: config.thumb_width,
|
||||
thumb_height: config.thumb_height,
|
||||
contact_email: config.contact_email,
|
||||
max_fsentry_name_length: config.max_fsentry_name_length,
|
||||
require_email_verification_to_publish_website: config.require_email_verification_to_publish_website,
|
||||
short_description: config.short_description,
|
||||
long_description: config.long_description,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
generate_puter_page_html ({
|
||||
env,
|
||||
|
||||
manifest,
|
||||
gui_path,
|
||||
use_bundled_gui,
|
||||
|
||||
app_origin,
|
||||
api_origin,
|
||||
|
||||
meta,
|
||||
|
||||
gui_params,
|
||||
}) {
|
||||
const require = this.require;
|
||||
const {encode} = require('html-entities');
|
||||
const path_ = require('path');
|
||||
const fs_ = require('fs');
|
||||
|
||||
const e = encode;
|
||||
|
||||
const {
|
||||
title,
|
||||
description,
|
||||
short_description,
|
||||
company,
|
||||
canonical_url,
|
||||
} = meta;
|
||||
|
||||
gui_params = {
|
||||
...meta,
|
||||
...gui_params,
|
||||
app_origin,
|
||||
api_origin,
|
||||
gui_origin: app_origin,
|
||||
};
|
||||
|
||||
const asset_dir = env === 'dev'
|
||||
? '/src' : '/dist' ;
|
||||
// const asset_dir = '/dist';
|
||||
|
||||
gui_params.asset_dir = asset_dir;
|
||||
|
||||
const bundled = env != 'dev' || use_bundled_gui;
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>${e(title)}</title>
|
||||
<meta name="author" content="${e(company)}">
|
||||
<meta name="description" content="${e((description).replace(/\n/g, " "))}">
|
||||
<meta name="facebook-domain-verification" content="e29w3hjbnnnypf4kzk2cewcdaxym1y" />
|
||||
<link rel="canonical" href="${e(canonical_url)}">
|
||||
|
||||
<!-- Meta meta tags -->
|
||||
<meta property="og:url" content="${app_origin}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="${e(title)}">
|
||||
<meta property="og:description" content="${e((short_description).replace(/\n/g, " "))}">
|
||||
<meta property="og:image" content="${asset_dir}/images/screenshot.png">
|
||||
|
||||
<!-- Twitter meta tags -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta property="twitter:domain" content="puter.com">
|
||||
<meta property="twitter:url" content="${app_origin}">
|
||||
<meta name="twitter:title" content="${e(title)}">
|
||||
<meta name="twitter:description" content="${e((short_description).replace(/\n/g, " "))}">
|
||||
<meta name="twitter:image" content="${asset_dir}/images/screenshot.png">
|
||||
|
||||
<!-- favicons -->
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="${asset_dir}/favicons/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="${asset_dir}/favicons/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="${asset_dir}/favicons/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="${asset_dir}/favicons/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="${asset_dir}/favicons/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="${asset_dir}/favicons/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="${asset_dir}/favicons/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="${asset_dir}/favicons/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="${asset_dir}/favicons/apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="${asset_dir}/favicons/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="${asset_dir}/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="${asset_dir}/favicons/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="${asset_dir}/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="${asset_dir}/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="${asset_dir}/favicons/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<!-- Preload images when applicable -->
|
||||
<link rel="preload" as="image" href="${asset_dir}/images/wallpaper.webp">
|
||||
|
||||
<!-- Files from JSON (may be empty) -->
|
||||
${
|
||||
((!bundled && manifest?.css_paths)
|
||||
? manifest.css_paths.map(path => `<link rel="stylesheet" href="${path}">\n`)
|
||||
: []).join('')
|
||||
}
|
||||
<!-- END Files from JSON -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>window.puter_gui_enabled = true;</script>
|
||||
${
|
||||
use_bundled_gui
|
||||
? `<script>window.gui_env = 'prod';</script>`
|
||||
: ''
|
||||
}
|
||||
${
|
||||
((!bundled && manifest?.lib_paths)
|
||||
? manifest.lib_paths.map(path => `<script type="text/javascript" src="${path}"></script>\n`)
|
||||
: []).join('')
|
||||
}
|
||||
|
||||
<script>
|
||||
window.icons = {};
|
||||
|
||||
${(() => {
|
||||
if ( !(!bundled && manifest) ) return '';
|
||||
const html = [];
|
||||
fs_.readdirSync(path_.join(gui_path, 'src/icons')).forEach(file => {
|
||||
// skip dotfiles
|
||||
if(file.startsWith('.'))
|
||||
return;
|
||||
// load image
|
||||
let buff = new Buffer.from(fs_.readFileSync(path_.join(gui_path, 'src/icons') + '/' + file));
|
||||
// convert to base64
|
||||
let base64data = buff.toString('base64');
|
||||
// add to `window.icons`
|
||||
if(file.endsWith('.png'))
|
||||
html.push(`window.icons['${file}'] = "data:image/png;base64,${base64data}";\n`);
|
||||
else if(file.endsWith('.svg'))
|
||||
html.push(`window.icons['${file}'] = "data:image/svg+xml;base64,${base64data}";\n`);
|
||||
})
|
||||
return html.join('');
|
||||
})()}
|
||||
</script>
|
||||
|
||||
${
|
||||
((!bundled && manifest?.js_paths)
|
||||
? manifest.js_paths.map(path => `<script type="module" src="${path}"></script>\n`)
|
||||
: []).join('')
|
||||
}
|
||||
${
|
||||
this.service_scripts
|
||||
.map(path => `<script type="module" src="${path}"></script>\n`)
|
||||
.join('')
|
||||
}
|
||||
<!-- Load the GUI script -->
|
||||
<script ${ !bundled ? ' type="module"' : ''} src="${(!bundled && manifest?.index) || '/dist/gui.js'}"></script>
|
||||
<!-- Initialize GUI when document is loaded -->
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
gui(${
|
||||
// TODO: override JSON.stringify to ALWAYS to this...
|
||||
// this should be an opt-OUT, not an opt-IN!
|
||||
JSON.stringify(gui_params).replace(/</g, '\\u003c')
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<div id="templates" style="display: none;"></div>
|
||||
</body>
|
||||
|
||||
</html>`;
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
PuterHomepageService
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
/**
|
||||
* ServeLandingService is for "landing" pages, like payment success or failure.
|
||||
*/
|
||||
class ServceLandingService {}
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const {encode} = require('html-entities');
|
||||
const path_ = require('path');
|
||||
const fs_ = require('fs');
|
||||
|
||||
const generate_puter_page_html = ({
|
||||
env,
|
||||
|
||||
manifest,
|
||||
gui_path,
|
||||
use_bundled_gui,
|
||||
|
||||
app_origin,
|
||||
api_origin,
|
||||
|
||||
meta,
|
||||
|
||||
gui_params,
|
||||
}) => {
|
||||
const e = encode;
|
||||
|
||||
const {
|
||||
title,
|
||||
description,
|
||||
short_description,
|
||||
company,
|
||||
canonical_url,
|
||||
} = meta;
|
||||
|
||||
gui_params = {
|
||||
...meta,
|
||||
...gui_params,
|
||||
app_origin,
|
||||
api_origin,
|
||||
gui_origin: app_origin,
|
||||
};
|
||||
|
||||
const asset_dir = env === 'dev'
|
||||
? '/src' : '/dist' ;
|
||||
// const asset_dir = '/dist';
|
||||
|
||||
gui_params.asset_dir = asset_dir;
|
||||
|
||||
const bundled = env != 'dev' || use_bundled_gui;
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>${e(title)}</title>
|
||||
<meta name="author" content="${e(company)}">
|
||||
<meta name="description" content="${e((description).replace(/\n/g, " "))}">
|
||||
<meta name="facebook-domain-verification" content="e29w3hjbnnnypf4kzk2cewcdaxym1y" />
|
||||
<link rel="canonical" href="${e(canonical_url)}">
|
||||
|
||||
<!-- Meta meta tags -->
|
||||
<meta property="og:url" content="${app_origin}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="${e(title)}">
|
||||
<meta property="og:description" content="${e((short_description).replace(/\n/g, " "))}">
|
||||
<meta property="og:image" content="${asset_dir}/images/screenshot.png">
|
||||
|
||||
<!-- Twitter meta tags -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta property="twitter:domain" content="puter.com">
|
||||
<meta property="twitter:url" content="${app_origin}">
|
||||
<meta name="twitter:title" content="${e(title)}">
|
||||
<meta name="twitter:description" content="${e((short_description).replace(/\n/g, " "))}">
|
||||
<meta name="twitter:image" content="${asset_dir}/images/screenshot.png">
|
||||
|
||||
<!-- favicons -->
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="${asset_dir}/favicons/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="${asset_dir}/favicons/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="${asset_dir}/favicons/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="${asset_dir}/favicons/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="${asset_dir}/favicons/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="${asset_dir}/favicons/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="${asset_dir}/favicons/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="${asset_dir}/favicons/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="${asset_dir}/favicons/apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="${asset_dir}/favicons/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="${asset_dir}/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="${asset_dir}/favicons/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="${asset_dir}/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="${asset_dir}/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="${asset_dir}/favicons/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<!-- Preload images when applicable -->
|
||||
<link rel="preload" as="image" href="${asset_dir}/images/wallpaper.webp">
|
||||
|
||||
<!-- Files from JSON (may be empty) -->
|
||||
${
|
||||
((!bundled && manifest?.css_paths)
|
||||
? manifest.css_paths.map(path => `<link rel="stylesheet" href="${path}">\n`)
|
||||
: []).join('')
|
||||
}
|
||||
<!-- END Files from JSON -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>window.puter_gui_enabled = true;</script>
|
||||
${
|
||||
use_bundled_gui
|
||||
? `<script>window.gui_env = 'prod';</script>`
|
||||
: ''
|
||||
}
|
||||
${
|
||||
((!bundled && manifest?.lib_paths)
|
||||
? manifest.lib_paths.map(path => `<script type="text/javascript" src="${path}"></script>\n`)
|
||||
: []).join('')
|
||||
}
|
||||
|
||||
<script>
|
||||
window.icons = {};
|
||||
|
||||
${(() => {
|
||||
if ( !(!bundled && manifest) ) return '';
|
||||
const html = [];
|
||||
fs_.readdirSync(path_.join(gui_path, 'src/icons')).forEach(file => {
|
||||
// skip dotfiles
|
||||
if(file.startsWith('.'))
|
||||
return;
|
||||
// load image
|
||||
let buff = new Buffer.from(fs_.readFileSync(path_.join(gui_path, 'src/icons') + '/' + file));
|
||||
// convert to base64
|
||||
let base64data = buff.toString('base64');
|
||||
// add to `window.icons`
|
||||
if(file.endsWith('.png'))
|
||||
html.push(`window.icons['${file}'] = "data:image/png;base64,${base64data}";\n`);
|
||||
else if(file.endsWith('.svg'))
|
||||
html.push(`window.icons['${file}'] = "data:image/svg+xml;base64,${base64data}";\n`);
|
||||
})
|
||||
return html.join('');
|
||||
})()}
|
||||
</script>
|
||||
|
||||
${
|
||||
((!bundled && manifest?.js_paths)
|
||||
? manifest.js_paths.map(path => `<script type="module" src="${path}"></script>\n`)
|
||||
: []).join('')
|
||||
}
|
||||
<!-- Load the GUI script -->
|
||||
<script ${ !bundled ? ' type="module"' : ''} src="${(!bundled && manifest?.index) || '/dist/gui.js'}"></script>
|
||||
<!-- Initialize GUI when document is loaded -->
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
gui(${
|
||||
// TODO: override JSON.stringify to ALWAYS to this...
|
||||
// this should be an opt-OUT, not an opt-IN!
|
||||
JSON.stringify(gui_params).replace(/</g, '\\u003c')
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<div id="templates" style="display: none;"></div>
|
||||
</body>
|
||||
|
||||
</html>`;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
generate_puter_page_html,
|
||||
};
|
||||
+35
-30
@@ -1,32 +1,37 @@
|
||||
{
|
||||
"index": "/src/index.js",
|
||||
"lib_paths": [
|
||||
"/lib/jquery-3.6.1/jquery-3.6.1.min.js",
|
||||
"/lib/viselect.min.js",
|
||||
"/lib/FileSaver.min.js",
|
||||
"/lib/socket.io/socket.io.min.js",
|
||||
"/lib/qrcode.min.js",
|
||||
"/lib/jquery-ui-1.13.2/jquery-ui.min.js",
|
||||
"/lib/lodash@4.17.21.min.js",
|
||||
"/lib/jquery.dragster.js",
|
||||
"/lib/jquery.menu-aim.js",
|
||||
"/lib/html-entities.js",
|
||||
"/lib/timeago.min.js",
|
||||
"/lib/iro.min.js",
|
||||
"/lib/isMobile.min.js",
|
||||
"/lib/jszip-3.10.1.min.js"
|
||||
],
|
||||
"css_paths": [
|
||||
"/css/normalize.css",
|
||||
"/lib/jquery-ui-1.13.2/jquery-ui.min.css",
|
||||
"/css/style.css",
|
||||
"/css/theme.css"
|
||||
],
|
||||
"js_paths": [
|
||||
"/src/initgui.js",
|
||||
"/src/helpers.js",
|
||||
"/src/IPC.js",
|
||||
"/src/globals.js",
|
||||
"/src/i18n/i18n.js"
|
||||
]
|
||||
"development": {
|
||||
"index": "/src/index.js",
|
||||
"lib_paths": [
|
||||
"/lib/jquery-3.6.1/jquery-3.6.1.min.js",
|
||||
"/lib/viselect.min.js",
|
||||
"/lib/FileSaver.min.js",
|
||||
"/lib/socket.io/socket.io.min.js",
|
||||
"/lib/qrcode.min.js",
|
||||
"/lib/jquery-ui-1.13.2/jquery-ui.min.js",
|
||||
"/lib/lodash@4.17.21.min.js",
|
||||
"/lib/jquery.dragster.js",
|
||||
"/lib/jquery.menu-aim.js",
|
||||
"/lib/html-entities.js",
|
||||
"/lib/timeago.min.js",
|
||||
"/lib/iro.min.js",
|
||||
"/lib/isMobile.min.js",
|
||||
"/lib/jszip-3.10.1.min.js"
|
||||
],
|
||||
"css_paths": [
|
||||
"/css/normalize.css",
|
||||
"/lib/jquery-ui-1.13.2/jquery-ui.min.css",
|
||||
"/css/style.css",
|
||||
"/css/theme.css"
|
||||
],
|
||||
"js_paths": [
|
||||
"/src/initgui.js",
|
||||
"/src/helpers.js",
|
||||
"/src/IPC.js",
|
||||
"/src/globals.js",
|
||||
"/src/i18n/i18n.js"
|
||||
]
|
||||
},
|
||||
"bundle": {
|
||||
"index": ["/dist/gui.js", false]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user