Skip to content
Snippets Groups Projects
Verified Commit f8505445 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

chore: update nix, node, code format

parent 798ac427
No related branches found
No related tags found
No related merge requests found
Showing
with 3790 additions and 3351 deletions
export const projectRoot = "/home/vs/workspaces/oss/monster/monster";
export const sourcePath = "/home/vs/workspaces/oss/monster/monster/source";
export const developmentPath = "/home/vs/workspaces/oss/monster/monster/development";
export const pnpxBin = "/nix/store/aik0qrmx9wxy1q480lfwqv1wqsrhcsl8-pnpm-9.15.3/bin/pnpx";
export const nodeBin = "/nix/store/l9vrjjavsgf5b5ypp5m9qcqnivsjpgbf-nodejs-22.13.1/bin/node";
export const pnpxBin = "/nix/store/sxw7i3pyw8v1ycw2sph0zq2byh1prrwm-nodejs-20.18.1/bin/npx";
export const nodeBin = "/nix/store/95gnwih6qz9w2iahacfq9awadby19n3k-nodejs-23.6.1/bin/node";
export const license = "/**" + "\n" +
" * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved." + "\n" +
" * Node module: @schukai/monster" + "\n" +
......
......@@ -3,4 +3,4 @@
commit = "5d3c01f0835707cfffb4c3b5e81722be309a9e75";
name = "Monster";
mnemonic = "monster";
}
\ No newline at end of file
}
......@@ -10,7 +10,7 @@ in
echo_step "Installing dependencies"
if ! ${pkgs'.findutils}/bin/find . -type d -name node_modules -prune -o -type f -name package.json -print | ${pkgs'.findutils}/bin/xargs -I {} sh -c "cd $(dirname {}); ${pkgs'.projectCorepack}/bin/npm install"
if ! ${pkgs'.findutils}/bin/find . -type d -name node_modules -prune -o -type f -name package.json -print | ${pkgs'.findutils}/bin/xargs -I {} sh -c "cd $(dirname {}); ${pkgs'.projectNodeJS}/bin/npm install"
then
echo_error "Failed to install dependencies"
echo_hint "Check the error message and try again"
......
......@@ -19,7 +19,7 @@ in
echo_step "Installing dependencies (node)"
if ! ${pkgs'.findutils}/bin/find . -type d -name node_modules -prune -o -type f -name package.json -print | ${pkgs'.findutils}/bin/xargs -I {} sh -c "cd $(dirname {}); ${pkgs'.projectCorepack}/bin/npm install"
if ! ${pkgs'.findutils}/bin/find . -type d -name node_modules -prune -o -type f -name package.json -print | ${pkgs'.findutils}/bin/xargs -I {} sh -c "cd $(dirname {}); ${pkgs'.projectNodeJS}/bin/npm install"
then
echo_error "Failed to install dependencies"
echo_hint "Check the error message and try again"
......
This diff is collapsed.
......@@ -41,7 +41,8 @@
"license": "AGPL 3.0",
"dependencies": {
"@floating-ui/dom": "^1.6.13",
"@popperjs/core": "^2.11.8"
"@popperjs/core": "^2.11.8",
"buffer": "^6.0.3"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
......@@ -59,10 +60,10 @@
"cssnano": "^7.0.6",
"dom-storage": "^2.1.0",
"element-internals-polyfill": "^1.3.13",
"esbuild": "^0.24.2",
"esbuild": "^0.25.0",
"espree": "^10.3.0",
"estraverse": "^5.3.0",
"flow-bin": "^0.259.1",
"flow-bin": "^0.260.0",
"fs": "0.0.1-security",
"glob": "^11.0.1",
"graphviz": "^0.0.9",
......@@ -70,7 +71,7 @@
"jsdom-global": "^3.0.2",
"mocha": "^11.1.0",
"playwright": "^1.50.1",
"postcss": "^8.5.1",
"postcss": "^8.5.2",
"postcss-fluid": "^1.4.2",
"postcss-for": "^2.1.1",
"postcss-import": "^16.1.0",
......@@ -82,7 +83,7 @@
"postcss-responsive-type": "^1.0.0",
"postcss-rtlcss": "^5.6.0",
"postcss-strip-units": "^2.0.1",
"puppeteer": "^24.1.1",
"puppeteer": "^24.2.0",
"sinon": "^19.0.2",
"turbowatch": "^2.29.4",
"url": "^0.11.4",
......
......@@ -32,7 +32,13 @@ import { Settings } from "./filter/settings.mjs";
import { FilterStyleSheet } from "./stylesheet/filter.mjs";
import { getDocument, getWindow } from "../../dom/util.mjs";
import { getGlobal } from "../../types/global.mjs";
import {isInstance, isFunction, isObject, isArray, isString} from "../../types/is.mjs";
import {
isInstance,
isFunction,
isObject,
isArray,
isString,
} from "../../types/is.mjs";
import { Host } from "../host/host.mjs";
import { addAttributeToken } from "../../dom/attributes.mjs";
import { ATTRIBUTE_ERRORMESSAGE } from "../../dom/constants.mjs";
......@@ -1063,8 +1069,10 @@ function doSearch({ showEffect } = { showEffect: true }) {
return Promise.reject(new Error(msg));
}
if (this.getOption("features.preventSameQuery") &&
buildQuery === this.getOption("query")) {
if (
this.getOption("features.preventSameQuery") &&
buildQuery === this.getOption("query")
) {
const msg = this.getOption("labels.query-not-changed");
if (showEffect) {
......@@ -1205,8 +1213,7 @@ function collectSearchQueries() {
});
},
"tag-list": (value, key) => {
if(isString(value)) {
if (isString(value)) {
value = value.split(",");
}
......@@ -1214,11 +1221,15 @@ function collectSearchQueries() {
return "";
}
return key+" IN "+value
.map((v) => {
return `"${encodeURIComponent(v)}"`;
})
.join(",");
return (
key +
" IN " +
value
.map((v) => {
return `"${encodeURIComponent(v)}"`;
})
.join(",")
);
},
"date-range": (value, key) => {
const query = parseDateInput(value, key);
......
......@@ -129,7 +129,6 @@ class SaveButton extends CustomElement {
disabled: false,
logLevel: "off",
});
updateOptionsFromArguments.call(this, obj);
......@@ -204,18 +203,18 @@ class SaveButton extends CustomElement {
const ignoreChanges = self.getOption("ignoreChanges");
const result = diff(self[originValuesSymbol], currentValues);
if(self.getOption("logLevel") === "debug") {
if (self.getOption("logLevel") === "debug") {
console.groupCollapsed("SaveButton");
console.log(result);
if(isArray(result)&&result.length>0) {
const formattedDiff = result.map(change => ({
if (isArray(result) && result.length > 0) {
const formattedDiff = result.map((change) => ({
Operator: change?.operator,
Path: change?.path?.join("."),
"First Value": change?.first?.value,
"First Type": change?.first?.type,
"Second Value": change?.second?.value,
"Second Type": change?.second?.type
"Second Type": change?.second?.type,
}));
console.table(formattedDiff);
......@@ -223,7 +222,6 @@ class SaveButton extends CustomElement {
console.log("There are no changes to save");
}
console.groupEnd();
}
if (isArray(ignoreChanges) && ignoreChanges.length > 0) {
......@@ -359,9 +357,9 @@ function initControlReferences() {
changed: new State(
"changed",
'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cloud-arrow-up" viewBox="0 0 16 16">' +
'<path fill-rule="evenodd" d="M7.646 5.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 6.707V10.5a.5.5 0 0 1-1 0V6.707L6.354 7.854a.5.5 0 1 1-.708-.708z"/>' +
'<path d="M4.406 3.342A5.53 5.53 0 0 1 8 2c2.69 0 4.923 2 5.166 4.579C14.758 6.804 16 8.137 16 9.773 16 11.569 14.502 13 12.687 13H3.781C1.708 13 0 11.366 0 9.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383m.653.757c-.757.653-1.153 1.44-1.153 2.056v.448l-.445.049C2.064 6.805 1 7.952 1 9.318 1 10.785 2.23 12 3.781 12h8.906C13.98 12 15 10.988 15 9.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 4.825 10.328 3 8 3a4.53 4.53 0 0 0-2.941 1.1z"/>' +
"</svg>",
'<path fill-rule="evenodd" d="M7.646 5.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 6.707V10.5a.5.5 0 0 1-1 0V6.707L6.354 7.854a.5.5 0 1 1-.708-.708z"/>' +
'<path d="M4.406 3.342A5.53 5.53 0 0 1 8 2c2.69 0 4.923 2 5.166 4.579C14.758 6.804 16 8.137 16 9.773 16 11.569 14.502 13 12.687 13H3.781C1.708 13 0 11.366 0 9.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383m.653.757c-.757.653-1.153 1.44-1.153 2.056v.448l-.445.049C2.064 6.805 1 7.952 1 9.318 1 10.785 2.23 12 3.781 12h8.906C13.98 12 15 10.988 15 9.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 4.825 10.328 3 8 3a4.53 4.53 0 0 0-2.941 1.1z"/>' +
"</svg>",
),
};
......@@ -433,4 +431,4 @@ function getTemplate() {
`;
}
registerCustomElement(SaveButton);
\ No newline at end of file
registerCustomElement(SaveButton);
This diff is collapsed.
This diff is collapsed.
......@@ -17,7 +17,7 @@ import { validateString } from "../types/validate.mjs";
import { clone } from "../util/clone.mjs";
import { DELIMITER, Pathfinder, WILDCARD } from "./pathfinder.mjs";
export { buildMap, PARENT, assembleParts};
export { buildMap, PARENT, assembleParts };
/**
* @type {string}
......
......@@ -19,7 +19,7 @@ import { Server } from "../server.mjs";
import { WriteError } from "./restapi/writeerror.mjs";
import { DataFetchError } from "./restapi/data-fetch-error.mjs";
import { clone } from "../../../util/clone.mjs";
import {getInternalLocalizationMessage} from "../../../i18n/internal.mjs";
import { getInternalLocalizationMessage } from "../../../i18n/internal.mjs";
export { RestAPI };
......@@ -226,7 +226,7 @@ function fetchData(init, key, callback) {
if (acceptedStatus.indexOf(resp.status) === -1) {
throw new DataFetchError(
getInternalLocalizationMessage(
`i18n{the-response-does-not-contain-an-accepted-status::status=${resp.status}}`
`i18n{the-response-does-not-contain-an-accepted-status::status=${resp.status}}`,
),
response,
);
......@@ -248,7 +248,7 @@ function fetchData(init, key, callback) {
throw new DataFetchError(
getInternalLocalizationMessage(
`i18n{the-response-does-not-contain-a-valid-json::actual=${body}}`
`i18n{the-response-does-not-contain-a-valid-json::actual=${body}}`,
),
response,
);
......
......@@ -12,120 +12,115 @@
* SPDX-License-Identifier: AGPL-3.0
*/
import {Formatter} from "./formatter.mjs";
import {getLocaleOfDocument} from "../dom/locale.mjs";
import {Translations} from "./translations.mjs";
import { Formatter } from "./formatter.mjs";
import { getLocaleOfDocument } from "../dom/locale.mjs";
import { Translations } from "./translations.mjs";
export {getInternalLocalizationMessage};
export { getInternalLocalizationMessage };
let internalTranslations = null;
getInternalTranslations();
function getInternalTranslations() {
if (internalTranslations) {
return internalTranslations;
}
let locale = "en";
try {
let locale = getLocaleOfDocument();
} catch (error) {
}
let messages = {};
switch (locale.language) {
case "de":
messages = {
"the-response-does-not-contain-an-accepted-status": `Der Server hat die Anfrage nicht akzeptiert (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `Die Antwort des Servers ist kein gültiges JSON (actual=\${actual}).`,
};
break;
case "es":
messages = {
"the-response-does-not-contain-an-accepted-status": `El servidor no ha aceptado la solicitud (Estado \${status}).`,
"the-response-does-not-contain-a-valid-json": `La respuesta del servidor no es un JSON válido (actual=\${actual}).`,
};
break;
case "zh":
messages = {
"the-response-does-not-contain-an-accepted-status": `服务器未接受请求(状态 \${status})。`,
"the-response-does-not-contain-a-valid-json": `服务器响应不是有效的JSON(实际=\${actual})。`,
};
break;
case "fr":
messages = {
"the-response-does-not-contain-an-accepted-status": `Le serveur n'a pas accepté la demande (Statut \${status}).`,
"the-response-does-not-contain-a-valid-json": `La réponse du serveur n'est pas un JSON valide (actuel=\${actual}).`,
};
break;
case "it":
messages = {
"the-response-does-not-contain-an-accepted-status": `Il server non ha accettato la richiesta (Stato \${status}).`,
"the-response-does-not-contain-a-valid-json": `La risposta del server non è un JSON valido (attuale=\${actual}).`,
};
break;
case "nl":
messages = {
"the-response-does-not-contain-an-accepted-status": `De server heeft het verzoek niet geaccepteerd (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `De serverrespons is geen geldige JSON (actueel=\${actual}).`,
};
break;
case "sv":
messages = {
"the-response-does-not-contain-an-accepted-status": `Servern accepterade inte begäran (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `Serverns svar är inte en giltig JSON (faktisk=\${actual}).`,
};
break;
case "pl":
messages = {
"the-response-does-not-contain-an-accepted-status": `Serwer nie zaakceptował żądania (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `Odpowiedź serwera nie jest prawidłowym JSON-em (aktualne=\${actual}).`,
};
break;
case "da":
messages = {
"the-response-does-not-contain-an-accepted-status": `Serveren accepterede ikke forespørgslen (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `Serverens svar er ikke en gyldig JSON (aktuel=\${actual}).`,
};
break;
case "fi":
messages = {
"the-response-does-not-contain-an-accepted-status": `Palvelin ei hyväksynyt pyyntöä (Tila \${status}).`,
"the-response-does-not-contain-a-valid-json": `Palvelimen vastaus ei ole kelvollinen JSON (todellinen=\${actual}).`,
};
break;
case "no":
messages = {
"the-response-does-not-contain-an-accepted-status": `Serveren aksepterte ikke forespørselen (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `Serverens respons er ikke en gyldig JSON (faktisk=\${actual}).`,
};
break;
case "cs":
messages = {
"the-response-does-not-contain-an-accepted-status": `Server nepřijal požadavek (Stav \${status}).`,
"the-response-does-not-contain-a-valid-json": `Odpověď serveru není platný JSON (skutečný=\${actual}).`,
};
break;
default: // English
messages = {
"the-response-does-not-contain-an-accepted-status": `The server did not accept the request (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `The server response is not a valid JSON (actual=\${actual}).`,
};
}
const translation = new Translations(locale);
translation.assignTranslations(messages);
internalTranslations = translation;
return translation
if (internalTranslations) {
return internalTranslations;
}
let locale = "en";
try {
let locale = getLocaleOfDocument();
} catch (error) {}
let messages = {};
switch (locale.language) {
case "de":
messages = {
"the-response-does-not-contain-an-accepted-status": `Der Server hat die Anfrage nicht akzeptiert (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `Die Antwort des Servers ist kein gültiges JSON (actual=\${actual}).`,
};
break;
case "es":
messages = {
"the-response-does-not-contain-an-accepted-status": `El servidor no ha aceptado la solicitud (Estado \${status}).`,
"the-response-does-not-contain-a-valid-json": `La respuesta del servidor no es un JSON válido (actual=\${actual}).`,
};
break;
case "zh":
messages = {
"the-response-does-not-contain-an-accepted-status": `服务器未接受请求(状态 \${status})。`,
"the-response-does-not-contain-a-valid-json": `服务器响应不是有效的JSON(实际=\${actual})。`,
};
break;
case "fr":
messages = {
"the-response-does-not-contain-an-accepted-status": `Le serveur n'a pas accepté la demande (Statut \${status}).`,
"the-response-does-not-contain-a-valid-json": `La réponse du serveur n'est pas un JSON valide (actuel=\${actual}).`,
};
break;
case "it":
messages = {
"the-response-does-not-contain-an-accepted-status": `Il server non ha accettato la richiesta (Stato \${status}).`,
"the-response-does-not-contain-a-valid-json": `La risposta del server non è un JSON valido (attuale=\${actual}).`,
};
break;
case "nl":
messages = {
"the-response-does-not-contain-an-accepted-status": `De server heeft het verzoek niet geaccepteerd (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `De serverrespons is geen geldige JSON (actueel=\${actual}).`,
};
break;
case "sv":
messages = {
"the-response-does-not-contain-an-accepted-status": `Servern accepterade inte begäran (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `Serverns svar är inte en giltig JSON (faktisk=\${actual}).`,
};
break;
case "pl":
messages = {
"the-response-does-not-contain-an-accepted-status": `Serwer nie zaakceptował żądania (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `Odpowiedź serwera nie jest prawidłowym JSON-em (aktualne=\${actual}).`,
};
break;
case "da":
messages = {
"the-response-does-not-contain-an-accepted-status": `Serveren accepterede ikke forespørgslen (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `Serverens svar er ikke en gyldig JSON (aktuel=\${actual}).`,
};
break;
case "fi":
messages = {
"the-response-does-not-contain-an-accepted-status": `Palvelin ei hyväksynyt pyyntöä (Tila \${status}).`,
"the-response-does-not-contain-a-valid-json": `Palvelimen vastaus ei ole kelvollinen JSON (todellinen=\${actual}).`,
};
break;
case "no":
messages = {
"the-response-does-not-contain-an-accepted-status": `Serveren aksepterte ikke forespørselen (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `Serverens respons er ikke en gyldig JSON (faktisk=\${actual}).`,
};
break;
case "cs":
messages = {
"the-response-does-not-contain-an-accepted-status": `Server nepřijal požadavek (Stav \${status}).`,
"the-response-does-not-contain-a-valid-json": `Odpověď serveru není platný JSON (skutečný=\${actual}).`,
};
break;
default: // English
messages = {
"the-response-does-not-contain-an-accepted-status": `The server did not accept the request (Status \${status}).`,
"the-response-does-not-contain-a-valid-json": `The server response is not a valid JSON (actual=\${actual}).`,
};
}
const translation = new Translations(locale);
translation.assignTranslations(messages);
internalTranslations = translation;
return translation;
}
/**
* Returns the internal localization message.
* @param message
......@@ -133,7 +128,6 @@ function getInternalTranslations() {
*/
function getInternalLocalizationMessage(message) {
const formatter = new Formatter({}, getInternalTranslations());
return formatter.format(message);
const formatter = new Formatter({}, getInternalTranslations());
return formatter.format(message);
}
......@@ -36,11 +36,9 @@ export const currentSupportedLanguages = [
"da", // Danish
"fi", // Finnish
"no", // Norwegian
"cs" // Czech
"cs", // Czech
];
export const languages = {
en: "English",
"en-GB": "English (United Kingdom)",
......
......@@ -199,6 +199,7 @@ export * from "./types/queue.mjs";
export * from "./types/noderecursiveiterator.mjs";
export * from "./i18n/time-ago.mjs";
export * from "./i18n/formatter.mjs";
export * from "./i18n/internal.mjs";
export * from "./i18n/locale.mjs";
export * from "./i18n/provider.mjs";
export * from "./i18n/providers/fetch.mjs";
......
......@@ -13,12 +13,12 @@
*/
import {
validateFunction,
validateObject,
validateString,
validateFunction,
validateObject,
validateString,
} from "./validate.mjs";
export {getGlobal, getGlobalObject, getGlobalFunction};
export { getGlobal, getGlobalObject, getGlobalFunction };
/**
* @type {object}
......@@ -31,40 +31,39 @@ let globalReference;
* @throws {Error} unsupported environment.
*/
(function () {
if (typeof globalThis === "object") {
globalReference = globalThis;
return;
}
if (typeof globalThis === "object") {
globalReference = globalThis;
return;
}
if (typeof self !== "undefined") {
globalReference = self;
return;
} else if (typeof window !== "undefined") {
globalReference = window;
return;
}
if (typeof self !== "undefined") {
globalReference = self;
return;
} else if (typeof window !== "undefined") {
globalReference = window;
return;
}
Object.defineProperty(Object.prototype, "__monster__", {
get: function () {
return this;
},
configurable: true,
});
Object.defineProperty(Object.prototype, "__monster__", {
get: function () {
return this;
},
configurable: true,
});
if (typeof __monster__ === "object") {
__monster__.globalThis = __monster__;
delete Object.prototype.__monster__;
if (typeof __monster__ === "object") {
__monster__.globalThis = __monster__;
delete Object.prototype.__monster__;
globalReference = globalThis;
return;
}
globalReference = globalThis;
return;
}
try {
globalReference = Function("return this")();
} catch (e) {
}
try {
globalReference = Function("return this")();
} catch (e) {}
throw new Error("unsupported environment.");
throw new Error("unsupported environment.");
})();
/**
......@@ -77,7 +76,7 @@ let globalReference;
* @return {object} globalThis
*/
function getGlobal() {
return globalReference;
return globalReference;
}
/**
......@@ -112,12 +111,12 @@ function getGlobal() {
* @throws {TypeError} value is not a string
*/
function getGlobalObject(name) {
validateString(name);
const o = globalReference?.[name];
if (typeof o === "undefined")
throw new Error(`the object ${name} is not defined`);
validateObject(o);
return o;
validateString(name);
const o = globalReference?.[name];
if (typeof o === "undefined")
throw new Error(`the object ${name} is not defined`);
validateObject(o);
return o;
}
/**
......@@ -150,11 +149,11 @@ function getGlobalObject(name) {
* @throws {TypeError} value is not a string
*/
function getGlobalFunction(name) {
validateString(name);
const f = globalReference?.[name];
if (typeof f === "undefined") {
throw new Error(`the function ${name} is not defined`);
}
validateFunction(f);
return f;
validateString(name);
const f = globalReference?.[name];
if (typeof f === "undefined") {
throw new Error(`the function ${name} is not defined`);
}
validateFunction(f);
return f;
}
......@@ -156,7 +156,7 @@ function getMonsterVersion() {
}
/** don't touch, replaced by make with package.json version */
monsterVersion = new Version("3.104.1");
monsterVersion = new Version("3.107.0");
return monsterVersion;
}
......@@ -7,7 +7,7 @@ describe('Monster', function () {
let monsterVersion
/** don´t touch, replaced by make with package.json version */
monsterVersion = new Version("3.104.1")
monsterVersion = new Version("3.107.0")
let m = getMonsterVersion();
......
......@@ -9,8 +9,8 @@
</head>
<body>
<div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
<h1 style='margin-bottom: 0.1em;'>Monster 3.104.1</h1>
<div id="lastupdate" style='font-size:0.7em'>last update Mi 5. Feb 19:28:33 CET 2025</div>
<h1 style='margin-bottom: 0.1em;'>Monster 3.107.0</h1>
<div id="lastupdate" style='font-size:0.7em'>last update Di 11. Feb 14:09:24 CET 2025</div>
</div>
<div id="mocha-errors"
style="color: red;font-weight: bold;display: flex;align-items: center;justify-content: center;flex-direction: column;margin:20px;"></div>
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment