mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-07-30 13:11:39 +00:00
Compare commits
23 commits
a2307b5b07
...
e0d100732a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0d100732a | ||
|
|
b60887c71d | ||
|
|
9f686c88fe | ||
|
|
36244ec63f | ||
|
|
f45e3a9ef8 | ||
|
|
a46f1713fe | ||
|
|
22f23d9c82 | ||
|
|
b4cf5b57fa | ||
|
|
3491559e9f | ||
|
|
b83fc73e18 | ||
|
|
8c88df4ecf | ||
|
|
176d5ad2b6 | ||
|
|
99e56c4b1d | ||
|
|
a489380f49 | ||
|
|
9127bcf25e | ||
|
|
c3af73daae | ||
|
|
7e90f6d707 | ||
|
|
a793bc32c7 | ||
|
|
e642dbe060 | ||
|
|
8ba3139617 | ||
|
|
b62f47ba05 | ||
|
|
0cd83f0322 | ||
|
|
02726fdf69 |
55 changed files with 1459 additions and 2320 deletions
|
|
@ -51,6 +51,15 @@
|
|||
# Disable Topics tracking if not enabled explicitly: https://github.com/jkarlin/topics
|
||||
header ?Permissions-Policy "browsing-topics=()"
|
||||
|
||||
# Set a strict CSP and nosniff for all static assets not handled by PHP.
|
||||
# ? means "set only if not already present", so PHP responses carrying a Nelmio CSP are left untouched.
|
||||
header ?Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; sandbox;"
|
||||
header ?X-Content-Type-Options "nosniff"
|
||||
|
||||
# SVG files get a slightly different CSP because they can embed resources and must not be framed.
|
||||
@svg path *.svg *.svg.gz *.svg.br
|
||||
header @svg Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'; sandbox;"
|
||||
|
||||
# Prevent PHP execution in the media upload directory
|
||||
@php_in_media path_regexp (?i)^/media/.*\.(php[3-8]?|phar|phtml|pht|phps)$
|
||||
respond @php_in_media 403
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ RUN a2dissite 000-default.conf && \
|
|||
a2enmod proxy_fcgi setenvif && \
|
||||
a2enconf php${PHP_VERSION}-fpm && \
|
||||
a2enconf docker-php && \
|
||||
a2enmod rewrite
|
||||
a2enmod rewrite headers
|
||||
|
||||
# Install composer and yarn dependencies for Part-DB
|
||||
USER www-data
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
2.12.2
|
||||
2.12.3
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
import {Controller} from "@hotwired/stimulus";
|
||||
import {visit} from "@hotwired/turbo";
|
||||
import * as bootbox from "bootbox";
|
||||
import "../../css/components/bootbox_extensions.css";
|
||||
import {ConfirmSwal} from "../../helpers/swal";
|
||||
import "../../css/components/dirty_form.css";
|
||||
|
||||
/**
|
||||
|
|
@ -207,11 +206,10 @@ export default class extends Controller {
|
|||
}
|
||||
|
||||
_confirmNavigation(onConfirm) {
|
||||
bootbox.confirm({
|
||||
title: this.confirmTitleValue,
|
||||
message: this.confirmMessageValue,
|
||||
callback: (result) => { if (result) onConfirm(); }
|
||||
});
|
||||
ConfirmSwal.fire({
|
||||
titleText: this.confirmTitleValue,
|
||||
text: this.confirmMessageValue,
|
||||
}).then(({isConfirmed}) => { if (isConfirmed) onConfirm(); });
|
||||
}
|
||||
|
||||
_handleLinkClick(event) {
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
import {Controller} from "@hotwired/stimulus";
|
||||
|
||||
import * as bootbox from "bootbox";
|
||||
import "../../css/components/bootbox_extensions.css";
|
||||
import {AlertSwal, ConfirmSwal} from "../../helpers/swal";
|
||||
import accept from "attr-accept";
|
||||
|
||||
export default class extends Controller {
|
||||
|
|
@ -62,7 +61,7 @@ export default class extends Controller {
|
|||
|
||||
if(!prototype) {
|
||||
console.warn("Prototype is not set, we cannot create a new element. This is most likely due to missing permissions.");
|
||||
bootbox.alert("You do not have the permissions to create a new element. (No protoype element is set)");
|
||||
AlertSwal.fire({"text": "You do not have the permissions to create a new element. (No protoype element is set)"});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -226,8 +225,10 @@ export default class extends Controller {
|
|||
}
|
||||
|
||||
if(this.deleteMessageValue) {
|
||||
bootbox.confirm(this.deleteMessageValue, (result) => {
|
||||
if (result) {
|
||||
ConfirmSwal.fire({
|
||||
text: this.deleteMessageValue,
|
||||
}).then(({isConfirmed}) => {
|
||||
if (isConfirmed) {
|
||||
del();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -38,9 +38,7 @@ import 'datatables.net-colreorder-bs5';
|
|||
import 'datatables.net-responsive-bs5';
|
||||
import '../../../js/lib/datatables';
|
||||
|
||||
//import 'datatables.net-select-bs5';
|
||||
//Use the local version containing the fix for the select extension
|
||||
import '../../../js/lib/dataTables.select.mjs';
|
||||
import 'datatables.net-select-bs5';
|
||||
|
||||
|
||||
const EVENT_DT_LOADED = 'dt:loaded';
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
import DatatablesController from "./datatables_controller.js";
|
||||
import TomSelect from "tom-select";
|
||||
|
||||
import * as bootbox from "bootbox";
|
||||
import {ConfirmSwal} from "../../../helpers/swal";
|
||||
|
||||
/**
|
||||
* This is the datatables controller for parts lists
|
||||
|
|
@ -146,15 +146,17 @@ export default class extends DatatablesController {
|
|||
bubbles: true, //This line is important, otherwise Turbo will not receive the event
|
||||
});
|
||||
|
||||
const confirm = bootbox.confirm({
|
||||
message: message, title: title, callback: function (result) {
|
||||
//If the dialog was confirmed, then submit the form.
|
||||
if (result) {
|
||||
that._confirmed = true;
|
||||
form.dispatchEvent(that._our_event);
|
||||
} else {
|
||||
that._confirmed = false;
|
||||
}
|
||||
ConfirmSwal.fire({
|
||||
titleText: title,
|
||||
text: message,
|
||||
icon: "warning"
|
||||
}).then(({isConfirmed}) => {
|
||||
//If the dialog was confirmed, then submit the form.
|
||||
if (isConfirmed) {
|
||||
that._confirmed = true;
|
||||
form.dispatchEvent(that._our_event);
|
||||
} else {
|
||||
that._confirmed = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
import {Controller} from "@hotwired/stimulus";
|
||||
|
||||
import * as bootbox from "bootbox";
|
||||
import "../../css/components/bootbox_extensions.css";
|
||||
import {ConfirmSwal} from "../../helpers/swal";
|
||||
|
||||
export default class extends Controller
|
||||
{
|
||||
|
|
@ -48,32 +47,33 @@ export default class extends Controller
|
|||
const submitter = event.submitter;
|
||||
const that = this;
|
||||
|
||||
const confirm = bootbox.confirm({
|
||||
message: message, title: title, callback: function (result) {
|
||||
//If the dialog was confirmed, then submit the form.
|
||||
if (result) {
|
||||
//Set a flag to prevent the dialog from popping up again and allowing turbo to submit the form
|
||||
that._confirmed = true;
|
||||
ConfirmSwal.fire({
|
||||
titleText: title,
|
||||
html: message, //Message contains a <br> tag and no user injectable HTML
|
||||
}).then(({isConfirmed}) => {
|
||||
//If the dialog was confirmed, then submit the form.
|
||||
if (isConfirmed) {
|
||||
//Set a flag to prevent the dialog from popping up again and allowing turbo to submit the form
|
||||
that._confirmed = true;
|
||||
|
||||
//Create a submit button in the form and click it to submit the form
|
||||
//Before a submit event was dispatched, but this caused weird issues on Firefox causing the delete request being posted twice (and the second time was returning 404). See https://github.com/Part-DB/Part-DB-server/issues/273
|
||||
const submit_btn = document.createElement('button');
|
||||
submit_btn.type = 'submit';
|
||||
submit_btn.style.display = 'none';
|
||||
//Create a submit button in the form and click it to submit the form
|
||||
//Before a submit event was dispatched, but this caused weird issues on Firefox causing the delete request being posted twice (and the second time was returning 404). See https://github.com/Part-DB/Part-DB-server/issues/273
|
||||
const submit_btn = document.createElement('button');
|
||||
submit_btn.type = 'submit';
|
||||
submit_btn.style.display = 'none';
|
||||
|
||||
//If the clicked button has a value, set it on the submit button
|
||||
if (submitter.value) {
|
||||
submit_btn.value = submitter.value;
|
||||
}
|
||||
if (submitter.name) {
|
||||
submit_btn.name = submitter.name;
|
||||
}
|
||||
form.appendChild(submit_btn);
|
||||
submit_btn.click();
|
||||
} else {
|
||||
that._confirmed = false;
|
||||
//If the clicked button has a value, set it on the submit button
|
||||
if (submitter.value) {
|
||||
submit_btn.value = submitter.value;
|
||||
}
|
||||
if (submitter.name) {
|
||||
submit_btn.name = submitter.name;
|
||||
}
|
||||
form.appendChild(submit_btn);
|
||||
submit_btn.click();
|
||||
} else {
|
||||
that._confirmed = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
import {Controller} from "@hotwired/stimulus";
|
||||
|
||||
import * as bootbox from "bootbox";
|
||||
import "../../css/components/bootbox_extensions.css";
|
||||
import {ConfirmSwal} from "../../helpers/swal";
|
||||
|
||||
export default class extends Controller
|
||||
{
|
||||
|
|
@ -53,20 +52,19 @@ export default class extends Controller
|
|||
|
||||
const that = this;
|
||||
|
||||
bootbox.confirm({
|
||||
title: this.titleValue,
|
||||
message: this.messageValue,
|
||||
callback: (result) => {
|
||||
if (result) {
|
||||
//Set a flag to prevent the dialog from popping up again and allowing turbo to submit the form
|
||||
that._confirmed = true;
|
||||
ConfirmSwal.fire({
|
||||
titleText: this.titleValue,
|
||||
text: this.messageValue,
|
||||
}).then(({isConfirmed}) => {
|
||||
if (isConfirmed) {
|
||||
//Set a flag to prevent the dialog from popping up again and allowing turbo to submit the form
|
||||
that._confirmed = true;
|
||||
|
||||
//Click the link
|
||||
that.element.click();
|
||||
} else {
|
||||
that._confirmed = false;
|
||||
}
|
||||
//Click the link
|
||||
that.element.click();
|
||||
} else {
|
||||
that._confirmed = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@
|
|||
|
||||
|
||||
import {Controller} from "@hotwired/stimulus";
|
||||
import { zxcvbn, zxcvbnOptions } from '@zxcvbn-ts/core';
|
||||
import { ZxcvbnFactory } from '@zxcvbn-ts/core';
|
||||
import * as zxcvbnCommonPackage from '@zxcvbn-ts/language-common';
|
||||
import * as zxcvbnEnPackage from '@zxcvbn-ts/language-en';
|
||||
import * as zxcvbnDePackage from '@zxcvbn-ts/language-de';
|
||||
import * as zxcvbnFrPackage from '@zxcvbn-ts/language-fr';
|
||||
import * as zxcvbnJaPackage from '@zxcvbn-ts/language-ja';
|
||||
import * as zxcvbnItPackage from '@zxcvbn-ts/language-it';
|
||||
import * as zxcvbnPlPackage from '@zxcvbn-ts/language-pl';
|
||||
import {trans} from '../../translator.js';
|
||||
|
||||
/* stimulusFetch: 'lazy' */
|
||||
|
|
@ -34,6 +36,8 @@ export default class extends Controller {
|
|||
|
||||
static targets = ["badge", "warning"]
|
||||
|
||||
_zxcvbnFactory;
|
||||
|
||||
_getTranslations() {
|
||||
//Get the current locale
|
||||
const locale = document.documentElement.lang;
|
||||
|
|
@ -43,6 +47,10 @@ export default class extends Controller {
|
|||
return zxcvbnFrPackage.translations;
|
||||
} else if (locale.includes('ja')) {
|
||||
return zxcvbnJaPackage.translations;
|
||||
} else if (locale.includes('it')) {
|
||||
return zxcvbnItPackage.translations;
|
||||
} else if (locale.includes('pl')) {
|
||||
return zxcvbnPlPackage.translations;
|
||||
}
|
||||
|
||||
//Fallback to english
|
||||
|
|
@ -56,34 +64,39 @@ export default class extends Controller {
|
|||
//Configure zxcvbn
|
||||
const options = {
|
||||
graphs: zxcvbnCommonPackage.adjacencyGraphs,
|
||||
useLevenshtein: true,
|
||||
dictionary: {
|
||||
...zxcvbnCommonPackage.dictionary,
|
||||
// We could use the english dictionary here too, but it is very big. So we just use the common words
|
||||
//...zxcvbnEnPackage.dictionary,
|
||||
...zxcvbnEnPackage.dictionary,
|
||||
...zxcvbnDePackage.dictionary,
|
||||
|
||||
"partdb": ['part-db', 'partdb', 'part_db', 'part-db-symfony', 'partdb-symfony', 'part_db_symfony'],
|
||||
},
|
||||
translations: this._getTranslations(),
|
||||
};
|
||||
zxcvbnOptions.setOptions(options);
|
||||
|
||||
this._zxcvbnFactory = new ZxcvbnFactory(options);
|
||||
|
||||
//Add event listener to the password input field
|
||||
this._passwordInput.addEventListener('input', this._onPasswordInput.bind(this));
|
||||
}
|
||||
|
||||
_onPasswordInput() {
|
||||
async _onPasswordInput() {
|
||||
//Retrieve the password
|
||||
const password = this._passwordInput.value;
|
||||
|
||||
//Estimate the password strength
|
||||
const result = zxcvbn(password);
|
||||
const result = await this._zxcvbnFactory.checkAsync(password);
|
||||
|
||||
//Update the badge
|
||||
this.badgeTarget.parentElement.classList.remove("d-none");
|
||||
this._setBadgeToLevel(result.score);
|
||||
this._setBadgeToLevel(result.score, result.crackTimes.onlineNoThrottlingXPerSecond.display);
|
||||
|
||||
this.warningTarget.innerHTML = result.feedback.warning;
|
||||
}
|
||||
|
||||
_setBadgeToLevel(level) {
|
||||
_setBadgeToLevel(level, time = null) {
|
||||
let text, classes;
|
||||
|
||||
switch (level) {
|
||||
|
|
@ -118,5 +131,11 @@ export default class extends Controller {
|
|||
//Re-add the classes
|
||||
this.badgeTarget.classList.add("badge");
|
||||
this.badgeTarget.classList.add(...classes.split(" "));
|
||||
|
||||
if (time) {
|
||||
this.badgeTarget.setAttribute("title", trans("user.password_strength.crack_time", {"%time%": time}));
|
||||
} else {
|
||||
this.badgeTarget.removeAttribute("title");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import {Controller} from "@hotwired/stimulus";
|
||||
import * as bootbox from "bootbox";
|
||||
import {AlertSwal} from "../../helpers/swal";
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
|
|
@ -35,12 +35,12 @@ export default class extends Controller {
|
|||
const part_distance = document.getElementById('reel_part_distance').value;
|
||||
|
||||
if (dia_inner == "" || dia_outer == "" || tape_thickness == "") {
|
||||
bootbox.alert(this.errorMissingValuesValue);
|
||||
AlertSwal.fire({title: this.errorMissingValuesValue});
|
||||
return;
|
||||
}
|
||||
|
||||
if (dia_outer**dia_outer < dia_inner**dia_inner) {
|
||||
bootbox.alert(this.errorOuterGreaterInnerValue);
|
||||
AlertSwal.fire({title: this.errorOuterGreaterInnerValue});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -61,12 +61,12 @@ export default class extends Controller {
|
|||
return;
|
||||
}
|
||||
|
||||
var parts_per_meter = 1 / (part_distance / 1000);
|
||||
const parts_per_meter = 1 / (part_distance / 1000);
|
||||
|
||||
document.getElementById('result_parts_per_meter').textContent = parts_per_meter.toFixed(2) + ' 1/m';
|
||||
|
||||
var parts_amount = (length/1000) * parts_per_meter;
|
||||
const parts_amount = (length / 1000) * parts_per_meter;
|
||||
|
||||
document.getElementById('result_amount').textContent = Math.floor(parts_amount);
|
||||
document.getElementById('result_amount').textContent = Math.floor(parts_amount).toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
50
assets/css/components/swal.css
Normal file
50
assets/css/components/swal.css
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Respect the dark mode of Bootstrap 5 set via data-bs-theme="dark" on the <html> element. This is done by overriding the CSS variables of the bootstrap-5 theme of SweetAlert2.
|
||||
*/
|
||||
|
||||
html[data-bs-theme="dark"] [data-swal2-theme='bootstrap-5'] {
|
||||
/* POPUP */
|
||||
--swal2-background: #212529;
|
||||
--swal2-color: #fff;
|
||||
--swal2-border: 1px solid #495057;
|
||||
|
||||
/* INPUT */
|
||||
--swal2-input-background: #2b3035;
|
||||
--swal2-input-border: 1px solid #495057;
|
||||
--swal2-input-focus-border: 1px solid #86b7fe;
|
||||
--swal2-input-focus-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
||||
|
||||
/* VALIDATION MESSAGE */
|
||||
--swal2-validation-message-background: #2c0b0e;
|
||||
--swal2-validation-message-color: #ea868f;
|
||||
|
||||
/* FOOTER */
|
||||
--swal2-footer-border-color: #495057;
|
||||
--swal2-footer-background: #343a40;
|
||||
--swal2-footer-color: #adb5bd;
|
||||
|
||||
/* CLOSE BUTTON */
|
||||
--swal2-close-button-color: #fff;
|
||||
|
||||
/* TOASTS */
|
||||
--swal2-toast-border: 1px solid #495057;
|
||||
}
|
||||
44
assets/helpers/swal.js
Normal file
44
assets/helpers/swal.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program 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/>.
|
||||
*/
|
||||
|
||||
import Swal from 'sweetalert2';
|
||||
import 'sweetalert2/themes/bootstrap-5.css';
|
||||
import '../css/components/swal.css'
|
||||
import { trans } from '../translator';
|
||||
|
||||
const BaseSwal = Swal.mixin({
|
||||
position: "top",
|
||||
theme: "bootstrap-5",
|
||||
confirmButtonText: trans('dialog.btn.ok'),
|
||||
cancelButtonText: trans('dialog.btn.cancel'),
|
||||
denyButtonText: trans('dialog.btn.deny'),
|
||||
});
|
||||
|
||||
const ConfirmSwal = BaseSwal.mixin({
|
||||
showCancelButton: true,
|
||||
showCloseButton: true,
|
||||
icon: "warning",
|
||||
});
|
||||
|
||||
const AlertSwal = BaseSwal.mixin({
|
||||
showCloseButton: true,
|
||||
icon: "info",
|
||||
});
|
||||
|
||||
export { ConfirmSwal, AlertSwal, BaseSwal, BaseSwal as default,};
|
||||
|
|
@ -30,21 +30,21 @@ import '../css/app/images.css';
|
|||
// start the Stimulus application
|
||||
import '../stimulus_bootstrap';
|
||||
|
||||
// Need jQuery? Install it with "yarn add jquery", then uncomment to require it.
|
||||
const $ = require('jquery');
|
||||
import $ from 'jquery';
|
||||
|
||||
//Only include javascript
|
||||
import '@fortawesome/fontawesome-free/css/all.css'
|
||||
|
||||
require('bootstrap');
|
||||
import 'bootstrap';
|
||||
|
||||
import "./error_handler";
|
||||
import "./tab_remember";
|
||||
import "./register_events";
|
||||
import "./tristate_checkboxes";
|
||||
|
||||
//Define jquery globally
|
||||
global.$ = global.jQuery = require("jquery");
|
||||
// Expose jQuery globally so legacy plugins and Bootstrap's jQuery integration
|
||||
// can find it on window at runtime.
|
||||
global.$ = global.jQuery = $;
|
||||
|
||||
//Use the local WASM file for the ZXing library
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import * as bootbox from "bootbox";
|
||||
import Swal from "../helpers/swal";
|
||||
|
||||
/**
|
||||
* If this class is imported the user is shown an error dialog if he calls an page via Turbo and an error is responded.
|
||||
|
|
@ -40,21 +40,6 @@ class ErrorHandlerHelper {
|
|||
_showAlert(statusText, statusCode, location, responseHTML)
|
||||
{
|
||||
const httpStatusToText = {
|
||||
'200': 'OK',
|
||||
'201': 'Created',
|
||||
'202': 'Accepted',
|
||||
'203': 'Non-Authoritative Information',
|
||||
'204': 'No Content',
|
||||
'205': 'Reset Content',
|
||||
'206': 'Partial Content',
|
||||
'300': 'Multiple Choices',
|
||||
'301': 'Moved Permanently',
|
||||
'302': 'Found',
|
||||
'303': 'See Other',
|
||||
'304': 'Not Modified',
|
||||
'305': 'Use Proxy',
|
||||
'306': 'Unused',
|
||||
'307': 'Temporary Redirect',
|
||||
'400': 'Bad Request',
|
||||
'401': 'Unauthorized',
|
||||
'402': 'Payment Required',
|
||||
|
|
@ -83,49 +68,67 @@ class ErrorHandlerHelper {
|
|||
'505': 'HTTP Version Not Supported',
|
||||
};
|
||||
|
||||
//If the statusText is empty, we use the status code as text
|
||||
if (!statusText) {
|
||||
statusText = httpStatusToText[statusCode];
|
||||
}
|
||||
|
||||
//Create error text
|
||||
const title = statusText + ' (Status ' + statusCode + ')';
|
||||
|
||||
let trimString = function (string, length) {
|
||||
return string.length > length ?
|
||||
string.substring(0, length) + '...' :
|
||||
string;
|
||||
const userFriendlyMessages = {
|
||||
'400': 'The request was invalid or malformed.',
|
||||
'401': 'You need to log in to access this resource.',
|
||||
'403': 'You don\'t have permission to access this resource.',
|
||||
'404': 'The requested page or resource could not be found.',
|
||||
'408': 'The request timed out. Please check your connection and try again.',
|
||||
'409': 'There was a conflict with the current state of the resource.',
|
||||
'429': 'Too many requests sent. Please wait a moment and try again.',
|
||||
'500': 'An internal server error occurred. This is not your fault.',
|
||||
'502': 'The server received an invalid response from an upstream service.',
|
||||
'503': 'The service is temporarily unavailable. Please try again later.',
|
||||
'504': 'The server did not respond in time. Please try again later.',
|
||||
};
|
||||
|
||||
const short_location = trimString(location, 50);
|
||||
if (!statusText) {
|
||||
statusText = httpStatusToText[String(statusCode)] ?? 'Unknown Error';
|
||||
}
|
||||
|
||||
const alert = bootbox.alert(
|
||||
{
|
||||
size: 'large',
|
||||
message: function() {
|
||||
let url = location;
|
||||
let msg = `Error calling <a href="${url}">${short_location}</a>.<br>`;
|
||||
msg += '<b>Try to reload the page or contact the administrator if this error persists.</b>';
|
||||
const title = `${statusText} <small class="text-muted fs-6">(HTTP ${statusCode})</small>`;
|
||||
const friendlyMsg = userFriendlyMessages[String(statusCode)]
|
||||
?? 'An unexpected error occurred. Please try again or contact the administrator.';
|
||||
|
||||
msg += '<br><br><a class=\"btn btn-outline-secondary mb-2\" data-bs-toggle=\"collapse\" href=\"#iframe_div\" >' + 'View details' + "</a>";
|
||||
msg += "<div class=\" collapse\" id='iframe_div'><iframe height='512' width='100%' id='error-iframe'></iframe></div>";
|
||||
const short_location = location.length > 80
|
||||
? location.substring(0, 80) + '…'
|
||||
: location;
|
||||
|
||||
return msg;
|
||||
},
|
||||
title: title,
|
||||
callback: function () {
|
||||
//Remove blur
|
||||
$('#content').removeClass('loading-content');
|
||||
}
|
||||
const msg = `
|
||||
<p class="mb-3">${friendlyMsg}</p>
|
||||
<p class="text-muted small mb-3">If this error keeps happening, please contact your administrator.</p>
|
||||
<button class="btn btn-sm btn-outline-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#swal-error-details" aria-expanded="false">
|
||||
<i class="fas fa-code me-1"></i>Technical details
|
||||
</button>
|
||||
<div class="collapse mt-2" id="swal-error-details">
|
||||
<iframe height="400" width="100%" id="error-iframe" style="border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);"></iframe>
|
||||
</div>`;
|
||||
|
||||
});
|
||||
const footer = `<span class="text-muted small">Error while loading: <a href="${location}" class="text-muted text-decoration-none" style="opacity:0.7;">${short_location}</a></span>`;
|
||||
|
||||
alert.init(function (){
|
||||
var dstFrame = document.getElementById('error-iframe');
|
||||
//@ts-ignore
|
||||
var dstDoc = dstFrame.contentDocument || dstFrame.contentWindow.document;
|
||||
dstDoc.write(responseHTML)
|
||||
dstDoc.close();
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: title,
|
||||
html: msg,
|
||||
footer: footer,
|
||||
width: '90%',
|
||||
confirmButtonText: '<i class="fas fa-rotate-right me-1"></i>Reload page',
|
||||
showCancelButton: true,
|
||||
cancelButtonText: 'Close',
|
||||
showCloseButton: true,
|
||||
reverseButtons: true,
|
||||
didOpen: () => {
|
||||
const dstFrame = document.getElementById('error-iframe');
|
||||
//@ts-ignore
|
||||
const dstDoc = dstFrame.contentDocument || dstFrame.contentWindow.document;
|
||||
dstDoc.write(responseHTML);
|
||||
dstDoc.close();
|
||||
},
|
||||
}).then((result) => {
|
||||
document.getElementById('content').classList.remove('loading-content');
|
||||
if (result.isConfirmed) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -171,4 +174,4 @@ class ErrorHandlerHelper {
|
|||
}
|
||||
}
|
||||
|
||||
export default new ErrorHandlerHelper();
|
||||
export default new ErrorHandlerHelper();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -19,15 +19,14 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
import {Dropdown} from "bootstrap";
|
||||
import {Dropdown, Modal, Tooltip} from "bootstrap";
|
||||
import ClipboardJS from "clipboard";
|
||||
import {Modal} from "bootstrap";
|
||||
|
||||
class RegisterEventHelper {
|
||||
constructor() {
|
||||
this.registerTooltips();
|
||||
this.configureDropdowns();
|
||||
|
||||
|
||||
// Only register special character input if enabled in configuration
|
||||
const keybindingsEnabled = document.body.dataset.keybindingsSpecialCharacters !== 'false';
|
||||
if (keybindingsEnabled) {
|
||||
|
|
@ -40,8 +39,6 @@ class RegisterEventHelper {
|
|||
});
|
||||
|
||||
this.registerModalDropRemovalOnFormSubmit();
|
||||
|
||||
|
||||
}
|
||||
|
||||
registerModalDropRemovalOnFormSubmit() {
|
||||
|
|
@ -83,11 +80,17 @@ class RegisterEventHelper {
|
|||
|
||||
registerTooltips() {
|
||||
const handler = () => {
|
||||
$(".tooltip").remove();
|
||||
document.querySelectorAll('.tooltip').forEach(el => el.remove());
|
||||
|
||||
//Exclude dropdown buttons from tooltips, otherwise we run into endless errors from bootstrap (bootstrap.esm.js:614 Bootstrap doesn't allow more than one instance per element. Bound instance: bs.dropdown.)
|
||||
$('a[title], label[title], button[title]:not([data-bs-toggle="dropdown"]), p[title], span[title], h6[title], h3[title], i[title], small[title]')
|
||||
//@ts-ignore
|
||||
.tooltip("hide").tooltip({container: "body", placement: "auto", boundary: 'window'});
|
||||
const tooltipSelector = 'a[title], label[title], button[title]:not([data-bs-toggle="dropdown"]), p[title], span[title], h6[title], h3[title], i[title], small[title]';
|
||||
document.querySelectorAll(tooltipSelector).forEach(el => {
|
||||
const existing = Tooltip.getInstance(el);
|
||||
if (existing) {
|
||||
existing.dispose();
|
||||
}
|
||||
new Tooltip(el, {container: 'body', placement: 'auto', boundary: 'window'});
|
||||
});
|
||||
};
|
||||
|
||||
this.registerLoadHandler(handler);
|
||||
|
|
@ -95,242 +98,240 @@ class RegisterEventHelper {
|
|||
}
|
||||
|
||||
registerSpecialCharInput() {
|
||||
this.registerLoadHandler(() => {
|
||||
//@ts-ignore
|
||||
$("input[type=text], input[type=search]").unbind("keydown").keydown(function (event) {
|
||||
let use_special_char = event.altKey;
|
||||
|
||||
let greek_char = "";
|
||||
if (use_special_char){
|
||||
//Use the key property to determine the greek letter (as it is independent of the keyboard layout)
|
||||
switch(event.key) {
|
||||
//Greek letters
|
||||
case "a": //Alpha (lowercase)
|
||||
greek_char = "\u03B1";
|
||||
break;
|
||||
case "A": //Alpha (uppercase)
|
||||
greek_char = "\u0391";
|
||||
break;
|
||||
case "b": //Beta (lowercase)
|
||||
greek_char = "\u03B2";
|
||||
break;
|
||||
case "B": //Beta (uppercase)
|
||||
greek_char = "\u0392";
|
||||
break;
|
||||
case "g": //Gamma (lowercase)
|
||||
greek_char = "\u03B3";
|
||||
break;
|
||||
case "G": //Gamma (uppercase)
|
||||
greek_char = "\u0393";
|
||||
break;
|
||||
case "d": //Delta (lowercase)
|
||||
greek_char = "\u03B4";
|
||||
break;
|
||||
case "D": //Delta (uppercase)
|
||||
greek_char = "\u0394";
|
||||
break;
|
||||
case "e": //Epsilon (lowercase)
|
||||
greek_char = "\u03B5";
|
||||
break;
|
||||
case "E": //Epsilon (uppercase)
|
||||
greek_char = "\u0395";
|
||||
break;
|
||||
case "z": //Zeta (lowercase)
|
||||
greek_char = "\u03B6";
|
||||
break;
|
||||
case "Z": //Zeta (uppercase)
|
||||
greek_char = "\u0396";
|
||||
break;
|
||||
case "h": //Eta (lowercase)
|
||||
greek_char = "\u03B7";
|
||||
break;
|
||||
case "H": //Eta (uppercase)
|
||||
greek_char = "\u0397";
|
||||
break;
|
||||
case "q": //Theta (lowercase)
|
||||
greek_char = "\u03B8";
|
||||
break;
|
||||
case "Q": //Theta (uppercase)
|
||||
greek_char = "\u0398";
|
||||
break;
|
||||
case "i": //Iota (lowercase)
|
||||
greek_char = "\u03B9";
|
||||
break;
|
||||
case "I": //Iota (uppercase)
|
||||
greek_char = "\u0399";
|
||||
break;
|
||||
case "k": //Kappa (lowercase)
|
||||
greek_char = "\u03BA";
|
||||
break;
|
||||
case "K": //Kappa (uppercase)
|
||||
greek_char = "\u039A";
|
||||
break;
|
||||
case "l": //Lambda (lowercase)
|
||||
greek_char = "\u03BB";
|
||||
break;
|
||||
case "L": //Lambda (uppercase)
|
||||
greek_char = "\u039B";
|
||||
break;
|
||||
case "m": //Mu (lowercase)
|
||||
greek_char = "\u03BC";
|
||||
break;
|
||||
case "M": //Mu (uppercase)
|
||||
greek_char = "\u039C";
|
||||
break;
|
||||
case "n": //Nu (lowercase)
|
||||
greek_char = "\u03BD";
|
||||
break;
|
||||
case "N": //Nu (uppercase)
|
||||
greek_char = "\u039D";
|
||||
break;
|
||||
case "x": //Xi (lowercase)
|
||||
greek_char = "\u03BE";
|
||||
break;
|
||||
case "X": //Xi (uppercase)
|
||||
greek_char = "\u039E";
|
||||
break;
|
||||
case "o": //Omicron (lowercase)
|
||||
greek_char = "\u03BF";
|
||||
break;
|
||||
case "O": //Omicron (uppercase)
|
||||
greek_char = "\u039F";
|
||||
break;
|
||||
case "p": //Pi (lowercase)
|
||||
greek_char = "\u03C0";
|
||||
break;
|
||||
case "P": //Pi (uppercase)
|
||||
greek_char = "\u03A0";
|
||||
break;
|
||||
case "r": //Rho (lowercase)
|
||||
greek_char = "\u03C1";
|
||||
break;
|
||||
case "R": //Rho (uppercase)
|
||||
greek_char = "\u03A1";
|
||||
break;
|
||||
case "s": //Sigma (lowercase)
|
||||
greek_char = "\u03C3";
|
||||
break;
|
||||
case "S": //Sigma (uppercase)
|
||||
greek_char = "\u03A3";
|
||||
break;
|
||||
case "t": //Tau (lowercase)
|
||||
greek_char = "\u03C4";
|
||||
break;
|
||||
case "T": //Tau (uppercase)
|
||||
greek_char = "\u03A4";
|
||||
break;
|
||||
case "u": //Upsilon (lowercase)
|
||||
greek_char = "\u03C5";
|
||||
break;
|
||||
case "U": //Upsilon (uppercase)
|
||||
greek_char = "\u03A5";
|
||||
break;
|
||||
case "f": //Phi (lowercase)
|
||||
greek_char = "\u03C6";
|
||||
break;
|
||||
case "F": //Phi (uppercase)
|
||||
greek_char = "\u03A6";
|
||||
break;
|
||||
case "c": //Chi (lowercase)
|
||||
greek_char = "\u03C7";
|
||||
break;
|
||||
case "C": //Chi (uppercase)
|
||||
greek_char = "\u03A7";
|
||||
break;
|
||||
case "y": //Psi (lowercase)
|
||||
greek_char = "\u03C8";
|
||||
break;
|
||||
case "Y": //Psi (uppercase)
|
||||
greek_char = "\u03A8";
|
||||
break;
|
||||
case "w": //Omega (lowercase)
|
||||
greek_char = "\u03C9";
|
||||
break;
|
||||
case "W": //Omega (uppercase)
|
||||
greek_char = "\u03A9";
|
||||
break;
|
||||
}
|
||||
|
||||
//Use keycodes for special characters as the shift char on the number keys are layout dependent
|
||||
switch (event.keyCode) {
|
||||
case 49: //1 key
|
||||
//Product symbol on shift, sum on no shift
|
||||
greek_char = event.shiftKey ? "\u220F" : "\u2211";
|
||||
break;
|
||||
case 50: //2 key
|
||||
//Integral on no shift, partial derivative on shift
|
||||
greek_char = event.shiftKey ? "\u2202" : "\u222B";
|
||||
break;
|
||||
case 51: //3 key
|
||||
//Less than or equal on no shift, greater than or equal on shift
|
||||
greek_char = event.shiftKey ? "\u2265" : "\u2264";
|
||||
break;
|
||||
case 52: //4 key
|
||||
//Empty set on shift, infinity on no shift
|
||||
greek_char = event.shiftKey ? "\u2205" : "\u221E";
|
||||
break;
|
||||
case 53: //5 key
|
||||
//Not equal on shift, approx equal on no shift
|
||||
greek_char = event.shiftKey ? "\u2260" : "\u2248";
|
||||
break;
|
||||
case 54: //6 key
|
||||
//Element of on no shift, not element of on shift
|
||||
greek_char = event.shiftKey ? "\u2209" : "\u2208";
|
||||
break;
|
||||
case 55: //7 key
|
||||
//And on shift, or on no shift
|
||||
greek_char = event.shiftKey ? "\u2227" : "\u2228";
|
||||
break;
|
||||
case 56: //8 key
|
||||
//Proportional to on shift, angle on no shift
|
||||
greek_char = event.shiftKey ? "\u221D" : "\u2220";
|
||||
break;
|
||||
case 57: //9 key
|
||||
//Cube root on shift, square root on no shift
|
||||
greek_char = event.shiftKey ? "\u221B" : "\u221A";
|
||||
break;
|
||||
case 48: //0 key
|
||||
//Minus-Plus on shift, plus-minus on no shift
|
||||
greek_char = event.shiftKey ? "\u2213" : "\u00B1";
|
||||
break;
|
||||
|
||||
//Special characters
|
||||
case 219: //hyphen (or ß on german layout)
|
||||
//Copyright on no shift, TM on shift
|
||||
greek_char = event.shiftKey ? "\u2122" : "\u00A9";
|
||||
break;
|
||||
case 191: //forward slash (or # on german layout)
|
||||
//Generic currency on no shift, paragraph on shift
|
||||
greek_char = event.shiftKey ? "\u00B6" : "\u00A4";
|
||||
break;
|
||||
|
||||
//Currency symbols
|
||||
case 192: //: or (ö on german layout)
|
||||
//Euro on no shift, pound on shift
|
||||
greek_char = event.shiftKey ? "\u00A3" : "\u20AC";
|
||||
break;
|
||||
case 221: //; or (ä on german layout)
|
||||
//Yen on no shift, dollar on shift
|
||||
greek_char = event.shiftKey ? "\u0024" : "\u00A5";
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(greek_char=="") return;
|
||||
|
||||
let $txt = $(this);
|
||||
//@ts-ignore
|
||||
let caretPos = $txt[0].selectionStart;
|
||||
let textAreaTxt = $txt.val().toString();
|
||||
$txt.val(textAreaTxt.substring(0, caretPos) + greek_char + textAreaTxt.substring(caretPos) );
|
||||
const keydownHandler = function(event) {
|
||||
let use_special_char = event.altKey;
|
||||
|
||||
let greek_char = "";
|
||||
if (use_special_char){
|
||||
//Use the key property to determine the greek letter (as it is independent of the keyboard layout)
|
||||
switch(event.key) {
|
||||
//Greek letters
|
||||
case "a": //Alpha (lowercase)
|
||||
greek_char = "α";
|
||||
break;
|
||||
case "A": //Alpha (uppercase)
|
||||
greek_char = "Α";
|
||||
break;
|
||||
case "b": //Beta (lowercase)
|
||||
greek_char = "β";
|
||||
break;
|
||||
case "B": //Beta (uppercase)
|
||||
greek_char = "Β";
|
||||
break;
|
||||
case "g": //Gamma (lowercase)
|
||||
greek_char = "γ";
|
||||
break;
|
||||
case "G": //Gamma (uppercase)
|
||||
greek_char = "Γ";
|
||||
break;
|
||||
case "d": //Delta (lowercase)
|
||||
greek_char = "δ";
|
||||
break;
|
||||
case "D": //Delta (uppercase)
|
||||
greek_char = "Δ";
|
||||
break;
|
||||
case "e": //Epsilon (lowercase)
|
||||
greek_char = "ε";
|
||||
break;
|
||||
case "E": //Epsilon (uppercase)
|
||||
greek_char = "Ε";
|
||||
break;
|
||||
case "z": //Zeta (lowercase)
|
||||
greek_char = "ζ";
|
||||
break;
|
||||
case "Z": //Zeta (uppercase)
|
||||
greek_char = "Ζ";
|
||||
break;
|
||||
case "h": //Eta (lowercase)
|
||||
greek_char = "η";
|
||||
break;
|
||||
case "H": //Eta (uppercase)
|
||||
greek_char = "Η";
|
||||
break;
|
||||
case "q": //Theta (lowercase)
|
||||
greek_char = "θ";
|
||||
break;
|
||||
case "Q": //Theta (uppercase)
|
||||
greek_char = "Θ";
|
||||
break;
|
||||
case "i": //Iota (lowercase)
|
||||
greek_char = "ι";
|
||||
break;
|
||||
case "I": //Iota (uppercase)
|
||||
greek_char = "Ι";
|
||||
break;
|
||||
case "k": //Kappa (lowercase)
|
||||
greek_char = "κ";
|
||||
break;
|
||||
case "K": //Kappa (uppercase)
|
||||
greek_char = "Κ";
|
||||
break;
|
||||
case "l": //Lambda (lowercase)
|
||||
greek_char = "λ";
|
||||
break;
|
||||
case "L": //Lambda (uppercase)
|
||||
greek_char = "Λ";
|
||||
break;
|
||||
case "m": //Mu (lowercase)
|
||||
greek_char = "μ";
|
||||
break;
|
||||
case "M": //Mu (uppercase)
|
||||
greek_char = "Μ";
|
||||
break;
|
||||
case "n": //Nu (lowercase)
|
||||
greek_char = "ν";
|
||||
break;
|
||||
case "N": //Nu (uppercase)
|
||||
greek_char = "Ν";
|
||||
break;
|
||||
case "x": //Xi (lowercase)
|
||||
greek_char = "ξ";
|
||||
break;
|
||||
case "X": //Xi (uppercase)
|
||||
greek_char = "Ξ";
|
||||
break;
|
||||
case "o": //Omicron (lowercase)
|
||||
greek_char = "ο";
|
||||
break;
|
||||
case "O": //Omicron (uppercase)
|
||||
greek_char = "Ο";
|
||||
break;
|
||||
case "p": //Pi (lowercase)
|
||||
greek_char = "π";
|
||||
break;
|
||||
case "P": //Pi (uppercase)
|
||||
greek_char = "Π";
|
||||
break;
|
||||
case "r": //Rho (lowercase)
|
||||
greek_char = "ρ";
|
||||
break;
|
||||
case "R": //Rho (uppercase)
|
||||
greek_char = "Ρ";
|
||||
break;
|
||||
case "s": //Sigma (lowercase)
|
||||
greek_char = "σ";
|
||||
break;
|
||||
case "S": //Sigma (uppercase)
|
||||
greek_char = "Σ";
|
||||
break;
|
||||
case "t": //Tau (lowercase)
|
||||
greek_char = "τ";
|
||||
break;
|
||||
case "T": //Tau (uppercase)
|
||||
greek_char = "Τ";
|
||||
break;
|
||||
case "u": //Upsilon (lowercase)
|
||||
greek_char = "υ";
|
||||
break;
|
||||
case "U": //Upsilon (uppercase)
|
||||
greek_char = "Υ";
|
||||
break;
|
||||
case "f": //Phi (lowercase)
|
||||
greek_char = "φ";
|
||||
break;
|
||||
case "F": //Phi (uppercase)
|
||||
greek_char = "Φ";
|
||||
break;
|
||||
case "c": //Chi (lowercase)
|
||||
greek_char = "χ";
|
||||
break;
|
||||
case "C": //Chi (uppercase)
|
||||
greek_char = "Χ";
|
||||
break;
|
||||
case "y": //Psi (lowercase)
|
||||
greek_char = "ψ";
|
||||
break;
|
||||
case "Y": //Psi (uppercase)
|
||||
greek_char = "Ψ";
|
||||
break;
|
||||
case "w": //Omega (lowercase)
|
||||
greek_char = "ω";
|
||||
break;
|
||||
case "W": //Omega (uppercase)
|
||||
greek_char = "Ω";
|
||||
break;
|
||||
}
|
||||
|
||||
//Use keycodes for special characters as the shift char on the number keys are layout dependent
|
||||
switch (event.keyCode) {
|
||||
case 49: //1 key
|
||||
//Product symbol on shift, sum on no shift
|
||||
greek_char = event.shiftKey ? "∏" : "∑";
|
||||
break;
|
||||
case 50: //2 key
|
||||
//Integral on no shift, partial derivative on shift
|
||||
greek_char = event.shiftKey ? "∂" : "∫";
|
||||
break;
|
||||
case 51: //3 key
|
||||
//Less than or equal on no shift, greater than or equal on shift
|
||||
greek_char = event.shiftKey ? "≥" : "≤";
|
||||
break;
|
||||
case 52: //4 key
|
||||
//Empty set on shift, infinity on no shift
|
||||
greek_char = event.shiftKey ? "∅" : "∞";
|
||||
break;
|
||||
case 53: //5 key
|
||||
//Not equal on shift, approx equal on no shift
|
||||
greek_char = event.shiftKey ? "≠" : "≈";
|
||||
break;
|
||||
case 54: //6 key
|
||||
//Element of on no shift, not element of on shift
|
||||
greek_char = event.shiftKey ? "∉" : "∈";
|
||||
break;
|
||||
case 55: //7 key
|
||||
//And on shift, or on no shift
|
||||
greek_char = event.shiftKey ? "∧" : "∨";
|
||||
break;
|
||||
case 56: //8 key
|
||||
//Proportional to on shift, angle on no shift
|
||||
greek_char = event.shiftKey ? "∝" : "∠";
|
||||
break;
|
||||
case 57: //9 key
|
||||
//Cube root on shift, square root on no shift
|
||||
greek_char = event.shiftKey ? "∛" : "√";
|
||||
break;
|
||||
case 48: //0 key
|
||||
//Minus-Plus on shift, plus-minus on no shift
|
||||
greek_char = event.shiftKey ? "∓" : "±";
|
||||
break;
|
||||
|
||||
//Special characters
|
||||
case 219: //hyphen (or ß on german layout)
|
||||
//Copyright on no shift, TM on shift
|
||||
greek_char = event.shiftKey ? "™" : "©";
|
||||
break;
|
||||
case 191: //forward slash (or # on german layout)
|
||||
//Generic currency on no shift, paragraph on shift
|
||||
greek_char = event.shiftKey ? "¶" : "¤";
|
||||
break;
|
||||
|
||||
//Currency symbols
|
||||
case 192: //: or (ö on german layout)
|
||||
//Euro on no shift, pound on shift
|
||||
greek_char = event.shiftKey ? "£" : "€";
|
||||
break;
|
||||
case 221: //; or (ä on german layout)
|
||||
//Yen on no shift, dollar on shift
|
||||
greek_char = event.shiftKey ? "$" : "¥";
|
||||
break;
|
||||
}
|
||||
|
||||
if(greek_char=="") return;
|
||||
|
||||
const txt = event.currentTarget;
|
||||
const caretPos = txt.selectionStart;
|
||||
const textAreaTxt = txt.value;
|
||||
txt.value = textAreaTxt.substring(0, caretPos) + greek_char + textAreaTxt.substring(caretPos);
|
||||
}
|
||||
};
|
||||
|
||||
this.registerLoadHandler(() => {
|
||||
document.querySelectorAll('input[type=text], input[type=search]').forEach(input => {
|
||||
input.removeEventListener('keydown', keydownHandler);
|
||||
input.addEventListener('keydown', keydownHandler);
|
||||
});
|
||||
//@ts-ignore
|
||||
this.greek_once = true;
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new RegisterEventHelper();
|
||||
export default new RegisterEventHelper();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
|
||||
* Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
|
|
@ -17,30 +17,4 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.modal-body > .bootbox-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 0.5rem 0.75rem;
|
||||
z-index: 1;
|
||||
}
|
||||
.modal .bootbox-close-button {
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
button.bootbox-close-button {
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.bootbox-close-button {
|
||||
/* float: right; */
|
||||
font-size: 1.40625rem;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
color: #000;
|
||||
text-shadow: none;
|
||||
opacity: .5;
|
||||
}
|
||||
import "bootswatch/dist/brite/bootstrap.css";
|
||||
|
|
@ -57,9 +57,10 @@
|
|||
"scheb/2fa-trusted-device": "^v7.11.0",
|
||||
"shivas/versioning-bundle": "^4.0",
|
||||
"spatie/db-dumper": "^3.3.1",
|
||||
"symfony/ai-bundle": "^0.9.0",
|
||||
"symfony/ai-lm-studio-platform": "^0.9.0",
|
||||
"symfony/ai-open-router-platform": "^0.9.0",
|
||||
"symfony/ai-bundle": "^0.10.0",
|
||||
"symfony/ai-lm-studio-platform": "^v0.10.0",
|
||||
"symfony/ai-ollama-platform": "^0.10.0",
|
||||
"symfony/ai-open-router-platform": "^0.10.0",
|
||||
"symfony/apache-pack": "^1.0",
|
||||
"symfony/asset": "7.4.*",
|
||||
"symfony/console": "7.4.*",
|
||||
|
|
|
|||
601
composer.lock
generated
601
composer.lock
generated
File diff suppressed because it is too large
Load diff
5
config/packages/ai_ollama_platform.yaml
Normal file
5
config/packages/ai_ollama_platform.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ai:
|
||||
platform:
|
||||
ollama:
|
||||
endpoint: '%env(string:settings:ai_ollama:endpoint)%'
|
||||
api_key: '%env(string:settings:ai_ollama:apiKey)%'
|
||||
|
|
@ -53,6 +53,7 @@ parameters:
|
|||
# Themes commented here by default, are not really usable, because of display problems. Enable them at your own risk!
|
||||
partdb.available_themes:
|
||||
- bootstrap
|
||||
- brite
|
||||
- cerulean
|
||||
- cosmo
|
||||
- cyborg
|
||||
|
|
|
|||
|
|
@ -2874,8 +2874,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
|||
* enable_translation?: bool|Param, // Enable translation for the system prompt // Default: false
|
||||
* translation_domain?: string|Param, // The translation domain for the system prompt // Default: null
|
||||
* },
|
||||
* tools?: bool|array{
|
||||
* enabled?: bool|Param, // Default: true
|
||||
* tools?: bool|array{ // Tools are opt-in: set to true to inject all services tagged with "ai.tool", or configure an explicit list of tools. When the option is omitted (or set to null or false), no tools are registered.
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* services?: list<string|array{ // Default: []
|
||||
* service?: string|Param,
|
||||
* agent?: string|Param,
|
||||
|
|
@ -2886,6 +2886,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
|||
* },
|
||||
* keep_tool_messages?: bool|Param, // Keep tool messages in the conversation history // Default: false
|
||||
* include_sources?: bool|Param, // Include sources exposed by tools as part of the tool result metadata // Default: false
|
||||
* max_tool_calls?: scalar|Param|null, // Maximum number of tool calls per agent call, null to disable // Default: 50
|
||||
* fault_tolerant_toolbox?: bool|Param, // Continue the agent run even if a tool call fails // Default: true
|
||||
* speech?: bool|array{ // Speech (TTS/STT) decorator configuration
|
||||
* enabled?: bool|Param, // Default: true
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ sudo ln -s /etc/apache2/sites-available/partdb.conf /etc/apache2/sites-enabled/p
|
|||
Configure apache to show pretty URL paths for Part-DB (`/label/dialog` instead of `/index.php/label/dialog`):
|
||||
|
||||
```bash
|
||||
sudo a2enmod rewrite
|
||||
sudo a2enmod rewrite headers
|
||||
```
|
||||
|
||||
If you want to access Part-DB via the IP-Address of the server, instead of the domain name, you have to remove the
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ server {
|
|||
root /var/www/partdb/public;
|
||||
|
||||
location / {
|
||||
# Headers are set here for static assets. PHP responses are served via the index.php location
|
||||
# below and inherit neither of these headers, so Nelmio's PHP-side CSP is unaffected.
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; sandbox;" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
try_files $uri /index.php$is_args$args;
|
||||
}
|
||||
|
||||
|
|
@ -57,10 +61,12 @@ server {
|
|||
location ~* ^/media/.*\.(php[3-8]?|phar|phtml|pht|phps)$ {
|
||||
return 403;
|
||||
}
|
||||
|
||||
# Set Content-Security-Policy for svg files, to block embedded javascript in there
|
||||
|
||||
# SVG files get a slightly different CSP because they can embed resources and must not be framed.
|
||||
# This regex location takes precedence over location /, so headers must be repeated here.
|
||||
location ~* \.svg$ {
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none';";
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'; sandbox;" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
}
|
||||
|
||||
error_log /var/log/nginx/parts.error.log;
|
||||
|
|
|
|||
|
|
@ -25,3 +25,10 @@ You need to supply an API key for OpenRouter to use it as an AI platform in Part
|
|||
|
||||
[LMStudio](https://lmstudio.ai/) is a local LLM hosting solution that allows you to run LLMs on your own hardware. You can use LMStudio to host your own LLM and connect it to Part-DB for AI features.
|
||||
Currently only LMStudio without any authentication is supported. Supply your LMStudio instance URL (including the port) to use it as an AI platform in Part-DB.
|
||||
You have to set a model by hand, as suggestions currently do not work yet. Ensure the context length is suitable for your application.
|
||||
|
||||
### Ollama
|
||||
|
||||
[Ollama](https://ollama.com/) is another local LLM hosting solution that allows you to run LLMs on your own hardware. You can use Ollama to host your own LLM and connect it to Part-DB for AI features.
|
||||
Supply your Ollama instance URL (including the port) and an optional API key for authentication to use it as an AI platform in Part-DB. The model selector should give you suggestions about available models.
|
||||
Ensure the context length is suitable for your application.
|
||||
|
|
|
|||
22
package.json
22
package.json
|
|
@ -13,7 +13,7 @@
|
|||
"bootstrap": "^5.1.3",
|
||||
"core-js": "^3.38.0",
|
||||
"intl-messageformat": "^10.5.11",
|
||||
"jquery": "^3.5.1",
|
||||
"jquery": "^4.0.0",
|
||||
"popper.js": "^1.14.7",
|
||||
"regenerator-runtime": "^0.14.1",
|
||||
"webpack": "^5.74.0",
|
||||
|
|
@ -38,20 +38,21 @@
|
|||
"@algolia/autocomplete-theme-classic": "^1.17.0",
|
||||
"@jbtronics/bs-treeview": "^1.0.1",
|
||||
"@part-db/html5-qrcode": "^4.0.0",
|
||||
"@zxcvbn-ts/core": "^3.0.2",
|
||||
"@zxcvbn-ts/language-common": "^3.0.3",
|
||||
"@zxcvbn-ts/language-de": "^3.0.1",
|
||||
"@zxcvbn-ts/language-en": "^3.0.1",
|
||||
"@zxcvbn-ts/language-fr": "^3.0.1",
|
||||
"@zxcvbn-ts/language-ja": "^3.0.1",
|
||||
"@zxcvbn-ts/core": "^4.1.2",
|
||||
"@zxcvbn-ts/language-common": "^4.1.2",
|
||||
"@zxcvbn-ts/language-de": "^4.1.1",
|
||||
"@zxcvbn-ts/language-en": "^4.1.1",
|
||||
"@zxcvbn-ts/language-fr": "^4.1.1",
|
||||
"@zxcvbn-ts/language-it": "^4.1.1",
|
||||
"@zxcvbn-ts/language-ja": "^4.1.1",
|
||||
"@zxcvbn-ts/language-pl": "^4.1.1",
|
||||
"attr-accept": "^2.2.5",
|
||||
"barcode-detector": "^3.0.5",
|
||||
"bootbox": "^6.0.0",
|
||||
"bootswatch": "^5.1.3",
|
||||
"bs-custom-file-input": "^1.3.4",
|
||||
"ckeditor5": "^48.0.0",
|
||||
"clipboard": "^2.0.4",
|
||||
"compression-webpack-plugin": "^11.1.0",
|
||||
"compression-webpack-plugin": "^12.0.0",
|
||||
"datatables.net": "^2.0.0",
|
||||
"datatables.net-bs5": "^2.0.0",
|
||||
"datatables.net-buttons-bs5": "^3.0.0",
|
||||
|
|
@ -69,11 +70,12 @@
|
|||
"marked-mangle": "^1.0.1",
|
||||
"pdfmake": "^0.3.7",
|
||||
"stimulus-use": "^0.52.0",
|
||||
"sweetalert2": "^11.26.25",
|
||||
"tom-select": "^2.1.0",
|
||||
"ts-loader": "^9.2.6",
|
||||
"typescript": "^6.0.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"jquery": "^3.5.1"
|
||||
"jquery": "^4.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,9 +119,14 @@ DirectoryIndex index.php
|
|||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
# Set Content-Security-Policy for svg files (and compressed variants), to block embedded javascript in there
|
||||
<IfModule mod_headers.c>
|
||||
# Set a strict CSP for all static assets not handled by PHP.
|
||||
# PHP responses already carry their own CSP via NelmioSecurityBundle, so setifempty leaves those untouched.
|
||||
Header always setifempty Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; sandbox;"
|
||||
Header always setifempty X-Content-Type-Options "nosniff"
|
||||
|
||||
# SVG files get a slightly different CSP because they can embed resources and must not be framed.
|
||||
<FilesMatch "\.(svg|svg\.gz|svg\.br)$">
|
||||
Header set Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none';"
|
||||
Header always set Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'; sandbox;"
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated on Mon Jun 8 06:51:27 UTC 2026
|
||||
# Generated on Mon Jun 22 07:31:48 UTC 2026
|
||||
# This file contains all footprints available in the offical KiCAD library
|
||||
Audio_Module:Reverb_BTDR-1H
|
||||
Audio_Module:Reverb_BTDR-1V
|
||||
|
|
@ -8293,6 +8293,7 @@ Converter_DCDC:Converter_DCDC_Hamamatsu_C11204-1_THT
|
|||
Converter_DCDC:Converter_DCDC_MeanWell_NID30_THT
|
||||
Converter_DCDC:Converter_DCDC_MeanWell_NID60_THT
|
||||
Converter_DCDC:Converter_DCDC_MeanWell_NSD10_THT
|
||||
Converter_DCDC:Converter_DCDC_MeanWell_SMU02x-xxN_THT
|
||||
Converter_DCDC:Converter_DCDC_Murata_CRE1xxxxxx3C_THT
|
||||
Converter_DCDC:Converter_DCDC_Murata_CRE1xxxxxxDC_THT
|
||||
Converter_DCDC:Converter_DCDC_Murata_CRE1xxxxxxSC_THT
|
||||
|
|
@ -13030,8 +13031,6 @@ Package_SON:WSON-6-1EP_2x2mm_P0.65mm_EP1x1.6mm
|
|||
Package_SON:WSON-6-1EP_2x2mm_P0.65mm_EP1x1.6mm_ThermalVias
|
||||
Package_SON:WSON-6-1EP_3x3mm_P0.95mm
|
||||
Package_SON:WSON-6_1.5x1.5mm_P0.5mm
|
||||
Package_SON:WSON-8-1EP_2x2mm_P0.5mm_EP0.9x1.6mm
|
||||
Package_SON:WSON-8-1EP_2x2mm_P0.5mm_EP0.9x1.6mm_ThermalVias
|
||||
Package_SON:WSON-8-1EP_3x2.5mm_P0.5mm_EP1.2x1.5mm_PullBack
|
||||
Package_SON:WSON-8-1EP_3x2.5mm_P0.5mm_EP1.2x1.5mm_PullBack_ThermalVias
|
||||
Package_SON:WSON-8-1EP_3x3mm_P0.5mm_EP1.2x2mm
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated on Mon Jun 8 06:52:04 UTC 2026
|
||||
# Generated on Mon Jun 22 07:32:26 UTC 2026
|
||||
# This file contains all symbols available in the offical KiCAD library
|
||||
4xxx:14528
|
||||
4xxx:14529
|
||||
|
|
@ -4954,6 +4954,7 @@ Converter_DCDC:RPMH15-1.5
|
|||
Converter_DCDC:RPMH24-1.5
|
||||
Converter_DCDC:RPMH3.3-1.5
|
||||
Converter_DCDC:RPMH5.0-1.5
|
||||
Converter_DCDC:SMU02L-24N
|
||||
Converter_DCDC:TBA1-0310
|
||||
Converter_DCDC:TBA1-0311
|
||||
Converter_DCDC:TBA1-0510
|
||||
|
|
@ -5300,21 +5301,39 @@ Converter_DCDC:TMR-4812
|
|||
Converter_DCDC:TMR-4821
|
||||
Converter_DCDC:TMR-4822
|
||||
Converter_DCDC:TMR-4823
|
||||
Converter_DCDC:TMR10-1211WI
|
||||
Converter_DCDC:TMR10-1212WI
|
||||
Converter_DCDC:TMR10-1213WI
|
||||
Converter_DCDC:TMR10-1215WI
|
||||
Converter_DCDC:TMR10-1222WI
|
||||
Converter_DCDC:TMR10-1223WI
|
||||
Converter_DCDC:TMR10-2410WIR
|
||||
Converter_DCDC:TMR10-2411WI
|
||||
Converter_DCDC:TMR10-2411WIR
|
||||
Converter_DCDC:TMR10-2412WI
|
||||
Converter_DCDC:TMR10-2412WIR
|
||||
Converter_DCDC:TMR10-2413WI
|
||||
Converter_DCDC:TMR10-2413WIR
|
||||
Converter_DCDC:TMR10-2415WI
|
||||
Converter_DCDC:TMR10-2415WIR
|
||||
Converter_DCDC:TMR10-2421WIR
|
||||
Converter_DCDC:TMR10-2422WI
|
||||
Converter_DCDC:TMR10-2422WIR
|
||||
Converter_DCDC:TMR10-2423WI
|
||||
Converter_DCDC:TMR10-2423WIR
|
||||
Converter_DCDC:TMR10-4810WIR
|
||||
Converter_DCDC:TMR10-4811WI
|
||||
Converter_DCDC:TMR10-4811WIR
|
||||
Converter_DCDC:TMR10-4812WI
|
||||
Converter_DCDC:TMR10-4812WIR
|
||||
Converter_DCDC:TMR10-4813WI
|
||||
Converter_DCDC:TMR10-4813WIR
|
||||
Converter_DCDC:TMR10-4815WI
|
||||
Converter_DCDC:TMR10-4815WIR
|
||||
Converter_DCDC:TMR10-4821WIR
|
||||
Converter_DCDC:TMR10-4822WI
|
||||
Converter_DCDC:TMR10-4822WIR
|
||||
Converter_DCDC:TMR10-4823WI
|
||||
Converter_DCDC:TMR10-4823WIR
|
||||
Converter_DCDC:TMR10-7210WIR
|
||||
Converter_DCDC:TMR10-7211WIR
|
||||
|
|
@ -6124,6 +6143,7 @@ Device:SparkGap
|
|||
Device:Speaker
|
||||
Device:Speaker_Crystal
|
||||
Device:Speaker_Ultrasound
|
||||
Device:Thermal_Jumper
|
||||
Device:Thermistor
|
||||
Device:Thermistor_NTC
|
||||
Device:Thermistor_NTC_3Wire
|
||||
|
|
@ -14593,6 +14613,8 @@ MCU_Texas:LM4F111C4QR
|
|||
MCU_Texas:LM4F111E5QR
|
||||
MCU_Texas:LM4F111H5QR
|
||||
MCU_Texas:MSP432E401Y
|
||||
MCU_Texas:MSPM0C110xSDDF
|
||||
MCU_Texas:MSPM0C110xSDSG
|
||||
MCU_Texas:TM4C1230C3PM
|
||||
MCU_Texas:TM4C1230D5PM
|
||||
MCU_Texas:TM4C1230E6PM
|
||||
|
|
@ -15671,6 +15693,7 @@ Power_Management:LM5069MM-1
|
|||
Power_Management:LM5069MM-2
|
||||
Power_Management:LM66100DCK
|
||||
Power_Management:LM74700
|
||||
Power_Management:LM74701-Q1
|
||||
Power_Management:LMG3410
|
||||
Power_Management:LMG5200
|
||||
Power_Management:LT1641-1
|
||||
|
|
@ -15772,6 +15795,7 @@ Power_Management:TPS22810DBV
|
|||
Power_Management:TPS22810DRV
|
||||
Power_Management:TPS22917DBV
|
||||
Power_Management:TPS22917LDBV
|
||||
Power_Management:TPS22919DCK
|
||||
Power_Management:TPS22929D
|
||||
Power_Management:TPS22993
|
||||
Power_Management:TPS2412D
|
||||
|
|
@ -16683,6 +16707,19 @@ Reference_Voltage:LM4040LP-4.1
|
|||
Reference_Voltage:LM4040LP-5
|
||||
Reference_Voltage:LM4040LP-8.2
|
||||
Reference_Voltage:LM4041LP-ADJ
|
||||
Reference_Voltage:LM4050xEM3-2.1
|
||||
Reference_Voltage:LM4050xEM3-2.5
|
||||
Reference_Voltage:LM4050xEM3-3.0
|
||||
Reference_Voltage:LM4050xEM3-3.3
|
||||
Reference_Voltage:LM4050xEM3-4.1
|
||||
Reference_Voltage:LM4050xEM3-5.0
|
||||
Reference_Voltage:LM4050xEX3-2.1
|
||||
Reference_Voltage:LM4050xEX3-2.5
|
||||
Reference_Voltage:LM4050xEX3-3.3
|
||||
Reference_Voltage:LM4050xEX3-4.1
|
||||
Reference_Voltage:LM4050xEX3-5.0
|
||||
Reference_Voltage:LM4051xEM3-1.2
|
||||
Reference_Voltage:LM4051xEX3-1.2
|
||||
Reference_Voltage:LM4125AIM5-2.5
|
||||
Reference_Voltage:LM4125IM5-2.0
|
||||
Reference_Voltage:LM4125IM5-2.5
|
||||
|
|
@ -16830,7 +16867,6 @@ Reference_Voltage:MCP1501-25xCH
|
|||
Reference_Voltage:MCP1501-25xRW
|
||||
Reference_Voltage:MCP1501-25xSN
|
||||
Reference_Voltage:MCP1501-30xCH
|
||||
Reference_Voltage:MCP1501-30xRW
|
||||
Reference_Voltage:MCP1501-30xSN
|
||||
Reference_Voltage:MCP1501-33xCH
|
||||
Reference_Voltage:MCP1501-33xRW
|
||||
|
|
@ -19263,6 +19299,7 @@ Regulator_Switching:LT1373HVCN8
|
|||
Regulator_Switching:LT1373HVCS8
|
||||
Regulator_Switching:LT1377CN8
|
||||
Regulator_Switching:LT1377CS8
|
||||
Regulator_Switching:LT1931
|
||||
Regulator_Switching:LT1945
|
||||
Regulator_Switching:LT3430
|
||||
Regulator_Switching:LT3430-1
|
||||
|
|
@ -20991,6 +21028,7 @@ Sensor_Temperature:MCP9501
|
|||
Sensor_Temperature:MCP9502
|
||||
Sensor_Temperature:MCP9503
|
||||
Sensor_Temperature:MCP9504
|
||||
Sensor_Temperature:MCP96xx01x-x-MX
|
||||
Sensor_Temperature:MCP9700Ax-ELT
|
||||
Sensor_Temperature:MCP9700Ax-ETT
|
||||
Sensor_Temperature:MCP9700Ax-HLT
|
||||
|
|
@ -22481,6 +22519,7 @@ Transistor_FET_Other:Q_NMOS_Depletion_GDS
|
|||
Transistor_FET_Other:Q_NMOS_Depletion_GSD
|
||||
Transistor_FET_Other:Q_NMOS_Depletion_SDG
|
||||
Transistor_FET_Other:Q_NMOS_Depletion_SGD
|
||||
Transistor_FET_Other:SP010N70T8
|
||||
Transistor_FET_Other:VNB35N07xx-E
|
||||
Transistor_FET_Other:VNP10N07
|
||||
Transistor_FET_Other:VNP35N07xx-E
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ class AttachmentFileController extends AbstractController
|
|||
//Set header content disposition, so that the file will be downloaded
|
||||
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $attachment->getFilename());
|
||||
|
||||
$this->setAttachmentCSPHeaders($response);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
|
@ -112,6 +114,16 @@ class AttachmentFileController extends AbstractController
|
|||
//Set header content disposition, so that the file will be downloaded
|
||||
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE, $attachment->getFilename());
|
||||
|
||||
$this->setAttachmentCSPHeaders($response);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function setAttachmentCSPHeaders(Response $response): Response
|
||||
{
|
||||
//Set an CSP that disallow to run any scripts, styles or images from the attachment render page, as it is not used anywhere else for now and can be a security risk if used without proper precautions, so it should be opt-in
|
||||
$response->headers->set('Content-Security-Policy', "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; sandbox;");
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||
namespace App\Services\AI;
|
||||
|
||||
use App\Settings\AISettings\LMStudioSettings;
|
||||
use App\Settings\AISettings\OllamaSettings;
|
||||
use App\Settings\AISettings\OpenRouterSettings;
|
||||
use Symfony\Contracts\Translation\TranslatableInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
|
@ -32,6 +33,7 @@ enum AIPlatforms: string implements TranslatableInterface
|
|||
{
|
||||
case OPENROUTER = 'openrouter';
|
||||
case LMSTUDIO = 'lmstudio';
|
||||
case OLLAMA = 'ollama';
|
||||
|
||||
/**
|
||||
* Returns the name attribute of the service tag for this platform, which is used to register the platform in the AIPlatformRegistry
|
||||
|
|
@ -52,6 +54,7 @@ enum AIPlatforms: string implements TranslatableInterface
|
|||
return match ($this) {
|
||||
self::LMSTUDIO => LMStudioSettings::class,
|
||||
self::OPENROUTER => OpenRouterSettings::class,
|
||||
self::OLLAMA => OllamaSettings::class,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -543,8 +543,10 @@ class AttachmentSubmitHandler
|
|||
return $attachment;
|
||||
}
|
||||
|
||||
$guessed_mime_type = $this->mimeTypes->guessMimeType($path);
|
||||
|
||||
//Check if the file is an SVG
|
||||
if ($attachment->getExtension() === "svg") {
|
||||
if ($guessed_mime_type === "image/svg+xml" || $attachment->getExtension() === "svg") {
|
||||
$this->SVGSanitizer->sanitizeFile($path);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,4 +40,7 @@ class AISettings
|
|||
|
||||
#[EmbeddedSettings]
|
||||
public ?LMStudioSettings $lmstudio = null;
|
||||
|
||||
#[EmbeddedSettings]
|
||||
public ?OllamaSettings $ollama = null;
|
||||
}
|
||||
|
|
|
|||
58
src/Settings/AISettings/OllamaSettings.php
Normal file
58
src/Settings/AISettings/OllamaSettings.php
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program 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/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Settings\AISettings;
|
||||
|
||||
use App\Form\Type\APIKeyType;
|
||||
use App\Services\AI\AIPlatformSettingsInterface;
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||
use Symfony\Component\Form\Extension\Core\Type\UrlType;
|
||||
use Symfony\Component\Translation\StaticMessage;
|
||||
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||
|
||||
#[Settings(name: 'ai_ollama', label: new TM("settings.ai.ollama"))]
|
||||
#[SettingsIcon("fa-robot")]
|
||||
class OllamaSettings implements AIPlatformSettingsInterface
|
||||
{
|
||||
use SettingsTrait;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ai.ollama.endpoint"),
|
||||
formType: UrlType::class,
|
||||
formOptions: ["attr" => ["placeholder" => new StaticMessage("http://localhost:11434")]],
|
||||
envVar: "AI_OLLAMA_ENDPOINT", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
public ?string $endpoint = null;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ai.ollama.apiKey"),
|
||||
formType: APIKeyType::class,
|
||||
envVar: "AI_OLLAMA_API_KEY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
public ?string $apiKey = null;
|
||||
|
||||
public function isAIPlatformEnabled(): bool
|
||||
{
|
||||
return $this->endpoint !== null && $this->endpoint !== "";
|
||||
}
|
||||
}
|
||||
12
symfony.lock
12
symfony.lock
|
|
@ -411,6 +411,18 @@
|
|||
"config/packages/ai_lm_studio_platform.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/ai-ollama-platform": {
|
||||
"version": "0.10",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "0.1",
|
||||
"ref": "2f0ac0a8bc59c4e46b47a962a3ad7fe8104457d6"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/ai_ollama_platform.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/ai-open-router-platform": {
|
||||
"version": "0.8",
|
||||
"recipe": {
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Jdi!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Zrušit</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Ne</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Kom nu!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Annuller</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Nej</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Los!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Abbrechen</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Nein</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -7,5 +7,23 @@
|
|||
<target>Αναζήτηση</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Ακύρωση</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Όχι</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
@ -55,5 +55,29 @@
|
|||
<target>Go!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="8d38e7538" name="user.password_strength.crack_time">
|
||||
<segment state="translated">
|
||||
<source>user.password_strength.crack_time</source>
|
||||
<target>Estimated time to crack: %time%</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Cancel</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>No</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>¡Vamos!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Cancelar</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>No</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Rechercher !</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Annuler</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Non</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Indítás!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Mégse</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Nem</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Cerca!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Annulla</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>No</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -19,5 +19,23 @@
|
|||
<target>検索</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>キャンセル</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>いいえ</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Ga!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Annuleren</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Nee</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Idź!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Anuluj</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Nie</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Vá!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>OK</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Cancelar</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Não</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Поехали!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>ОК</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Отмена</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Нет</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>Почати!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>ОК</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>Скасувати</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>Ні</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,23 @@
|
|||
<target>GO!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnOk01" name="dialog.btn.ok">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.ok</source>
|
||||
<target>确定</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnCcl1" name="dialog.btn.cancel">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.cancel</source>
|
||||
<target>取消</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dBtnDny1" name="dialog.btn.deny">
|
||||
<segment state="translated">
|
||||
<source>dialog.btn.deny</source>
|
||||
<target>否</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ The user will have to set up all two-factor authentication methods again and pri
|
|||
<unit id="BtSvnI0" name="entity.delete.confirm_title">
|
||||
<segment state="translated">
|
||||
<source>entity.delete.confirm_title</source>
|
||||
<target>You really want to delete %name%?</target>
|
||||
<target>Do you really want to delete %name%?</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="WR9DNyZ" name="entity.delete.message">
|
||||
|
|
@ -13619,6 +13619,24 @@ Buerklin-API Authentication server:
|
|||
<target>Host URL</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="UeFbCNh" name="settings.ai.ollama">
|
||||
<segment state="translated">
|
||||
<source>settings.ai.ollama</source>
|
||||
<target>Ollama</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="9nfJ_vr" name="settings.ai.ollama.endpoint">
|
||||
<segment state="translated">
|
||||
<source>settings.ai.ollama.endpoint</source>
|
||||
<target>Endpoint URL</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="67dSwE5" name="settings.ai.ollama.apiKey">
|
||||
<segment state="translated">
|
||||
<source>settings.ai.ollama.apiKey</source>
|
||||
<target>API Key</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="kuDv.So" name="browser_plugin.recent_pages.title">
|
||||
<segment state="translated">
|
||||
<source>browser_plugin.recent_pages.title</source>
|
||||
|
|
|
|||
|
|
@ -119,7 +119,14 @@ Encore
|
|||
// requires WebpackEncoreBundle 1.4 or higher
|
||||
.enableIntegrityHashes(Encore.isProduction())
|
||||
|
||||
// uncomment if you're having problems with a jQuery plugin
|
||||
// Force all jquery imports to the UMD build so webpack always receives the
|
||||
// jQuery function directly instead of an ESM namespace object. Without this,
|
||||
// webpack's ESM interop wraps jquery.module.js in a namespace
|
||||
// { default, jQuery, $ } which has no .fn, crashing Bootstrap's
|
||||
// defineJQueryPlugin when it tries to access $.fn.alert.
|
||||
.addAliases({
|
||||
'jquery': path.resolve(__dirname, 'node_modules/jquery/dist/jquery.js')
|
||||
})
|
||||
.autoProvidejQuery()
|
||||
|
||||
|
||||
|
|
@ -142,7 +149,7 @@ Encore
|
|||
;
|
||||
|
||||
//These are all the themes that are available in bootswatch
|
||||
const AVAILABLE_THEMES = ['bootstrap', 'cerulean', 'cosmo', 'cyborg', 'darkly', 'flatly', 'journal',
|
||||
const AVAILABLE_THEMES = ['bootstrap', 'brite', 'cerulean', 'cosmo', 'cyborg', 'darkly', 'flatly', 'journal',
|
||||
'litera', 'lumen', 'lux', 'materia', 'minty', 'morph', 'pulse', 'quartz', 'sandstone', 'simplex', 'sketchy', 'slate', 'solar',
|
||||
'spacelab', 'superhero', 'united', 'vapor', 'yeti', 'zephyr'];
|
||||
|
||||
|
|
|
|||
188
yarn.lock
188
yarn.lock
|
|
@ -1887,11 +1887,11 @@
|
|||
integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==
|
||||
|
||||
"@types/node@*":
|
||||
version "25.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-25.9.3.tgz#11dfe7a33e68fa5c560f0aa76cc5595621ef26b9"
|
||||
integrity sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==
|
||||
version "26.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-26.0.0.tgz#d4aece9e9412e9f2008d59bc2d74f5279316b665"
|
||||
integrity sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA==
|
||||
dependencies:
|
||||
undici-types ">=7.24.0 <7.24.7"
|
||||
undici-types "~8.3.0"
|
||||
|
||||
"@types/trusted-types@^2.0.7":
|
||||
version "2.0.7"
|
||||
|
|
@ -2071,37 +2071,66 @@
|
|||
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
|
||||
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
|
||||
|
||||
"@zxcvbn-ts/core@^3.0.2":
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/core/-/core-3.0.4.tgz#c5bde72235eb6c273cec78b672bb47c0d7045cad"
|
||||
integrity sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==
|
||||
"@zxcvbn-ts/core@^4.1.2":
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/core/-/core-4.1.2.tgz#2d280f3d1a558201cf34080c4d7de335afd4cc4a"
|
||||
integrity sha512-RQmxWB3AMI+HGQErQdUv6Aq32aQhp6xOxrfgCP0+T9MsLZoP3xtLHuT8O8VojsUxdmQVZfJlYkYb1A0wOwIS+Q==
|
||||
dependencies:
|
||||
fastest-levenshtein "1.0.16"
|
||||
|
||||
"@zxcvbn-ts/language-common@^3.0.3":
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-common/-/language-common-3.0.4.tgz#fa1d2a42f8c8a589555859795da90d6b8027b7c4"
|
||||
integrity sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==
|
||||
"@zxcvbn-ts/dictionary-compression@^3.0.1":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/dictionary-compression/-/dictionary-compression-3.0.1.tgz#f357ad46e08fff8ba92f6f163d6b38b9533fc849"
|
||||
integrity sha512-p3KyPzxGc3vWSap5hHA6SllbUCmh7s+NtpGyC3qEWrxYJT9t9TUAzjPm48Okipo+UUyPQfDlIvTcs9JRShBFiQ==
|
||||
|
||||
"@zxcvbn-ts/language-de@^3.0.1":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-de/-/language-de-3.0.2.tgz#fbd0d1be9454e308bbd63bf5487d4c17670094f0"
|
||||
integrity sha512-CPl2314qWtnJl4EkeEqFbL4unP6yEAHO976ER+df8CQcKsF4FxdZYEahkleWU66dhNI2VKnmJKNMzq8QtHQKcw==
|
||||
"@zxcvbn-ts/language-common@^4.1.2":
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-common/-/language-common-4.1.2.tgz#c38c52500865d3a2ab7fa1193d747dafc4f2b995"
|
||||
integrity sha512-uJlBzhC9/KjPImqdnc1/lPxmdn4xKbkruN5p1mASWkXA0gli+GZ5LrVL+dqscA8Pcf4OfudE56TtCWeHljJOvA==
|
||||
dependencies:
|
||||
"@zxcvbn-ts/dictionary-compression" "^3.0.1"
|
||||
|
||||
"@zxcvbn-ts/language-en@^3.0.1":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-en/-/language-en-3.0.2.tgz#162ada6b2b556444efd5a7700e70845cfde6d6ec"
|
||||
integrity sha512-Zp+zL+I6Un2Bj0tRXNs6VUBq3Djt+hwTwUz4dkt2qgsQz47U0/XthZ4ULrT/RxjwJRl5LwiaKOOZeOtmixHnjg==
|
||||
"@zxcvbn-ts/language-de@^4.1.1":
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-de/-/language-de-4.1.1.tgz#c6a91f43119fdedefe35b7049c8e4f7af9dd88fa"
|
||||
integrity sha512-ig4zeCxg4yp5VU4/Iuq5CCHLJtbmHjczK87HKw/K2jYkpk1s7C4jRi+n3XgcPNRP71nvTxGhpPWWlsziCnm5xA==
|
||||
dependencies:
|
||||
"@zxcvbn-ts/dictionary-compression" "^3.0.1"
|
||||
|
||||
"@zxcvbn-ts/language-fr@^3.0.1":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-fr/-/language-fr-3.0.2.tgz#79c5f0475fd388502f04f5560456db37dc0dde35"
|
||||
integrity sha512-Tj9jS/Z8mNBAD21pn8Mp4O86CPrwImysO1fM3DG+fsfk8W79/MDzqpFDBHiqpu69Uo3LPPctMHEEteakFWt4Qg==
|
||||
"@zxcvbn-ts/language-en@^4.1.1":
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-en/-/language-en-4.1.1.tgz#20ca499affb4d6972d777ec04bb0c786d33add73"
|
||||
integrity sha512-6UdzuBd3Uex8TKubohcn+uXRVAH34Zjs2eCfT4hQVo9zeTy7AkQRQfdV4OnHR5hQfW/XBrK/AGTZk7VBWh7wwQ==
|
||||
dependencies:
|
||||
"@zxcvbn-ts/dictionary-compression" "^3.0.1"
|
||||
|
||||
"@zxcvbn-ts/language-ja@^3.0.1":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-ja/-/language-ja-3.0.2.tgz#299bb6f5465f99405577491b1b31352058540c76"
|
||||
integrity sha512-YjQyt+eMe3EdpeJiSt81AMF8HfEXXCary/VRoG+0erZBzRjfJ1U3JdSiu9wFFxiEF8Cb5FEmTQ6nQPyraezH6Q==
|
||||
"@zxcvbn-ts/language-fr@^4.1.1":
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-fr/-/language-fr-4.1.1.tgz#7d1eccaad7b4dbfe31efe018e9239893bdc33bc8"
|
||||
integrity sha512-5LW8KMiXLWKG6fTv/BdQbe76sa2EjYmvd59sM3Re+hZMGYEPOdjnAT5qFChQ2Zj8WIaU3P197Y6A0X8OgfoiqQ==
|
||||
dependencies:
|
||||
"@zxcvbn-ts/dictionary-compression" "^3.0.1"
|
||||
|
||||
"@zxcvbn-ts/language-it@^4.1.1":
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-it/-/language-it-4.1.1.tgz#b6fda40099e85a4fc1c5d14d75c9de8a304dd061"
|
||||
integrity sha512-YxKCBO1rKuCMPYRyOxfUZA+3ju8OO8W9Qx8h/vHrHvuGIavK7L+fgXTUrhjHU8M+zE0pQZxS4wOdfgLFZaP57w==
|
||||
dependencies:
|
||||
"@zxcvbn-ts/dictionary-compression" "^3.0.1"
|
||||
|
||||
"@zxcvbn-ts/language-ja@^4.1.1":
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-ja/-/language-ja-4.1.1.tgz#acd36abe4f6083dceda22771148d0948e0e421d9"
|
||||
integrity sha512-ZDFUZfm7hlmuiHOMLq7p85wE3Pa7s1WXixU6X+POTuRTjGwXi4LMtiS9wli7zXTEvxSUMdVWBx5ZgyIF6D0S8A==
|
||||
dependencies:
|
||||
"@zxcvbn-ts/dictionary-compression" "^3.0.1"
|
||||
|
||||
"@zxcvbn-ts/language-pl@^4.1.1":
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-pl/-/language-pl-4.1.1.tgz#627d4c365a69e3f78d3e2b6e9667d1b57b6cc1ff"
|
||||
integrity sha512-hF6Qu9cyHx7sSEzNOQrJQntq8geoincsGvlOC0wkD43LnUVSTR49MKxdsifsemlQgtxR7aUKDgK/e/RFHOljoQ==
|
||||
dependencies:
|
||||
"@zxcvbn-ts/dictionary-compression" "^3.0.1"
|
||||
|
||||
acorn-import-phases@^1.0.3:
|
||||
version "1.0.4"
|
||||
|
|
@ -2223,9 +2252,9 @@ base64-js@^1.1.2, base64-js@^1.3.0:
|
|||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
baseline-browser-mapping@^2.10.12:
|
||||
version "2.10.37"
|
||||
resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.37.tgz#3e636475b6b293244e2b23e2c71a2ab9d9e6ba7d"
|
||||
integrity sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==
|
||||
version "2.10.38"
|
||||
resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.38.tgz#c84d093c4bf7325c5053c279d90f153c66526042"
|
||||
integrity sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==
|
||||
|
||||
big.js@^5.2.2:
|
||||
version "5.2.2"
|
||||
|
|
@ -2242,11 +2271,6 @@ boolbase@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
|
||||
|
||||
bootbox@^6.0.0:
|
||||
version "6.0.4"
|
||||
resolved "https://registry.yarnpkg.com/bootbox/-/bootbox-6.0.4.tgz#005f12d712da5d5723a13a0495e5fc4ad2cc1472"
|
||||
integrity sha512-LoOT8WbiH6YjlhIxzJ3nZHK1p9tlcoa6QNILSGJMx9ihydzFk+DVzNVWNpHk8MZLOkizey1XhFu1dhoqk77xVg==
|
||||
|
||||
bootstrap@^5.1.3:
|
||||
version "5.3.8"
|
||||
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.8.tgz#6401a10057a22752d21f4e19055508980656aeed"
|
||||
|
|
@ -2507,13 +2531,13 @@ commander@^8.3.0:
|
|||
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
|
||||
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
|
||||
|
||||
compression-webpack-plugin@^11.1.0:
|
||||
version "11.1.0"
|
||||
resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-11.1.0.tgz#ee340d2029cf99ccecdea9ad1410b377d15b48b3"
|
||||
integrity sha512-zDOQYp10+upzLxW+VRSjEpRRwBXJdsb5lBMlRxx1g8hckIFBpe3DTI0en2w7h+beuq89576RVzfiXrkdPGrHhA==
|
||||
compression-webpack-plugin@^12.0.0:
|
||||
version "12.0.0"
|
||||
resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-12.0.0.tgz#6842bb3720407afb0686500411c765c37f37164d"
|
||||
integrity sha512-LR4mS19Jqq41XfA3xVMLrtzVNzqJbUHdzPeLRfQoLiAS9s87f0021fDuU89xxVQFcB6d20ufBkv4j1rQ4OowHw==
|
||||
dependencies:
|
||||
schema-utils "^4.2.0"
|
||||
serialize-javascript "^6.0.2"
|
||||
serialize-javascript "^7.0.3"
|
||||
|
||||
consola@^3.2.3:
|
||||
version "3.4.2"
|
||||
|
|
@ -2877,9 +2901,9 @@ domhandler@^5.0.2, domhandler@^5.0.3:
|
|||
domelementtype "^2.3.0"
|
||||
|
||||
dompurify@^3.0.3:
|
||||
version "3.4.10"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.10.tgz#96704295b4d8aeefcc8c7a90caa579b0ad69e46a"
|
||||
integrity sha512-0xzNv0e7oYC6yyuOGZIABPM4qtg3QxLFniDNPP4ZP90wR8Yq3zgwpRbrNiT4N3IKqDbbYFEJLV+JWEs19aZ//w==
|
||||
version "3.4.11"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.11.tgz#29c8ba496475f279ef4015784068452fb14a0680"
|
||||
integrity sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw==
|
||||
optionalDependencies:
|
||||
"@types/trusted-types" "^2.0.7"
|
||||
|
||||
|
|
@ -2902,9 +2926,9 @@ domutils@^3.0.1:
|
|||
domhandler "^5.0.3"
|
||||
|
||||
electron-to-chromium@^1.5.328:
|
||||
version "1.5.372"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.372.tgz#ae8ac69942a37b231773b8fb01759f73733599e3"
|
||||
integrity sha512-M3yhbAlilnwqC8D21t28UCDGHyitShTmmLRU/H+b74P6Ski16Nb9HONYEaVpMj/pwC7BEo5B95FpjODLCWbtfA==
|
||||
version "1.5.376"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.376.tgz#16a9d4b72cb16c416aa73a879d92b047b96797ac"
|
||||
integrity sha512-cUVA7/RvbFTEuw/i3obUwDTRIXojaxkResf+ibByPFxjc6XK3VNtcQXV0NSbAlJ0FMjcJGgftVVB4Qo184EXvA==
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
|
|
@ -3427,10 +3451,10 @@ jest-worker@^30.0.5:
|
|||
merge-stream "^2.0.0"
|
||||
supports-color "^8.1.1"
|
||||
|
||||
jquery@>=1.7, jquery@^3.5.1:
|
||||
version "3.7.1"
|
||||
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de"
|
||||
integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==
|
||||
jquery@>=1.7, jquery@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jquery/-/jquery-4.0.0.tgz#95c33ac29005ff72ec444c5ba1cf457e61404fbb"
|
||||
integrity sha512-TXCHVR3Lb6TZdtw1l3RTLf8RBWVGexdxL6AC8/e0xZKEpBflBsjh9/8LXw+dkNFuOyW9B7iB3O1sP7hS0Kiacg==
|
||||
|
||||
js-md5@^0.8.3:
|
||||
version "0.8.3"
|
||||
|
|
@ -4057,9 +4081,9 @@ ms@^2.1.3:
|
|||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
nanoid@^3.3.12:
|
||||
version "3.3.12"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.12.tgz#ab3d912e217a6d0a514f00a72a16543a28982c05"
|
||||
integrity sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==
|
||||
version "3.3.14"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.14.tgz#02d7e019f05dd8eeee2779c6f42206c06542ab33"
|
||||
integrity sha512-U9kYi5bpVMEI31yC8iw4bJJp0avcHXA0W8/wNfLfnvJYzihQo2ZRPYPvpAAd570HAcCBjCTN7vnr+v4StKl1IQ==
|
||||
|
||||
neo-async@^2.6.2:
|
||||
version "2.6.2"
|
||||
|
|
@ -4079,9 +4103,9 @@ node-notifier@^9.0.0:
|
|||
which "^2.0.2"
|
||||
|
||||
node-releases@^2.0.36:
|
||||
version "2.0.47"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.47.tgz#521bb2786da8eb140b748841c0b3b3a75334ffc4"
|
||||
integrity sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==
|
||||
version "2.0.48"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.48.tgz#4da73d040ada751fc9959d993f27de48792e3b7d"
|
||||
integrity sha512-1uz8041X6LoI6ZSdZacM9lVY28vuzDlSKitnpbSNK0RfKoIJkX29NBPVEFXhnuSuEOA9Ww0xnPJ+ILWbGAv8DA==
|
||||
|
||||
nth-check@^2.0.1:
|
||||
version "2.1.1"
|
||||
|
|
@ -4482,13 +4506,6 @@ property-information@^7.0.0:
|
|||
resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.2.0.tgz#0809b34264e995c0bfcd3227028a1e35210af80a"
|
||||
integrity sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==
|
||||
|
||||
randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
|
||||
dependencies:
|
||||
safe-buffer "^5.1.0"
|
||||
|
||||
readable-stream@~2.3.6:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
|
||||
|
|
@ -4697,11 +4714,6 @@ restructure@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/restructure/-/restructure-3.0.2.tgz#e6b2fad214f78edee21797fa8160fef50eb9b49a"
|
||||
integrity sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==
|
||||
|
||||
safe-buffer@^5.1.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
|
|
@ -4733,21 +4745,14 @@ semver@^6.3.1:
|
|||
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||
|
||||
semver@^7.3.2, semver@^7.3.4, semver@^7.6.3:
|
||||
version "7.8.4"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.4.tgz#c73eceebae0616934be8dff28a7fd70757c8e696"
|
||||
integrity sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==
|
||||
|
||||
serialize-javascript@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2"
|
||||
integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==
|
||||
dependencies:
|
||||
randombytes "^2.1.0"
|
||||
version "7.8.5"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.5.tgz#39b646037dd50c14fb451e7e4cac58ed8b863f69"
|
||||
integrity sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==
|
||||
|
||||
serialize-javascript@^7.0.3:
|
||||
version "7.0.5"
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-7.0.5.tgz#c798cc0552ffbb08981914a42a8756e339d0d5b1"
|
||||
integrity sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==
|
||||
version "7.0.6"
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-7.0.6.tgz#f2f20c8af0757e4d8fa329d0210636da0682ddef"
|
||||
integrity sha512-ATTK5Q4gFVg0YDp1my2vqygyvhcklD/UV5GIlYHooGTn/NogJqIzpetkD6E5kmuVULqz/S9inUL25XcAgDRJQg==
|
||||
|
||||
setimmediate@^1.0.5:
|
||||
version "1.0.5"
|
||||
|
|
@ -4906,6 +4911,11 @@ svgo@^4.0.1:
|
|||
picocolors "^1.1.1"
|
||||
sax "^1.5.0"
|
||||
|
||||
sweetalert2@^11.26.25:
|
||||
version "11.26.25"
|
||||
resolved "https://registry.yarnpkg.com/sweetalert2/-/sweetalert2-11.26.25.tgz#ba24ffb79c67648ac51f834620baa15866a56e35"
|
||||
integrity sha512-+hunCOJdJ6FLj04T9YSLvvZXRjsvIkTeTKP2e4VF8CaBias961BTnWiSFAy7F/CM5eq3QK2Rraoc5Gzftslvkg==
|
||||
|
||||
tagged-tag@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tagged-tag/-/tagged-tag-1.0.0.tgz#a0b5917c2864cba54841495abfa3f6b13edcf4d6"
|
||||
|
|
@ -4987,9 +4997,9 @@ trough@^2.0.0:
|
|||
integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==
|
||||
|
||||
ts-loader@^9.2.6:
|
||||
version "9.6.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.6.0.tgz#50dfdea9c63ff9c5f4e89b04c1e3ce0d5d2946a1"
|
||||
integrity sha512-dsJO0S+T7grTDWTc4a0nTygXGjKncVUpx8Y+af8EvI/D5WgTJby5UEk5eoMCB9EcLQmnvitqh99MqtjtHgAwFQ==
|
||||
version "9.6.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.6.1.tgz#4a5e87a24c2f9f0e6f1fee3e844e4591f2628e55"
|
||||
integrity sha512-8FMHnmxtpncUAu0ZjkqpXnOTlwc9eY95esH8WVN94guTPPdkg2ofVdiVM5j8L2lmjiGerXd56zXb/D2JyVQPLg==
|
||||
dependencies:
|
||||
chalk "^4.1.0"
|
||||
enhanced-resolve "^5.0.0"
|
||||
|
|
@ -5014,10 +5024,10 @@ typescript@^6.0.2:
|
|||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-6.0.3.tgz#90251dc007916e972786cb94d74d15b185577d21"
|
||||
integrity sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==
|
||||
|
||||
"undici-types@>=7.24.0 <7.24.7":
|
||||
version "7.24.6"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.24.6.tgz#61275b485d7fd4e9d269c7cf04ec2873c9cc0f91"
|
||||
integrity sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==
|
||||
undici-types@~8.3.0:
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-8.3.0.tgz#44e9fc9f3244648cdea35e4f9bb2d681e9410809"
|
||||
integrity sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==
|
||||
|
||||
unicode-canonical-property-names-ecmascript@^2.0.0:
|
||||
version "2.0.1"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue