underpost 2.85.7 → 2.89.1
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.
- package/.github/workflows/release.cd.yml +3 -1
- package/README.md +2 -2
- package/bin/build.js +8 -10
- package/bin/index.js +8 -1
- package/cli.md +3 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +50 -50
- package/manifests/deployment/dd-test-development/proxy.yaml +4 -4
- package/package.json +1 -1
- package/scripts/rpmfusion-ffmpeg-setup.sh +55 -0
- package/src/api/file/file.service.js +29 -3
- package/src/cli/baremetal.js +1 -2
- package/src/cli/index.js +1 -0
- package/src/cli/repository.js +8 -1
- package/src/cli/run.js +104 -36
- package/src/client/components/core/AgGrid.js +42 -3
- package/src/client/components/core/CommonJs.js +4 -0
- package/src/client/components/core/Css.js +95 -48
- package/src/client/components/core/CssCore.js +0 -1
- package/src/client/components/core/LoadingAnimation.js +2 -2
- package/src/client/components/core/Logger.js +2 -9
- package/src/client/components/core/Modal.js +22 -14
- package/src/client/components/core/ObjectLayerEngine.js +300 -9
- package/src/client/components/core/ObjectLayerEngineModal.js +686 -148
- package/src/client/components/core/ObjectLayerEngineViewer.js +1061 -0
- package/src/client/components/core/Pagination.js +57 -12
- package/src/client/components/core/Router.js +37 -1
- package/src/client/components/core/Translate.js +4 -0
- package/src/client/components/core/Worker.js +8 -1
- package/src/client/services/default/default.management.js +86 -16
- package/src/db/mariadb/MariaDB.js +2 -2
- package/src/index.js +1 -1
- package/src/server/client-build.js +57 -2
- package/src/server/object-layer.js +44 -0
- package/src/server/start.js +12 -0
- package/src/ws/IoInterface.js +2 -3
- package/AUTHORS.md +0 -21
- package/src/server/network.js +0 -72
package/src/cli/run.js
CHANGED
|
@@ -58,6 +58,8 @@ class UnderpostRun {
|
|
|
58
58
|
* @property {string} stdin - The stdin option for the container.
|
|
59
59
|
* @property {string} restartPolicy - The restart policy for the container.
|
|
60
60
|
* @property {boolean} terminal - Whether to open a terminal.
|
|
61
|
+
* @property {number} devProxyPortOffset - The port offset for the development proxy.
|
|
62
|
+
* @property {string} confServerPath - The configuration server path.
|
|
61
63
|
* @memberof UnderpostRun
|
|
62
64
|
*/
|
|
63
65
|
static DEFAULT_OPTION = {
|
|
@@ -80,6 +82,7 @@ class UnderpostRun {
|
|
|
80
82
|
restartPolicy: '',
|
|
81
83
|
terminal: false,
|
|
82
84
|
devProxyPortOffset: 0,
|
|
85
|
+
confServerPath: '',
|
|
83
86
|
};
|
|
84
87
|
/**
|
|
85
88
|
* @static
|
|
@@ -257,30 +260,6 @@ class UnderpostRun {
|
|
|
257
260
|
shellExec(`node bin deploy --restore-hosts`);
|
|
258
261
|
},
|
|
259
262
|
|
|
260
|
-
/**
|
|
261
|
-
* @method cyberia-ide
|
|
262
|
-
* @description Starts the development environment (IDE) for both `cyberia-server` and `cyberia-client` repositories.
|
|
263
|
-
* @param {string} path - The input value, identifier, or path for the operation.
|
|
264
|
-
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
265
|
-
* @memberof UnderpostRun
|
|
266
|
-
*/
|
|
267
|
-
'cyberia-ide': (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
268
|
-
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
269
|
-
shellExec(`${baseCommand} run ide /home/dd/cyberia-server`);
|
|
270
|
-
shellExec(`${baseCommand} run ide /home/dd/cyberia-client`);
|
|
271
|
-
},
|
|
272
|
-
/**
|
|
273
|
-
* @method engine-ide
|
|
274
|
-
* @description Starts the development environment (IDE) for the `engine` and `engine-private` repositories.
|
|
275
|
-
* @param {string} path - The input value, identifier, or path for the operation.
|
|
276
|
-
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
277
|
-
* @memberof UnderpostRun
|
|
278
|
-
*/
|
|
279
|
-
'engine-ide': (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
280
|
-
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
281
|
-
shellExec(`${baseCommand} run ide /home/dd/engine`);
|
|
282
|
-
shellExec(`${baseCommand} run ide /home/dd/engine/engine-private`);
|
|
283
|
-
},
|
|
284
263
|
/**
|
|
285
264
|
* @method cluster-build
|
|
286
265
|
* @description Build configuration for cluster deployment.
|
|
@@ -293,8 +272,12 @@ class UnderpostRun {
|
|
|
293
272
|
shellExec(`node bin run --dev sync-replica template-deploy`);
|
|
294
273
|
shellExec(`node bin run sync-replica template-deploy`);
|
|
295
274
|
shellExec(`node bin env clean`);
|
|
296
|
-
|
|
297
|
-
|
|
275
|
+
for (const deployId of fs.readFileSync('./engine-private/deploy/dd.router', 'utf8').split(','))
|
|
276
|
+
shellExec(`node bin/deploy update-default-conf ${deployId.trim()}`);
|
|
277
|
+
if (path === 'cmt') {
|
|
278
|
+
shellExec(`git add . && underpost cmt . build cluster-build`);
|
|
279
|
+
shellExec(`cd engine-private && git add . && underpost cmt . build cluster-build`);
|
|
280
|
+
}
|
|
298
281
|
},
|
|
299
282
|
/**
|
|
300
283
|
* @method template-deploy
|
|
@@ -423,6 +406,7 @@ class UnderpostRun {
|
|
|
423
406
|
// Dev usage: node bin run --dev --build sync dd-default
|
|
424
407
|
const env = options.dev ? 'development' : 'production';
|
|
425
408
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
409
|
+
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
426
410
|
const defaultPath = [
|
|
427
411
|
'dd-default',
|
|
428
412
|
1,
|
|
@@ -440,6 +424,8 @@ class UnderpostRun {
|
|
|
440
424
|
if (isDeployRunnerContext(path, options)) {
|
|
441
425
|
const { validVersion } = UnderpostRepository.API.privateConfUpdate(deployId);
|
|
442
426
|
if (!validVersion) throw new Error('Version mismatch');
|
|
427
|
+
shellExec(`${baseCommand} run${baseClusterCommand} tz`);
|
|
428
|
+
shellExec(`${baseCommand} run${baseClusterCommand} cron`);
|
|
443
429
|
}
|
|
444
430
|
|
|
445
431
|
const currentTraffic = isDeployRunnerContext(path, options)
|
|
@@ -461,6 +447,39 @@ class UnderpostRun {
|
|
|
461
447
|
UnderpostDeploy.API.switchTraffic(deployId, env, targetTraffic);
|
|
462
448
|
} else logger.info('current traffic', UnderpostDeploy.API.getCurrentTraffic(deployId));
|
|
463
449
|
},
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* @method tz
|
|
453
|
+
* @description Sets the system timezone using `timedatectl set-timezone` command.
|
|
454
|
+
* @param {string} path - The input value, identifier, or path for the operation (used as the timezone string).
|
|
455
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
456
|
+
* @memberof UnderpostRun
|
|
457
|
+
*/
|
|
458
|
+
tz: (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
459
|
+
const tz = path
|
|
460
|
+
? path
|
|
461
|
+
: UnderpostRootEnv.API.get('TIME_ZONE', undefined, { disableLog: true })
|
|
462
|
+
? UnderpostRootEnv.API.get('TIME_ZONE')
|
|
463
|
+
: process.env.TIME_ZONE
|
|
464
|
+
? process.env.TIME_ZONE
|
|
465
|
+
: 'America/New_York';
|
|
466
|
+
shellExec(`sudo timedatectl set-timezone ${tz}`);
|
|
467
|
+
},
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* @method cron
|
|
471
|
+
* @description Sets up and starts the `dd-cron` environment by writing environment variables, starting the cron service, and cleaning up.
|
|
472
|
+
* @param {string} path - The input value, identifier, or path for the operation.
|
|
473
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
474
|
+
* @memberof UnderpostRun
|
|
475
|
+
*/
|
|
476
|
+
cron: (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
477
|
+
const env = options.dev ? 'development' : 'production';
|
|
478
|
+
shellExec(`node bin env ${path ? path : 'dd-cron'} ${env}`);
|
|
479
|
+
shellExec(`npm start`);
|
|
480
|
+
shellExec(`node bin env clean`);
|
|
481
|
+
},
|
|
482
|
+
|
|
464
483
|
/**
|
|
465
484
|
* @method ls-deployments
|
|
466
485
|
* @description Retrieves and logs a table of Kubernetes deployments using `UnderpostDeploy.API.get`.
|
|
@@ -806,6 +825,22 @@ class UnderpostRun {
|
|
|
806
825
|
*/
|
|
807
826
|
dev: async (path = '', options = UnderpostRun.DEFAULT_OPTION) => {
|
|
808
827
|
let [deployId, subConf, host, _path, clientHostPort] = path.split(',');
|
|
828
|
+
if (options.confServerPath) {
|
|
829
|
+
const confServer = JSON.parse(fs.readFileSync(options.confServerPath, 'utf8'));
|
|
830
|
+
fs.writeFileSync(
|
|
831
|
+
`./engine-private/conf/${deployId}/conf.server.dev.${subConf}.json`,
|
|
832
|
+
JSON.stringify(
|
|
833
|
+
{
|
|
834
|
+
[host]: {
|
|
835
|
+
[_path]: confServer[host][_path],
|
|
836
|
+
},
|
|
837
|
+
},
|
|
838
|
+
null,
|
|
839
|
+
4,
|
|
840
|
+
),
|
|
841
|
+
'utf8',
|
|
842
|
+
);
|
|
843
|
+
}
|
|
809
844
|
if (!deployId) deployId = 'dd-default';
|
|
810
845
|
if (!host) host = 'default.net';
|
|
811
846
|
if (!_path) _path = '/';
|
|
@@ -820,7 +855,7 @@ class UnderpostRun {
|
|
|
820
855
|
envObj.DEV_PROXY_PORT_OFFSET = options.devProxyPortOffset;
|
|
821
856
|
writeEnv(envPath, envObj);
|
|
822
857
|
}
|
|
823
|
-
shellExec(`node bin run dev-cluster expose
|
|
858
|
+
shellExec(`node bin run dev-cluster expose`, { async: true });
|
|
824
859
|
{
|
|
825
860
|
const cmd = `npm run dev-api ${deployId} ${subConf} ${host} ${_path} ${clientHostPort}${options.tls ? ' tls' : ''}`;
|
|
826
861
|
options.terminal ? openTerminal(cmd) : shellExec(cmd, { async: true });
|
|
@@ -896,6 +931,41 @@ class UnderpostRun {
|
|
|
896
931
|
}
|
|
897
932
|
},
|
|
898
933
|
|
|
934
|
+
/**
|
|
935
|
+
* @method sh
|
|
936
|
+
* @description Enables remote control for the Kitty terminal emulator.
|
|
937
|
+
* @param {string} path - The input value, identifier, or path for the operation.
|
|
938
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
939
|
+
* @memberof UnderpostRun
|
|
940
|
+
*/
|
|
941
|
+
sh: async (path = '', options = UnderpostRun.DEFAULT_OPTION) => {
|
|
942
|
+
let [operator, arg0, arg1] = path.split(',');
|
|
943
|
+
if (operator == 'copy') {
|
|
944
|
+
shellExec(
|
|
945
|
+
`kitty @ get-text ${arg0 === 'all' ? '--match all' : '--self'} --extent all${arg1 === 'ansi' ? ' --ansi yes' : ''} | kitty +kitten clipboard`,
|
|
946
|
+
);
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
shellExec(`kitty -o allow_remote_control=yes`);
|
|
950
|
+
},
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* @method log
|
|
954
|
+
* @description Searches and highlights keywords in a specified log file, optionally showing surrounding lines.
|
|
955
|
+
* @param {string} path - The input value, identifier, or path for the operation (formatted as `filePath,keywords,lines`).
|
|
956
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
957
|
+
* @memberof UnderpostRun
|
|
958
|
+
*/
|
|
959
|
+
log: async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
960
|
+
const [filePath, keywords, lines] = path.split(',');
|
|
961
|
+
let result = shellExec(`grep -i -E ${lines ? `-C ${lines} ` : ''}'${keywords}' ${filePath}`, {
|
|
962
|
+
stdout: true,
|
|
963
|
+
silent: true,
|
|
964
|
+
}).replaceAll(`--`, `==============================`.green.bold);
|
|
965
|
+
for (const keyword of keywords.split('|')) result = result.replaceAll(keyword, keyword.bgYellow.black.bold);
|
|
966
|
+
console.log(result);
|
|
967
|
+
},
|
|
968
|
+
|
|
899
969
|
/**
|
|
900
970
|
* @method release-cmt
|
|
901
971
|
* @description Commits and pushes a new release for the `engine` repository with a message indicating the new version.
|
|
@@ -927,15 +997,13 @@ class UnderpostRun {
|
|
|
927
997
|
const _path = '/single-replica';
|
|
928
998
|
const confServer = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'));
|
|
929
999
|
shellExec(`${baseCommand} env ${deployId} ${env}`);
|
|
930
|
-
for (const host of Object.keys(confServer))
|
|
931
|
-
if (
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
shellExec(`${baseCommand} run${options.dev === true ? ' --dev' : ''} --build sync ${defaultPath}`);
|
|
938
|
-
}
|
|
1000
|
+
for (const host of Object.keys(confServer))
|
|
1001
|
+
if (_path in confServer[host]) shellExec(`node bin/deploy build-single-replica ${deployId} ${host} ${_path}`);
|
|
1002
|
+
const node = options.dev || !isDeployRunnerContext(path, options) ? 'kind-control-plane' : os.hostname();
|
|
1003
|
+
// deployId, replicas, versions, image, node
|
|
1004
|
+
let defaultPath = [deployId, 1, ``, ``, node];
|
|
1005
|
+
shellExec(`${baseCommand} run${options.dev === true ? ' --dev' : ''} --build sync ${defaultPath}`);
|
|
1006
|
+
shellExec(`node bin/deploy build-full-client ${deployId}`);
|
|
939
1007
|
}
|
|
940
1008
|
if (isDeployRunnerContext(path, options)) shellExec(`${baseCommand} run promote ${path} production`);
|
|
941
1009
|
},
|
|
@@ -11,7 +11,7 @@ const AgGrid = {
|
|
|
11
11
|
grids: {},
|
|
12
12
|
theme: `ag-theme-alpine`, // quartz
|
|
13
13
|
Render: async function (options) {
|
|
14
|
-
let { id } = options;
|
|
14
|
+
let { id, paginationOptions } = options;
|
|
15
15
|
setTimeout(() => {
|
|
16
16
|
// Grid Options: Contains all of the grid configurations
|
|
17
17
|
const gridOptions = {
|
|
@@ -34,6 +34,38 @@ const AgGrid = {
|
|
|
34
34
|
return params.data && params.data._new;
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
|
+
// Cell rendering events
|
|
38
|
+
onFirstDataRendered: options?.onFirstDataRendered,
|
|
39
|
+
onViewportChanged: options?.onViewportChanged,
|
|
40
|
+
onModelUpdated: options?.onModelUpdated,
|
|
41
|
+
onVirtualRowRemoved: options?.onVirtualRowRemoved,
|
|
42
|
+
// Cell interaction events
|
|
43
|
+
onCellClicked: options?.onCellClicked,
|
|
44
|
+
onCellDoubleClicked: options?.onCellDoubleClicked,
|
|
45
|
+
onCellFocused: options?.onCellFocused,
|
|
46
|
+
onCellMouseOver: options?.onCellMouseOver,
|
|
47
|
+
onCellMouseOut: options?.onCellMouseOut,
|
|
48
|
+
onCellValueChanged: options?.onCellValueChanged,
|
|
49
|
+
// set background colour on every row, this is probably bad, should be using CSS classes
|
|
50
|
+
// rowStyle: { background: 'black' },
|
|
51
|
+
|
|
52
|
+
// set background colour on even rows again, this looks bad, should be using CSS classes
|
|
53
|
+
// getRowStyle: (params) => {
|
|
54
|
+
// if (params.node.rowIndex % 2 === 0) {
|
|
55
|
+
// return { background: 'red' };
|
|
56
|
+
// }
|
|
57
|
+
// },
|
|
58
|
+
|
|
59
|
+
// all rows assigned CSS class 'my-green-class'
|
|
60
|
+
// rowClass: 'my-green-class',
|
|
61
|
+
|
|
62
|
+
// all even rows assigned 'my-shaded-effect'
|
|
63
|
+
// getRowClass: (params) => {
|
|
64
|
+
// if (params.node.rowIndex % 2 === 0) {
|
|
65
|
+
// return 'my-shaded-effect';
|
|
66
|
+
// }
|
|
67
|
+
// },
|
|
68
|
+
|
|
37
69
|
// domLayout: 'autoHeight', || 'normal'
|
|
38
70
|
// Column Definitions: Defines & controls grid columns.
|
|
39
71
|
columnDefs: options?.gridOptions?.rowData?.[0]
|
|
@@ -62,7 +94,9 @@ const AgGrid = {
|
|
|
62
94
|
if (!options.style || !options.style.height) {
|
|
63
95
|
if (options.parentModal && Modal.Data[options.parentModal].options.observer) {
|
|
64
96
|
Modal.Data[options.parentModal].onObserverListener[id + '-observer'] = ({ width, height }) => {
|
|
65
|
-
if (s(`.${id}`))
|
|
97
|
+
if (s(`.${id}`))
|
|
98
|
+
s(`.${id}`).style.height =
|
|
99
|
+
`${height - 180 + (options.customHeightOffset ? options.customHeightOffset : 0)}px`;
|
|
66
100
|
else delete Modal.Data[options.parentModal].onObserverListener[id + '-observer'];
|
|
67
101
|
};
|
|
68
102
|
s(`.${id}`).style.height = `${s(`.${options.parentModal}`).offsetHeight - 180}px`;
|
|
@@ -70,6 +104,9 @@ const AgGrid = {
|
|
|
70
104
|
}
|
|
71
105
|
});
|
|
72
106
|
const usePagination = options?.usePagination;
|
|
107
|
+
const limitOptionsAttr = paginationOptions?.limitOptions
|
|
108
|
+
? `limit-options='${JSON.stringify(paginationOptions.limitOptions)}'`
|
|
109
|
+
: '';
|
|
73
110
|
return html`
|
|
74
111
|
<div
|
|
75
112
|
class="${id} ${this.theme}${options?.darkTheme ? `-dark` : ''}"
|
|
@@ -77,7 +114,7 @@ const AgGrid = {
|
|
|
77
114
|
? Object.keys(options.style).map((styleKey) => `${styleKey}: ${options.style[styleKey]}; `)
|
|
78
115
|
: ''}"
|
|
79
116
|
></div>
|
|
80
|
-
${usePagination ? `<ag-pagination id="ag-pagination-${id}"></ag-pagination>` : ''}
|
|
117
|
+
${usePagination ? `<ag-pagination id="ag-pagination-${id}" ${limitOptionsAttr}></ag-pagination>` : ''}
|
|
81
118
|
`;
|
|
82
119
|
},
|
|
83
120
|
RenderStyle: async function (
|
|
@@ -159,6 +196,7 @@ const AgGrid = {
|
|
|
159
196
|
${darkTheme
|
|
160
197
|
? html`
|
|
161
198
|
<style>
|
|
199
|
+
.row-new-highlight,
|
|
162
200
|
.ag-row.row-new-highlight {
|
|
163
201
|
background-color: #6d68ff !important;
|
|
164
202
|
transition: background-color 1s ease-out;
|
|
@@ -172,6 +210,7 @@ const AgGrid = {
|
|
|
172
210
|
</style>
|
|
173
211
|
`
|
|
174
212
|
: html`<style>
|
|
213
|
+
.row-new-highlight,
|
|
175
214
|
.ag-row.row-new-highlight {
|
|
176
215
|
background-color: #d0eaf8 !important;
|
|
177
216
|
transition: background-color 1s ease-out;
|
|
@@ -947,6 +947,8 @@ const emotionsData = [
|
|
|
947
947
|
const userRoleEnum = ['admin', 'moderator', 'user', 'guest'];
|
|
948
948
|
const commonAdminGuard = (role) => userRoleEnum.indexOf(role) === userRoleEnum.indexOf('admin');
|
|
949
949
|
const commonModeratorGuard = (role) => userRoleEnum.indexOf(role) <= userRoleEnum.indexOf('moderator');
|
|
950
|
+
const commonUserGuard = (role) => userRoleEnum.indexOf(role) <= userRoleEnum.indexOf('user');
|
|
951
|
+
const commonGuestGuard = (role) => userRoleEnum.indexOf(role) <= userRoleEnum.indexOf('guest');
|
|
950
952
|
|
|
951
953
|
export {
|
|
952
954
|
s4,
|
|
@@ -1003,6 +1005,8 @@ export {
|
|
|
1003
1005
|
generateRandomPasswordSelection,
|
|
1004
1006
|
commonAdminGuard,
|
|
1005
1007
|
commonModeratorGuard,
|
|
1008
|
+
commonUserGuard,
|
|
1009
|
+
commonGuestGuard,
|
|
1006
1010
|
isChileanIdentityDocument,
|
|
1007
1011
|
getCurrentTrace,
|
|
1008
1012
|
userRoleEnum,
|
|
@@ -221,8 +221,11 @@ const borderChar = (px, color, selectors, hover = false) => {
|
|
|
221
221
|
(selector) => html`
|
|
222
222
|
<style>
|
|
223
223
|
${selector}${hover ? ':hover' : ''} {
|
|
224
|
-
text-shadow:
|
|
225
|
-
|
|
224
|
+
text-shadow:
|
|
225
|
+
${px}px -${px}px ${px}px ${color},
|
|
226
|
+
-${px}px ${px}px ${px}px ${color},
|
|
227
|
+
-${px}px -${px}px ${px}px ${color},
|
|
228
|
+
${px}px ${px}px ${px}px ${color};
|
|
226
229
|
}
|
|
227
230
|
</style>
|
|
228
231
|
`,
|
|
@@ -239,20 +242,28 @@ const boxShadow = ({ selector }) => html`
|
|
|
239
242
|
? html`
|
|
240
243
|
<style>
|
|
241
244
|
${selector} {
|
|
242
|
-
box-shadow:
|
|
245
|
+
box-shadow:
|
|
246
|
+
0 4px 8px 0 rgba(255, 255, 255, 0.1),
|
|
247
|
+
0 6px 20px 0 rgba(255, 255, 255, 0.08);
|
|
243
248
|
}
|
|
244
249
|
${selector}:hover {
|
|
245
|
-
box-shadow:
|
|
250
|
+
box-shadow:
|
|
251
|
+
0 8px 16px 0 rgba(255, 255, 255, 0.15),
|
|
252
|
+
0 10px 30px 0 rgba(255, 255, 255, 0.1);
|
|
246
253
|
}
|
|
247
254
|
</style>
|
|
248
255
|
`
|
|
249
256
|
: html`
|
|
250
257
|
<style>
|
|
251
258
|
${selector} {
|
|
252
|
-
box-shadow:
|
|
259
|
+
box-shadow:
|
|
260
|
+
0 4px 8px 0 rgba(0, 0, 0, 0.2),
|
|
261
|
+
0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
|
253
262
|
}
|
|
254
263
|
${selector}:hover {
|
|
255
|
-
box-shadow:
|
|
264
|
+
box-shadow:
|
|
265
|
+
0 8px 16px 0 rgba(0, 0, 0, 0.2),
|
|
266
|
+
0 10px 30px 0 rgba(0, 0, 0, 0.3);
|
|
256
267
|
}
|
|
257
268
|
</style>
|
|
258
269
|
`}
|
|
@@ -452,7 +463,9 @@ const typeWriter = async function ({ id, html, seconds, endHideBlink, container
|
|
|
452
463
|
overflow: hidden;
|
|
453
464
|
border-right: 0.15em solid orange;
|
|
454
465
|
white-space: nowrap;
|
|
455
|
-
animation:
|
|
466
|
+
animation:
|
|
467
|
+
typing-${id} ${typingAnimationTransitionStyle[1]},
|
|
468
|
+
blink-caret-${id} 0.5s step-end infinite;
|
|
456
469
|
animation-fill-mode: forwards;
|
|
457
470
|
width: 0;
|
|
458
471
|
}
|
|
@@ -517,12 +530,20 @@ const dashRange = ({ selector, color }) => {
|
|
|
517
530
|
return html`
|
|
518
531
|
<style>
|
|
519
532
|
.${selector} {
|
|
520
|
-
background:
|
|
521
|
-
linear-gradient(90deg, ${color} 50%, transparent 50%), linear-gradient(
|
|
522
|
-
linear-gradient(0deg, ${color} 50%, transparent 50%);
|
|
533
|
+
background:
|
|
534
|
+
linear-gradient(90deg, ${color} 50%, transparent 50%), linear-gradient(90deg, ${color} 50%, transparent 50%),
|
|
535
|
+
linear-gradient(0deg, ${color} 50%, transparent 50%), linear-gradient(0deg, ${color} 50%, transparent 50%);
|
|
523
536
|
background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
|
|
524
|
-
background-size:
|
|
525
|
-
|
|
537
|
+
background-size:
|
|
538
|
+
16px 4px,
|
|
539
|
+
16px 4px,
|
|
540
|
+
4px 16px,
|
|
541
|
+
4px 16px;
|
|
542
|
+
background-position:
|
|
543
|
+
0% 0%,
|
|
544
|
+
100% 100%,
|
|
545
|
+
0% 100%,
|
|
546
|
+
100% 0px;
|
|
526
547
|
border-radius: 5px;
|
|
527
548
|
padding: 10px;
|
|
528
549
|
animation: ${selector}_dash_range 5s linear infinite;
|
|
@@ -530,7 +551,11 @@ const dashRange = ({ selector, color }) => {
|
|
|
530
551
|
|
|
531
552
|
@keyframes ${selector}_dash_range {
|
|
532
553
|
to {
|
|
533
|
-
background-position:
|
|
554
|
+
background-position:
|
|
555
|
+
100% 0%,
|
|
556
|
+
0% 100%,
|
|
557
|
+
0% 0%,
|
|
558
|
+
100% 100%;
|
|
534
559
|
}
|
|
535
560
|
}
|
|
536
561
|
</style>
|
|
@@ -660,8 +685,8 @@ const scrollBarLightRender = () => {
|
|
|
660
685
|
::-` +
|
|
661
686
|
b +
|
|
662
687
|
`-scrollbar {
|
|
663
|
-
width: 5px;
|
|
664
|
-
height: 5px;
|
|
688
|
+
width: 5px;
|
|
689
|
+
height: 5px;
|
|
665
690
|
}
|
|
666
691
|
|
|
667
692
|
/* Track */
|
|
@@ -690,6 +715,10 @@ const scrollBarLightRender = () => {
|
|
|
690
715
|
.join('');
|
|
691
716
|
};
|
|
692
717
|
|
|
718
|
+
// adjustHex: supports #RGB #RGBA #RRGGBB #RRGGBBAA
|
|
719
|
+
// preserves alpha channel if present (does not modify it)
|
|
720
|
+
// usage: adjustHex('#24FBFFFF', 0.1)
|
|
721
|
+
|
|
693
722
|
function adjustHex(hex, factor = 0.1, options = {}) {
|
|
694
723
|
if (typeof hex !== 'string') throw new TypeError('hex must be a string');
|
|
695
724
|
if (typeof factor !== 'number') throw new TypeError('factor must be a number');
|
|
@@ -701,27 +730,34 @@ function adjustHex(hex, factor = 0.1, options = {}) {
|
|
|
701
730
|
|
|
702
731
|
const mode = options.mode === 'hsl' ? 'hsl' : 'mix';
|
|
703
732
|
|
|
704
|
-
// normalize hex
|
|
733
|
+
// normalize hex: accept 3,4,6,8 (with or without #)
|
|
705
734
|
let h = hex.replace(/^#/, '').trim();
|
|
706
|
-
if (!
|
|
707
|
-
|
|
735
|
+
if (![3, 4, 6, 8].includes(h.length)) {
|
|
736
|
+
throw new Error('Invalid hex format — expected 3, 4, 6 or 8 hex digits');
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// expand shorthand (#RGB or #RGBA -> #RRGGBB or #RRGGBBAA)
|
|
740
|
+
if (h.length === 3 || h.length === 4) {
|
|
708
741
|
h = h
|
|
709
742
|
.split('')
|
|
710
743
|
.map((c) => c + c)
|
|
711
744
|
.join('');
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
const hasAlpha = h.length === 8;
|
|
712
748
|
|
|
713
749
|
const r = parseInt(h.slice(0, 2), 16);
|
|
714
750
|
const g = parseInt(h.slice(2, 4), 16);
|
|
715
751
|
const b = parseInt(h.slice(4, 6), 16);
|
|
752
|
+
const a = hasAlpha ? parseInt(h.slice(6, 8), 16) : null; // keep alpha as-is if present
|
|
716
753
|
|
|
717
|
-
const clamp = (v,
|
|
754
|
+
const clamp = (v, a0 = 0, z = 255) => Math.max(a0, Math.min(z, v));
|
|
718
755
|
|
|
719
|
-
const rgbToHex = (rr, gg, bb) =>
|
|
720
|
-
'
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
.toLowerCase();
|
|
756
|
+
const rgbToHex = (rr, gg, bb, aa = null) => {
|
|
757
|
+
const parts = [rr, gg, bb].map((v) => Math.round(v).toString(16).padStart(2, '0'));
|
|
758
|
+
if (aa !== null) parts.push(Math.round(aa).toString(16).padStart(2, '0'));
|
|
759
|
+
return '#' + parts.join('').toLowerCase();
|
|
760
|
+
};
|
|
725
761
|
|
|
726
762
|
if (mode === 'mix') {
|
|
727
763
|
// positive: mix toward white (255); negative: mix toward black (0)
|
|
@@ -729,11 +765,15 @@ function adjustHex(hex, factor = 0.1, options = {}) {
|
|
|
729
765
|
if (factor >= 0) {
|
|
730
766
|
return clamp(Math.round(c + (255 - c) * factor));
|
|
731
767
|
} else {
|
|
732
|
-
const
|
|
733
|
-
return clamp(Math.round(c * (1 -
|
|
768
|
+
const aFactor = Math.abs(factor);
|
|
769
|
+
return clamp(Math.round(c * (1 - aFactor)));
|
|
734
770
|
}
|
|
735
771
|
};
|
|
736
|
-
|
|
772
|
+
|
|
773
|
+
const rr = mixChannel(r);
|
|
774
|
+
const gg = mixChannel(g);
|
|
775
|
+
const bb = mixChannel(b);
|
|
776
|
+
return rgbToHex(rr, gg, bb, a);
|
|
737
777
|
} else {
|
|
738
778
|
// HSL mode: convert rgb to hsl, adjust L by factor, convert back
|
|
739
779
|
const rgbToHsl = (r, g, b) => {
|
|
@@ -791,10 +831,16 @@ function adjustHex(hex, factor = 0.1, options = {}) {
|
|
|
791
831
|
let newL = ll + factor;
|
|
792
832
|
newL = Math.max(0, Math.min(1, newL));
|
|
793
833
|
const { r: r2, g: g2, b: b2 } = hslToRgb(hh, ss, newL);
|
|
794
|
-
return rgbToHex(r2, g2, b2);
|
|
834
|
+
return rgbToHex(r2, g2, b2, a);
|
|
795
835
|
}
|
|
796
836
|
}
|
|
797
837
|
|
|
838
|
+
// Examples (uncomment to test):
|
|
839
|
+
// console.log(adjustHex('#24FBFFFF', 0.1)); // accepts 8-digit input
|
|
840
|
+
// console.log(adjustHex('#24FBFF', 0.1)); // 6-digit
|
|
841
|
+
// console.log(adjustHex('#4bf', -0.2)); // 3-digit
|
|
842
|
+
// console.log(adjustHex('#4bf8', -0.2)); // 4-digit (with alpha)
|
|
843
|
+
|
|
798
844
|
// Convenience helpers:
|
|
799
845
|
function lightenHex(hex, percentOr01 = 0.1, options = {}) {
|
|
800
846
|
return adjustHex(hex, Math.abs(percentOr01), options);
|
|
@@ -867,7 +913,7 @@ const scrollBarDarkRender = () => {
|
|
|
867
913
|
b +
|
|
868
914
|
`-scrollbar {
|
|
869
915
|
width: 8px;
|
|
870
|
-
height: 8px;
|
|
916
|
+
height: 8px;
|
|
871
917
|
/* line-height: 1em; */
|
|
872
918
|
}
|
|
873
919
|
|
|
@@ -1011,29 +1057,30 @@ const cssEffect = async (containerSelector, event) => {
|
|
|
1011
1057
|
}, 600);
|
|
1012
1058
|
};
|
|
1013
1059
|
|
|
1014
|
-
const imageShimmer = () =>
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
style: {
|
|
1018
|
-
width: '95%',
|
|
1019
|
-
height: '95%',
|
|
1020
|
-
'border-radius': '10px',
|
|
1021
|
-
overflow: 'hidden',
|
|
1022
|
-
},
|
|
1023
|
-
})}"
|
|
1024
|
-
>
|
|
1025
|
-
<div
|
|
1026
|
-
class="abs center"
|
|
1060
|
+
const imageShimmer = () =>
|
|
1061
|
+
html`<div
|
|
1062
|
+
class="abs center ssr-shimmer-search-box"
|
|
1027
1063
|
style="${renderCssAttr({
|
|
1028
1064
|
style: {
|
|
1029
|
-
|
|
1030
|
-
|
|
1065
|
+
width: '95%',
|
|
1066
|
+
height: '95%',
|
|
1067
|
+
'border-radius': '10px',
|
|
1068
|
+
overflow: 'hidden',
|
|
1031
1069
|
},
|
|
1032
1070
|
})}"
|
|
1033
1071
|
>
|
|
1034
|
-
<
|
|
1035
|
-
|
|
1036
|
-
|
|
1072
|
+
<div
|
|
1073
|
+
class="abs center"
|
|
1074
|
+
style="${renderCssAttr({
|
|
1075
|
+
style: {
|
|
1076
|
+
'font-size': '70px',
|
|
1077
|
+
color: `#bababa`,
|
|
1078
|
+
},
|
|
1079
|
+
})}"
|
|
1080
|
+
>
|
|
1081
|
+
<i class="fa-solid fa-photo-film"></i>
|
|
1082
|
+
</div>
|
|
1083
|
+
</div>`;
|
|
1037
1084
|
|
|
1038
1085
|
const renderChessPattern = (patternSize = 20) =>
|
|
1039
1086
|
`background: repeating-conic-gradient(#808080 0 25%, #0000 0 50%) 50% / ${patternSize}px ${patternSize}px`;
|
|
@@ -57,7 +57,7 @@ const LoadingAnimation = {
|
|
|
57
57
|
},
|
|
58
58
|
spinner: {
|
|
59
59
|
getId: (id) => `spinner-progress-${id.slice(1)}`,
|
|
60
|
-
play: async function (container, spinner) {
|
|
60
|
+
play: async function (container, spinner, options = { append: '', prepend: '' }) {
|
|
61
61
|
if (!s(container)) return;
|
|
62
62
|
const id = this.getId(container);
|
|
63
63
|
|
|
@@ -85,7 +85,7 @@ const LoadingAnimation = {
|
|
|
85
85
|
style,
|
|
86
86
|
})}"
|
|
87
87
|
>
|
|
88
|
-
${render}
|
|
88
|
+
${options.prepend ? options.prepend : ''} ${render} ${options.append ? options.append : ''}
|
|
89
89
|
</div>
|
|
90
90
|
`,
|
|
91
91
|
);
|
|
@@ -5,16 +5,9 @@ const loggerFactory = (meta, options = { trace: false }) => {
|
|
|
5
5
|
const types = ['error', 'warn', 'info', 'debug'];
|
|
6
6
|
const logger = {
|
|
7
7
|
log: function (type, args) {
|
|
8
|
-
if (
|
|
9
|
-
console.log = () => null;
|
|
10
|
-
console.error = () => null;
|
|
11
|
-
console.info = () => null;
|
|
12
|
-
console.warn = () => null;
|
|
13
|
-
}
|
|
8
|
+
if (!window.renderPayload.dev) return;
|
|
14
9
|
if (options.trace === true) args.push(getCurrentTrace().split('Logger.js:23')[1]);
|
|
15
|
-
return
|
|
16
|
-
? console[type](`[${meta}] ${new Date().toISOString()} ${type}:`, ...args)
|
|
17
|
-
: null;
|
|
10
|
+
return console[type](`[${meta}] ${new Date().toISOString()} ${type}:`, ...args);
|
|
18
11
|
},
|
|
19
12
|
};
|
|
20
13
|
types.map(
|