Compare commits

..
Author SHA1 Message Date
Manuel d09a4f8468 chore: update cron 2026-06-19 22:08:25 +02:00
Thomas e1a245ff2d fix(auth): isolate session cookies from other Auth.js apps on same host (#5996)
Prefix all Auth.js cookies (default "homarr") so they no longer collide
with other Auth.js apps on the same hostname.
2026-06-19 21:24:15 +02:00
homarr-crowdin[bot] bf4396917e chore(lang): updated translations from crowdin (#5994)
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2026-06-19 21:22:48 +02:00
Thomas d059023b51 feat(analytics): migrate from Umami to PostHog server-side analytics (#5983)
* feat(analytics): migrate from Umami to PostHog server-side analytics

Replace @umami/node with posthog-node for all server-side telemetry.
Add singleton PostHog client, feature tracking POC, DAU heartbeat,
and tRPC analytics router. Cron job is now locked (no manual trigger,
no custom interval). Update consent copy to explain what we collect
and why.

* style: auto-fix lint and format

* refactor(analytics): simplify + add client-side posthog-js init

- Inline constants.ts and track.ts into client.ts (single source)
- Remove dead exports (shutdownPostHogAsync, getPostHogClient)
- Flatten all DB queries into one Promise.all (no waterfall)
- Derive integration/widget totals from group-by (drop redundant counts)
- Add posthog-js with dynamic import, gated on enableGeneral
- Move Analytics component to body, pass consent from server settings

* style: auto-fix lint and format

* feat(cron): add hidden flag to cron jobs, hide analytics from task panel

The analytics job runs silently in the background — users don't need
to see or interact with it. Hidden jobs are filtered out of getAllAsync
so they never appear in the management UI.

* refactor(analytics): simplify to single toggle, always collect all data

Remove granular enableWidgetData/enableIntegrationData/enableUserData
toggles. Analytics is now a single on/off switch. When enabled, all
anonymous usage data is collected in one flat Promise.all call.

Side effect: existing users with enableGeneral=true who had granular
flags off will now send all data. This is by design — the granular
controls added complexity without meaningful privacy benefit since
the data is already anonymous counts.

* style: auto-fix lint and format
2026-06-19 21:21:50 +02:00
d9cbd5427d feat: Calculate and display total CPU and memory usage (#5911)
* Calculate and display total CPU and memory usage

Added total CPU and memory usage calculations for containers.

* Refactor Docker component layout

Refactor component layout and remove redundant Group elements.

* Create test.yaml

* Add files via upload

* Delete packages/icons/icons directory

Accidental

* Add total CPU and memory strings to English translations

* Add English translations and size refactor

* Fix typo in search label in en.json

* chore(docs): update OpenAPI spec

* Remove color styling from CPU and memory usage text

* Enhance Docker component with footer and toolbar updates

Updated createColumns function to include totals and relativeTime parameters for footer display. Adjusted table configuration to enable bottom toolbar based on isTiny flag.

* Fix formatting and add missing newline at end of file

* Enable sticky header and footer in component

Enable sticky header and add footer row properties for sticky positioning.

* Refactor table component properties

* Refactor table columns and fix footers

* Revert "chore(docs): update OpenAPI spec"

This reverts commit 26f3c809d9.

---------

Co-authored-by: Bergasha <Bergasha@users.noreply.github.com>
Co-authored-by: Manuel <30572287+manuel-rw@users.noreply.github.com>
2026-06-19 20:58:57 +02:00
Matt Van HornandMatt Van Horn c56d9d6894 fix(downloads): sort stalled torrents last when sorting by finish time (#6011)
Stalled torrents have time=0 (infinite/never), which raw numeric sort
places between negative (completed) and positive (active) values.
Add a custom sortingFn on the time column that maps 0 to Infinity so
stalled entries always sort last in ascending order and first in
descending order.

Closes #5416

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-06-19 20:42:48 +02:00
homarr-update-contributors[bot] 3ea49f0391 chore: update contributors (#6010)
Co-authored-by: Homarr Update Contributors <210161987+homarr-update-contributors[bot]@users.noreply.github.com>
2026-06-19 15:02:14 +00:00
homarr-renovate[bot] e2f8f5f081 chore(deps): update lucide monorepo to ^1.18.0 (#5986)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2026-06-18 16:49:33 +00:00
homarr-renovate[bot] f57037b568 chore(deps): update dependency mantine-datatable to ^9.3.0 (#5992)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2026-06-18 16:49:08 +00:00
homarr-renovate[bot] 84803aeefb chore(deps): update dependency rollup@>=4.0.0 <4.22.4 to >=4.62.0 (#5998)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2026-06-18 16:48:53 +00:00
homarr-renovate[bot] 5f47298f3d chore(deps): update dependency isomorphic-dompurify to ^3.17.0 (#6003)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2026-06-18 16:48:07 +00:00
homarr-renovate[bot] de858011fc chore(deps): update dependency mantine-contextmenu to ^9.3.0 (#5991)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2026-06-18 13:08:17 +00:00
homarr-renovate[bot] 12f8e2b83a chore(deps): update dependency sass to ^1.101.0 (#5979)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2026-06-18 13:06:59 +00:00
homarr-renovate[bot] 78b6e520ac fix(deps): update tailwindcss monorepo to ^4.3.1 (#5988)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2026-06-18 13:04:08 +00:00
homarr-releases[bot] 15e6612697 chore: update bug report template (#6001)
Co-authored-by: Releases Homarr <175486441+homarr-releases[bot]@users.noreply.github.com>
2026-06-18 11:39:09 +00:00
Matt Van Horn 6960ac15e9 fix(integrations): make Emby Studios field optional (#5997) 2026-06-18 12:45:59 +02:00
Thomas f1ee76c99c fix(db): crash on MySQL — replace onConflictDoNothing with dialect-neutral pre-filter (#5995) 2026-06-18 12:45:02 +02:00
homarr-renovate[bot] 9a9ee5a9d7 chore(deps): update tiptap monorepo to v3.26.1 (#5976)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2026-06-18 09:24:34 +00:00
68 changed files with 2221 additions and 1571 deletions

No files matched your search

+1
View File
@@ -33,6 +33,7 @@ body:
options:
# The below comment is used to insert a new version with on-release.yml
#NEXT_VERSION#
- 1.66.1
- 1.66.0
- 1.65.0
- 1.64.0
@@ -3,6 +3,7 @@ name: "[Deployment] Automatic Weekly Release"
on:
schedule:
- cron: "0 19 * * 5" # https://crontab.guru/#0_19_*_*_5
timezone: Europe/Zurich
workflow_dispatch:
inputs:
send-notifications:
+2 -2
View File
@@ -32,7 +32,7 @@
"@scalar/api-reference-react": "catalog:",
"@signalwire/docusaurus-plugin-llms-txt": "^1.2.2",
"@tabler/icons-react": "catalog:",
"@tailwindcss/postcss": "^4.3.0",
"@tailwindcss/postcss": "^4.3.1",
"clsx": "catalog:",
"dayjs": "catalog:",
"docusaurus-plugin-image-zoom": "^3.0.1",
@@ -44,7 +44,7 @@
"react": "catalog:",
"react-dom": "catalog:",
"swiper": "^12.2.0",
"tailwindcss": "^4.3.0"
"tailwindcss": "^4.3.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.10.1",
+1
View File
@@ -89,6 +89,7 @@
"mcp-handler": "catalog:",
"next": "catalog:",
"postcss-preset-mantine": "catalog:",
"posthog-js": "catalog:",
"prismjs": "catalog:",
"react": "catalog:",
"react-dom": "catalog:",
+1 -1
View File
@@ -139,11 +139,11 @@ export default async function Layout(props: {
suppressHydrationWarning
>
<head>
<Analytics />
<SearchEngineOptimization />
<CrowdinLiveTranslation locale={locale} />
</head>
<body className={["font-sans", fontSans.variable].join(" ")}>
<Analytics enabled={serverSettings.analytics.enableGeneral} />
<StackedProvider>
<Notifications pauseResetOnHover="notification" />
<ServiceWorkerRegistration />
@@ -17,9 +17,10 @@ interface AnalyticsSettingsProps {
export const AnalyticsSettings = ({ initialData }: AnalyticsSettingsProps) => {
const t = useScopedI18n("management.page.settings.section.analytics");
const { instanceId: _, ...formDefaults } = initialData;
const form = useForm({
initialValues: initialData,
onValuesChange: (updatedValues, _) => {
initialValues: formDefaults,
onValuesChange: (updatedValues, _prev) => {
if (!form.isValid()) {
return;
}
+19 -11
View File
@@ -1,16 +1,24 @@
import Script from "next/script";
"use client";
import { UMAMI_WEBSITE_ID } from "@homarr/analytics";
import { db } from "@homarr/db";
import { getServerSettingByKeyAsync } from "@homarr/db/queries";
import { useEffect } from "react";
export const Analytics = async () => {
// For static pages it will not find any analytics data so we do not include the script on them
const analytics = await getServerSettingByKeyAsync(db, "analytics").catch(() => null);
const POSTHOG_KEY = "phc_vYBmGWNbRshvfeC7EHfeSmUm2pD2Neg5nGqzJuGvS8Hs";
const POSTHOG_HOST = "https://hog.homarr.dev";
if (analytics?.enableGeneral) {
return <Script src="https://umami.homarr.dev/script.js" data-website-id={UMAMI_WEBSITE_ID} defer />;
}
export const Analytics = ({ enabled }: { enabled: boolean }) => {
useEffect(() => {
if (!enabled) return;
return <></>;
void import("posthog-js").then(({ default: posthog }) => {
posthog.init(POSTHOG_KEY, {
api_host: POSTHOG_HOST,
capture_pageview: false,
capture_pageleave: false,
autocapture: false,
persistence: "memory",
});
});
}, [enabled]);
return null;
};
+1 -1
View File
@@ -64,7 +64,7 @@
"node": ">=24.16.0",
"pnpm": ">=11.6.0"
},
"packageManager": "pnpm@11.6.0",
"packageManager": "pnpm@11.7.0",
"dependencies": {
"jsonpath-plus": "catalog:"
}
+1 -3
View File
@@ -26,9 +26,7 @@
"@homarr/core": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0",
"@homarr/docker": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@umami/node": "catalog:",
"superjson": "catalog:"
"posthog-node": "catalog:"
},
"devDependencies": {
"@homarr/tsconfig": "workspace:^0.1.0",
+23
View File
@@ -0,0 +1,23 @@
import { PostHog } from "posthog-node";
export const POSTHOG_API_KEY = "phc_vYBmGWNbRshvfeC7EHfeSmUm2pD2Neg5nGqzJuGvS8Hs";
export const POSTHOG_HOST = "https://hog.homarr.dev";
let instance: PostHog | undefined;
export const getPostHogClient = (): PostHog => {
instance ??= new PostHog(POSTHOG_API_KEY, {
host: POSTHOG_HOST,
flushAt: 10,
flushInterval: 30_000,
});
return instance;
};
export const trackEvent = (instanceId: string, event: string, properties?: Record<string, unknown>) => {
getPostHogClient().capture({
distinctId: instanceId,
event,
properties,
});
};
-2
View File
@@ -1,2 +0,0 @@
export const UMAMI_HOST_URL = "https://umami.homarr.dev";
export const UMAMI_WEBSITE_ID = "ff7dc470-a84f-4779-b1ab-66a5bb16a94b";
+2 -2
View File
@@ -1,2 +1,2 @@
export * from "./constants";
export * from "./send-server-analytics";
export { trackEvent } from "./client";
export { sendServerAnalyticsAsync } from "./send-server-analytics";
+136 -63
View File
@@ -1,17 +1,16 @@
import type { UmamiEventData } from "@umami/node";
import { Umami } from "@umami/node";
import { isProviderEnabled } from "@homarr/auth/server";
import { Stopwatch } from "@homarr/common";
import { createId, Stopwatch } from "@homarr/common";
import { createLogger } from "@homarr/core/infrastructure/logs";
import { count, db } from "@homarr/db";
import { isMysql, isPostgresql } from "@homarr/db/collection";
import { getServerSettingByKeyAsync } from "@homarr/db/queries";
import { getServerSettingByKeyAsync, updateServerSettingByKeyAsync } from "@homarr/db/queries";
import {
accounts,
apiKeys,
apps,
boards,
cronJobConfigurations,
customWidgetDefinitions,
groups,
iconRepositories,
icons,
@@ -24,86 +23,160 @@ import {
searchEngines,
sectionLayouts,
sections,
sessions,
trustedCertificateHostnames,
users,
} from "@homarr/db/schema";
import { env as dockerEnv } from "@homarr/docker/env";
import packageJson from "../../../package.json";
import { UMAMI_HOST_URL, UMAMI_WEBSITE_ID } from "./constants";
import { getPostHogClient } from "./client";
const logger = createLogger({ module: "analytics" });
const getDatabaseType = (): "mysql" | "postgresql" | "sqlite" => {
if (isMysql()) return "mysql";
if (isPostgresql()) return "postgresql";
return "sqlite";
type AnalyticsResult = "sent" | "disabled" | "failed";
// ponytail: no DB-level lock; concurrent calls may both generate an ID, but the last write wins
// and the ID stabilizes after the first successful run. Upgrade path: use DB upsert with WHERE instanceId IS NULL.
const getOrCreateInstanceId = async (
analyticsSettings: Awaited<ReturnType<typeof getServerSettingByKeyAsync<"analytics">>>,
): Promise<string> => {
if (analyticsSettings.instanceId) return analyticsSettings.instanceId;
const instanceId = createId();
await updateServerSettingByKeyAsync(db, "analytics", { ...analyticsSettings, instanceId });
const verified = await getServerSettingByKeyAsync(db, "analytics");
return verified.instanceId ?? instanceId;
};
const getEnabledAuthProviders = (): string[] => {
const providers: string[] = [];
if (isProviderEnabled("credentials")) providers.push("credentials");
if (isProviderEnabled("oidc")) providers.push("oidc");
if (isProviderEnabled("ldap")) providers.push("ldap");
return providers;
};
const sumGroupedCounts = (rows: { count: number }[]): number => rows.reduce((sum, row) => sum + row.count, 0);
export const sendServerAnalyticsAsync = async () => {
export const sendServerAnalyticsAsync = async (): Promise<AnalyticsResult> => {
const stopWatch = new Stopwatch();
const analyticsSettings = await getServerSettingByKeyAsync(db, "analytics");
if (!analyticsSettings.enableGeneral) {
logger.info("Analytics are disabled. No data will be sent. Enable analytics in the settings");
return;
return "disabled";
}
const umamiInstance = new Umami();
umamiInstance.init({
hostUrl: UMAMI_HOST_URL,
websiteId: UMAMI_WEBSITE_ID,
});
const client = getPostHogClient();
const enabledAuthProviders = getEnabledAuthProviders();
try {
const instanceId = await getOrCreateInstanceId(analyticsSettings);
const analyticsData: UmamiEventData = {
homarrVersion: packageJson.version,
databaseType: getDatabaseType(),
dockerEnabled: dockerEnv.ENABLE_DOCKER ? 1 : 0,
kubernetesEnabled: dockerEnv.ENABLE_KUBERNETES ? 1 : 0,
authCredentials: enabledAuthProviders.includes("credentials") ? 1 : 0,
authOidc: enabledAuthProviders.includes("oidc") ? 1 : 0,
authLdap: enabledAuthProviders.includes("ldap") ? 1 : 0,
countUsers: await db.$count(users),
countBoards: await db.$count(boards),
countGroups: await db.$count(groups),
countApps: await db.$count(apps),
countWidgets: await db.$count(items),
countSections: await db.$count(sections),
countIntegrations: await db.$count(integrations),
countSearchEngines: await db.$count(searchEngines),
countIconRepositories: await db.$count(iconRepositories),
countIcons: await db.$count(icons),
countApiKeys: await db.$count(apiKeys),
countInvites: await db.$count(invites),
countMedias: await db.$count(medias),
countLayouts: await db.$count(layouts),
countItemLayouts: await db.$count(itemLayouts),
countSectionLayouts: await db.$count(sectionLayouts),
countCronJobConfigs: await db.$count(cronJobConfigurations),
};
const [
cultureSettings,
countBoards,
countGroups,
countApps,
countSections,
countSearchEngines,
countIconRepositories,
countIcons,
countLayouts,
countItemLayouts,
countSectionLayouts,
countCronJobConfigs,
countCustomWidgets,
countTrustedCertificates,
countUsers,
countApiKeys,
countInvites,
countMedias,
countSessions,
countAccounts,
integrationKinds,
widgetKinds,
] = await Promise.all([
getServerSettingByKeyAsync(db, "culture"),
db.$count(boards),
db.$count(groups),
db.$count(apps),
db.$count(sections),
db.$count(searchEngines),
db.$count(iconRepositories),
db.$count(icons),
db.$count(layouts),
db.$count(itemLayouts),
db.$count(sectionLayouts),
db.$count(cronJobConfigurations),
db.$count(customWidgetDefinitions),
db.$count(trustedCertificateHostnames),
db.$count(users),
db.$count(apiKeys),
db.$count(invites),
db.$count(medias),
db.$count(sessions),
db.$count(accounts),
db
.select({ kind: integrations.kind, count: count(integrations.id) })
.from(integrations)
.groupBy(integrations.kind),
db
.select({ kind: items.kind, count: count(items.id) })
.from(items)
.groupBy(items.kind),
]);
const integrationKinds = await db
.select({ kind: integrations.kind, count: count(integrations.id) })
.from(integrations)
.groupBy(integrations.kind);
const enabledAuthProviders = (["credentials", "oidc", "ldap"] as const).filter(isProviderEnabled);
integrationKinds.forEach((integrationKind) => {
analyticsData[`integration_${integrationKind.kind}`] = integrationKind.count;
});
const properties: Record<string, unknown> = {
homarrVersion: packageJson.version,
databaseType: isMysql() ? "mysql" : isPostgresql() ? "postgresql" : "sqlite",
dockerEnabled: Boolean(dockerEnv.ENABLE_DOCKER),
kubernetesEnabled: Boolean(dockerEnv.ENABLE_KUBERNETES),
authProviders: enabledAuthProviders,
const response = await umamiInstance.track("server-analytics-v2", analyticsData);
if (!response.ok) {
logger.warn("Unable to send analytics to Umami instance");
osPlatform: process.platform,
osArch: process.arch,
uptimeSeconds: Math.floor(process.uptime()),
defaultLocale: cultureSettings.defaultLocale,
countBoards,
countGroups,
countApps,
countSections,
countSearchEngines,
countIconRepositories,
countIcons,
countLayouts,
countItemLayouts,
countSectionLayouts,
countCronJobConfigs,
countCustomWidgets,
countTrustedCertificates,
countUsers,
countApiKeys,
countInvites,
countMedias,
countSessions,
countAccounts,
countIntegrations: sumGroupedCounts(integrationKinds),
countWidgets: sumGroupedCounts(widgetKinds),
};
for (const row of integrationKinds) {
properties[`integration_${row.kind}`] = row.count;
}
for (const row of widgetKinds) {
properties[`widget_${row.kind}`] = row.count;
}
client.capture({
distinctId: instanceId,
event: "server-analytics",
properties,
});
await client.flush();
logger.info(`Sent analytics to PostHog in ${stopWatch.getElapsedInHumanWords()}`);
return "sent";
} catch (error) {
logger.warn("Failed to send analytics to PostHog", { error });
return "failed";
}
logger.info(`Sent analytics in ${stopWatch.getElapsedInHumanWords()}`);
};
+1
View File
@@ -24,6 +24,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@homarr/analytics": "workspace:^0.1.0",
"@homarr/auth": "workspace:^0.1.0",
"@homarr/common": "workspace:^0.1.0",
"@homarr/core": "workspace:^0.1.0",
+1
View File
@@ -28,6 +28,7 @@ export const appRouter = createTRPCRouter({
updateChecker: lazy(() => import("./router/update-checker").then((mod) => mod.updateCheckerRouter)),
certificates: lazy(() => import("./router/certificates/certificate-router").then((mod) => mod.certificateRouter)),
bangs: lazy(() => import("./router/bangs/bangs-router").then((mod) => mod.bangsRouter)),
analytics: lazy(() => import("./router/analytics").then((mod) => mod.analyticsRouter)),
info: lazy(() => import("./router/info").then((mod) => mod.infoRouter)),
customWidget: lazy(() => import("./router/custom-widget/custom-widget-router").then((mod) => mod.customWidgetRouter)),
});
+51
View File
@@ -0,0 +1,51 @@
import { TRPCError } from "@trpc/server";
import z from "zod/v4";
import { sendServerAnalyticsAsync, trackEvent } from "@homarr/analytics";
import { env } from "@homarr/common/env";
import { db } from "@homarr/db";
import { getServerSettingByKeyAsync } from "@homarr/db/queries";
import { createTRPCRouter, permissionRequiredProcedure, protectedProcedure } from "../trpc";
const getInstanceId = async (): Promise<string | null> => {
if (env.NO_EXTERNAL_CONNECTION) return null;
const settings = await getServerSettingByKeyAsync(db, "analytics");
if (!settings.enableGeneral) return null;
return settings.instanceId;
};
export const analyticsRouter = createTRPCRouter({
sendAnalytics: permissionRequiredProcedure.requiresPermission("admin").mutation(async () => {
if (env.NO_EXTERNAL_CONNECTION) {
throw new TRPCError({ code: "PRECONDITION_FAILED", message: "External connections are disabled" });
}
return { status: await sendServerAnalyticsAsync() };
}),
trackFeature: protectedProcedure
.input(
z.object({
feature: z.string().max(128),
properties: z.record(z.string(), z.unknown()).optional(),
}),
)
.mutation(async ({ input, ctx }) => {
const instanceId = await getInstanceId();
if (!instanceId) return;
trackEvent(instanceId, `feature:${input.feature}`, {
...input.properties,
userId: ctx.session.user.id,
});
}),
heartbeat: protectedProcedure.mutation(async ({ ctx }) => {
const instanceId = await getInstanceId();
if (!instanceId) return;
trackEvent(instanceId, "user-active", {
userId: ctx.session.user.id,
});
}),
});
+7 -6
View File
@@ -24,17 +24,18 @@ export const serverSettingsRouter = createTRPCRouter({
}),
)
.mutation(async ({ ctx, input }) => {
await updateServerSettingByKeyAsync(
ctx.db,
input.settingsKey,
input.value as ServerSettings[keyof ServerSettings],
);
const current = await getServerSettingByKeyAsync(ctx.db, input.settingsKey);
await updateServerSettingByKeyAsync(ctx.db, input.settingsKey, {
...current,
...input.value,
} as ServerSettings[keyof ServerSettings]);
}),
initSettings: onboardingProcedure
.requiresStep("settings")
.input(settingsInitSchema)
.mutation(async ({ ctx, input }) => {
await updateServerSettingByKeyAsync(ctx.db, "analytics", input.analytics);
const currentAnalytics = await getServerSettingByKeyAsync(ctx.db, "analytics");
await updateServerSettingByKeyAsync(ctx.db, "analytics", { ...currentAnalytics, ...input.analytics });
await updateServerSettingByKeyAsync(ctx.db, "crawlingAndIndexing", input.crawlingAndIndexing);
await nextOnboardingStepAsync(ctx.db, undefined);
}),
@@ -75,9 +75,6 @@ describe("saveSettings", () => {
settingsKey: "analytics",
value: {
enableGeneral: true,
enableWidgetData: true,
enableIntegrationData: true,
enableUserData: true,
},
});
@@ -87,9 +84,7 @@ describe("saveSettings", () => {
settingKey: "analytics",
value: SuperJSON.stringify({
enableGeneral: true,
enableWidgetData: true,
enableIntegrationData: true,
enableUserData: true,
instanceId: null,
}),
},
]);
+2
View File
@@ -20,6 +20,7 @@ interface CreateCronJobOptions {
runOnStart?: boolean;
preventManualExecution?: boolean;
preventCustomInterval?: boolean;
hidden?: boolean;
expectedMaximumDurationInMillis?: number;
beforeStart?: () => MaybePromise<void>;
}
@@ -121,6 +122,7 @@ const createCallback = <TAllowedNames extends string, TName extends TAllowedName
},
preventManualExecution: options.preventManualExecution ?? false,
preventCustomInterval: options.preventCustomInterval ?? false,
hidden: options.hidden ?? false,
timezone: creatorOptions.timezone,
};
};
+12 -10
View File
@@ -122,15 +122,17 @@ export class JobManager {
> {
const configurations = await this.db.query.cronJobConfigurations.findMany();
return [...this.jobGroup.getJobRegistry().entries()].map(([name, job]) => {
const config = configurations.find((config) => config.name === name);
return {
name,
cron: config?.cronExpression ?? job.cronExpression,
preventManualExecution: job.preventManualExecution,
preventCustomInterval: job.preventCustomInterval,
isEnabled: config?.isEnabled ?? true,
};
});
return [...this.jobGroup.getJobRegistry().entries()]
.filter(([_, job]) => !job.hidden)
.map(([name, job]) => {
const config = configurations.find((config) => config.name === name);
return {
name,
cron: config?.cronExpression ?? job.cronExpression,
preventManualExecution: job.preventManualExecution,
preventCustomInterval: job.preventCustomInterval,
isEnabled: config?.isEnabled ?? true,
};
});
}
}
+1 -8
View File
@@ -1,8 +1,6 @@
import { sendServerAnalyticsAsync } from "@homarr/analytics";
import { env } from "@homarr/common/env";
import { EVERY_WEEK } from "@homarr/cron-jobs-core/expressions";
import { db } from "@homarr/db";
import { getServerSettingByKeyAsync } from "@homarr/db/queries";
import { createCronJob } from "../lib";
@@ -10,13 +8,8 @@ export const analyticsJob = createCronJob("analytics", EVERY_WEEK, {
runOnStart: true,
preventManualExecution: true,
preventCustomInterval: true,
hidden: true,
}).withCallback(async () => {
if (env.NO_EXTERNAL_CONNECTION) return;
const analyticSetting = await getServerSettingByKeyAsync(db, "analytics");
if (!analyticSetting.enableGeneral) {
return;
}
await sendServerAnalyticsAsync();
});
+10 -14
View File
@@ -647,9 +647,13 @@ const seedDemoUserAsync = async (db: Database) => {
const seedDefaultCustomWidgetsAsync = async (db: Database) => {
const seedIds = CUSTOM_WIDGET_SEEDS.map((s) => s.id);
const beforeCount = await db.$count(customWidgetDefinitions, inArray(customWidgetDefinitions.id, seedIds));
const existing = await db.query.customWidgetDefinitions.findMany({
columns: { id: true },
where: inArray(customWidgetDefinitions.id, seedIds),
});
const existingIds = new Set(existing.map((row) => row.id));
const seedValues = CUSTOM_WIDGET_SEEDS.map((seed) => {
const seedValues = CUSTOM_WIDGET_SEEDS.filter((seed) => !existingIds.has(seed.id)).map((seed) => {
const parsed = customWidgetImportSchema.parse(seed.data);
return {
id: seed.id,
@@ -668,22 +672,14 @@ const seedDefaultCustomWidgetsAsync = async (db: Database) => {
};
});
if (seedValues.length === 0) return;
await db
.insert(customWidgetDefinitions)
.values(seedValues)
.onConflictDoNothing({ target: customWidgetDefinitions.id });
const afterCount = await db.$count(customWidgetDefinitions, inArray(customWidgetDefinitions.id, seedIds));
const createdCount = afterCount - beforeCount;
if (createdCount === 0) {
if (seedValues.length === 0) {
console.log("Skipping seeding of default custom widgets as they already exist");
return;
}
console.log(`Created ${createdCount} default custom widgets through seeding process`);
await db.insert(customWidgetDefinitions).values(seedValues);
console.log(`Created ${seedValues.length} default custom widgets through seeding process`);
};
const seedBoardWidgetsAsync = async (db: Database) => {
@@ -38,7 +38,7 @@ const itemSchema = z.object({
ServerId: z.string(),
Name: z.string(),
Taglines: z.array(z.string()),
Studios: z.array(z.object({ Name: z.string() })),
Studios: z.array(z.object({ Name: z.string() })).optional(),
Overview: z.string().optional(),
PremiereDate: z
.string()
@@ -172,7 +172,7 @@ export class EmbyIntegration extends Integration implements IMediaServerIntegrat
poster: super.externalUrl(`/Items/${item.Id}/Images/Primary?maxHeight=492&maxWidth=328&quality=90`).toString(),
backdrop: super.externalUrl(`/Items/${item.Id}/Images/Backdrop/0?maxWidth=960&quality=70`).toString(),
},
producer: item.Studios.at(0)?.Name,
producer: item.Studios?.at(0)?.Name,
rating: item.CommunityRating?.toFixed(1),
tags: item.Genres,
href: super.externalUrl(`/web/index.html#!/item?id=${item.Id}&serverId=${item.ServerId}`).toString(),
+1 -3
View File
@@ -16,9 +16,7 @@ export type ServerSettingsRecord = Record<(typeof defaultServerSettingsKeys)[num
export const defaultServerSettings = {
analytics: {
enableGeneral: true,
enableWidgetData: false,
enableIntegrationData: false,
enableUserData: false,
instanceId: null as string | null,
},
crawlingAndIndexing: {
noIndex: true,
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "应用",
"description": "将应用嵌入到面板中。",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "crwdns5641:0crwdne5641:0",
"loading": "crwdns5643:0crwdne5643:0",
"placeholder": "crwdns5645:0crwdne5645:0",
"noResults": "crwdns5647:0crwdne5647:0",
"loadError": "crwdns5649:0crwdne5649:0"
},
"app": {
"name": "crwdns732:0crwdne732:0",
"description": "crwdns734:0crwdne734:0",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "crwdns4811:0crwdne4811:0",
"error": {
"internalServerError": "crwdns5651:0crwdne5651:0"
},
"column": {
"system": "crwdns4813:0crwdne4813:0",
"cpu": "crwdns4815:0crwdne4815:0",
@@ -3626,6 +3636,9 @@
"label": "crwdns4863:0crwdne4863:0"
}
},
"error": {
"internalServerError": "crwdns5653:0crwdne5653:0"
},
"metric": {
"cpu": "crwdns4865:0crwdne4865:0",
"memory": "crwdns4867:0crwdne4867:0",
@@ -3652,6 +3665,9 @@
}
},
"empty": "crwdns4895:0crwdne4895:0",
"error": {
"internalServerError": "crwdns5655:0crwdne5655:0"
},
"history": "crwdns4897:0crwdne4897:0",
"resolved": "crwdns4899:0crwdne4899:0",
"status": {
@@ -3663,6 +3679,10 @@
"name": "crwdns4905:0crwdne4905:0",
"description": "crwdns4907:0crwdne4907:0",
"option": {
"systemId": {
"label": "crwdns5657:0crwdne5657:0",
"description": "crwdns5659:0crwdne5659:0"
},
"timePeriod": {
"label": "crwdns4909:0crwdne4909:0"
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "crwdns4927:0crwdne4927:0",
"error": {
"internalServerError": "crwdns5661:0crwdne5661:0",
"liveConnectionFailed": "crwdns5663:0crwdne5663:0",
"switchToHistorical": "crwdns5665:0crwdne5665:0",
"systemNotFound": "crwdns5667:0crwdne5667:0"
},
"chart": {
"cpu": {
"title": "crwdns4929:0crwdne4929:0",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "App",
"description": "Indlejrer en app i tavlen.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "Bettet eine App in das Board ein.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+154 -128
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "Verbinde zuerst eine Integration",
"loading": "Wird geladen...",
"placeholder": "Wählen Sie eine Option",
"noResults": "Keine Ergebnisse gefunden",
"loadError": "Fehler beim Laden der Optionen"
},
"app": {
"name": "App",
"description": "Bettet eine App in das Board ein.",
@@ -1740,11 +1747,11 @@
}
},
"archiveTeamWarrior": {
"name": "",
"description": "",
"name": "ArchiveTeam Warrior",
"description": "ArchiveTeam Warrior Status, Projekte und aktive Archivaufträge überwachen.",
"option": {
"showBroadcastMessage": {
"label": ""
"label": "Broadcast Nachrichten anzeigen"
}
}
},
@@ -3332,58 +3339,58 @@
},
"uptimeKuma": {
"name": "Uptime Kuma",
"description": "",
"description": "Laufzeit Statistiken von der Uptime Kuma Statusseite überwachen",
"option": {
"showAverageUptime": {
"label": "",
"description": ""
"label": "Durchschnittliche Laufzeit anzeigen",
"description": "Zeige den durchschnittlichen Prozentsatz der 24 Stunden Laufzeit an"
},
"showUptimeRing": {
"label": "",
"description": ""
"label": "Uptime Ring anzeigen",
"description": "Einen Fortschrittsring neben dem durchschnittlichen Laufzeit Wert anzeigen"
},
"showTotalMonitors": {
"label": "",
"description": ""
"label": "Alle Monitore anzeigen",
"description": "Zeigt die Gesamtzahl der konfigurierten Monitore an"
},
"showUpCount": {
"label": "",
"description": ""
"label": "Aktive anzeigen",
"description": "Zeigt an, wie viele Monitore derzeit aktiv sind"
},
"showDownCount": {
"label": "",
"description": ""
"label": "Inaktive anzeigen",
"description": "Zeigt an, wie viele Monitore derzeit nicht verfügbar sind"
},
"showPausedCount": {
"label": "",
"description": ""
"label": "Pausierte anzeigen",
"description": "Zeigt an, wie viele Monitore derzeit pausiert sind"
}
},
"averageUptime": "",
"averageUptime": "Durchschnittliche Laufzeit (24h)",
"stats": {
"totalMonitors": "",
"upCount": "",
"downCount": "",
"pausedCount": ""
"totalMonitors": "Alle Monitore",
"upCount": "Aktiv",
"downCount": "Inaktiv",
"pausedCount": "Pausiert"
},
"error": {
"internalServerError": ""
}
},
"audioStats": {
"name": "",
"name": "Audiostatistiken",
"description": "",
"option": {
"showArtists": {
"label": "",
"label": "Künstler anzeigen",
"description": ""
},
"showAlbums": {
"label": "",
"description": ""
"description": "Zeigt die Gesamtzahl der Alben in deiner Musikbibliothek an (Navidrome)"
},
"showSongs": {
"label": "",
"label": "Songs anzeigen",
"description": ""
},
"showNowPlaying": {
@@ -3412,10 +3419,10 @@
},
"showListeningTime": {
"label": "",
"description": ""
"description": "Zeigt deine gesamte Hörzeit (Audiobookshelf)"
},
"showActiveSessions": {
"label": "",
"label": "Aktive Streams anzeigen",
"description": ""
},
"compactMode": {
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3596,13 +3606,13 @@
"label": ""
},
"showMemory": {
"label": ""
"label": "Arbeitsspeicher anzeigen"
},
"showDisk": {
"label": ""
},
"showGpu": {
"label": ""
"label": "GPU anzeigen"
},
"showLoadAvg": {
"label": ""
@@ -3611,13 +3621,13 @@
"label": ""
},
"showTemp": {
"label": ""
"label": "Temperatur anzeigen"
},
"showBattery": {
"label": ""
},
"showServices": {
"label": ""
"label": "Dienste anzeigen"
},
"showUptime": {
"label": ""
@@ -3626,18 +3636,21 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
"cpu": "CPU",
"memory": "Arbeitsspeicher",
"disk": "",
"gpu": "",
"gpu": "GPU",
"loadAvg": "",
"net": "",
"temp": "",
"battery": "",
"services": "",
"services": "Dienste",
"uptime": "",
"agent": ""
"agent": "Agent"
}
},
"beszelAlerts": {
@@ -3652,17 +3665,24 @@
}
},
"empty": "",
"history": "",
"error": {
"internalServerError": ""
},
"history": "Verlauf",
"resolved": "",
"status": {
"triggered": "",
"ok": ""
"ok": "Ok"
}
},
"beszelSystemStats": {
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3691,21 +3711,27 @@
"label": ""
}
},
"selectSystem": "",
"selectSystem": "System auswählen",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
"title": "CPU-Auslastung",
"subtitle": "",
"series": ""
"series": "CPU"
},
"memory": {
"title": "",
"subtitle": "",
"series": "",
"series": "Belegt",
"cache": ""
},
"disk": {
"title": "",
"title": "Festplattenbelegung",
"subtitle": "",
"series": ""
},
@@ -4256,12 +4282,12 @@
"message": ""
},
"status": {
"completed": "",
"notStarted": ""
"completed": "Abgeschlossen",
"notStarted": "Nicht gestartet"
},
"name": {
"management": "",
"dashboard": ""
"dashboard": "Dashboard"
}
}
}
@@ -4678,15 +4704,15 @@
"subtitle": "",
"description": "",
"noApiKey": "",
"createApiKeyButton": "",
"createApiKeyButton": "API Key erstellen",
"endpoint": {
"title": ""
},
"authentication": {
"title": "",
"title": "Authentifizierung",
"intro": "",
"apiKey": {
"title": "",
"title": "API Key (manuell)",
"description": ""
},
"oauth": {
@@ -4699,12 +4725,12 @@
"clientConfig": {
"title": "",
"streamableHttp": {
"recommended": "",
"recommended": "Empfohlen",
"title": "",
"worksWith": "",
"addToConfig": "",
"cursor": "",
"claudeDesktop": "",
"claudeDesktop": "{name}: {file}",
"claudeCode": "",
"vsCodeCopilot": "",
"replaceHint": ""
@@ -4715,16 +4741,16 @@
}
},
"testConnection": {
"title": "",
"title": "Verbindung testen",
"description": "",
"hint": ""
},
"availableTools": {
"title": "",
"title": "Verfügbare Tools",
"description": "",
"columnType": "",
"columnName": "",
"columnDescription": ""
"columnType": "Typ",
"columnName": "Tool",
"columnDescription": "Beschreibung"
},
"troubleshooting": {
"title": "",
@@ -4753,65 +4779,65 @@
"oneClick": {
"title": "",
"subtitle": "",
"vsCode": "",
"cursor": "",
"copyUrl": "",
"copied": "",
"copyHint": "",
"manualConfig": ""
"vsCode": "In VS Code installieren",
"cursor": "In Cursor installieren",
"copyUrl": "MCP URL kopieren",
"copied": "Kopiert!",
"copyHint": "Für ChatGPT, Claude Code oder weitere MCP-Client",
"manualConfig": "Manuelle Konfiguration"
}
}
}
},
"backup": {
"title": "",
"metaTitle": "",
"title": "Komplette Datenbanksicherung",
"metaTitle": "Sichern & Wiederherstellen",
"export": {
"title": "",
"description": "",
"button": "",
"error": "",
"title": "Datenbank exportieren",
"description": "Laden Sie eine vollständige Sicherung Ihrer SQLite-Datenbank herunter, inklusive aller Einstellungen, Benutzer, Boards und verschlüsselten Integrationsgeheimnissen. Das Backup wird als ZIP-Datei mit dem Verschlüsselungsschlüssel und den Metadaten gebündelt.",
"button": "Sicherung herunterladen",
"error": "Export fehlgeschlagen",
"confirm": {
"title": "",
"warningTitle": "",
"warningBody": "",
"typePrompt": "",
"submit": "",
"cancel": ""
"warningTitle": "Dieser Export enthält Ihre gesamte Datenbank.",
"warningBody": "Das Backup umfasst alle Benutzer, Integrationsgeheimnisse (verschlüsselt), API-Keys, Board-Konfigurationen und App-Daten. Speichern Sie die exportierte Datei sicher ab und teilen Sie diese nicht.",
"typePrompt": "Geben Sie \"{phrase}\" ein, um fortzufahren",
"submit": "Datenbank exportieren",
"cancel": "Abbrechen"
}
},
"import": {
"title": "",
"title": "Datenbank wiederherstellen",
"description": "",
"warning": "",
"dropzone": {
"title": "",
"description": ""
"title": "Ziehen Sie Ihre Backup-ZIP hierher oder klicken Sie zum Durchsuchen",
"description": "Nur .zip Dateien aus einer Homarr SQLite-Sicherung werden akzeptiert"
},
"changeFile": "",
"button": "",
"changeFile": "Datei ändern",
"button": "Datenbank wiederherstellen",
"success": {
"title": "",
"message": ""
"title": "Wiederherstellung abgeschlossen",
"message": "Datenbank wurde erfolgreich wiederhergestellt. Die Anwendung wird neu gestartet..."
},
"error": ""
"error": "Importieren fehlgeschlagen"
},
"preview": {
"title": "",
"exported": "",
"loading": "",
"loading": "Analysiere Backup-Datei...",
"errorTitle": "",
"entity": "",
"count": "",
"boards": "",
"boards": "Boards",
"entities": {
"board": "",
"user": "",
"app": "",
"integration": "",
"item": "",
"media": "",
"search_engine": ""
"board": "Boards",
"user": "Benutzer",
"app": "Apps",
"integration": "Integrationen",
"item": "Widgets",
"media": "Medien",
"search_engine": "Suchmaschinen"
},
"analyzeError": "",
"invalidMissingMetadata": "",
@@ -4819,11 +4845,11 @@
},
"restore": {
"dropzone": {
"title": "",
"description": ""
"title": "Backup-ZIP hierher ziehen",
"description": "Akzeptiert .zip-Dateien von einem Homarr SQLite-Backup (max. 256 MB)"
},
"analyzing": "",
"changeFile": "",
"analyzing": "Analysiere Backup-Datei...",
"changeFile": "Datei ändern",
"continueToRestore": "",
"tryAgain": "",
"analysisError": "",
@@ -4875,7 +4901,7 @@
"message": ""
},
"failed": {
"title": ""
"title": "Wiederherstellung fehlgeschlagen"
},
"invalidMissingMetadata": "",
"invalidMissingDb": "",
@@ -4961,15 +4987,15 @@
"label": "Ports"
},
"host": {
"label": ""
"label": "Host"
}
},
"action": {
"title": "Aktionen",
"logs": {
"label": "",
"label": "Logs anzeigen",
"page": {
"title": ""
"title": "{name} Logs"
}
},
"start": {
@@ -5364,12 +5390,12 @@
}
},
"custom-widgets": {
"label": "",
"label": "Benutzerdefinierte Widgets",
"new": {
"label": ""
"label": "Neu"
},
"edit": {
"label": "",
"label": "Bearbeiten",
"flow": {
"label": ""
}
@@ -5398,7 +5424,7 @@
"docker": {
"label": "Docker",
"logs": {
"label": ""
"label": "Logs"
}
},
"kubernetes": {
@@ -5550,26 +5576,26 @@
}
},
"preferences": {
"title": "",
"title": "Einstellungen",
"children": {
"detail": {
"title": "",
"backHint": "",
"backAction": ""
"backAction": "Zurück"
}
},
"notification": {
"error": {
"message": ""
"message": "Einstellung konnte nicht aktualisiert werden"
}
},
"option": {
"preferences": {
"label": ""
"label": "Einstellungen öffnen"
},
"boolean": {
"enabled": "",
"disabled": ""
"enabled": "Aktiviert",
"disabled": "Deaktiviert"
},
"board": {
"none": "",
@@ -5580,34 +5606,34 @@
"unavailable": ""
},
"colorScheme": {
"label": "",
"label": "Farbschema",
"children": {
"detail": {
"title": ""
"title": "Farbschema auswählen"
}
}
},
"locale": {
"label": "",
"label": "Sprache",
"children": {
"detail": {
"title": ""
"title": "Bevorzugte Sprache auswählen"
}
}
},
"defaultSearchEngineId": {
"label": "",
"label": "Standard Suchmaschine",
"children": {
"detail": {
"title": ""
"title": "Standard Suchmaschine auswählen"
}
}
},
"openSearchInNewTab": {
"label": "",
"label": "Suchergebnisse in neuem Tab öffnen",
"children": {
"detail": {
"title": ""
"title": "Suchergebnisse in neuem Tab öffnen"
}
}
},
@@ -5620,10 +5646,10 @@
}
},
"firstDayOfWeek": {
"label": "",
"label": "Erster Tag der Woche",
"children": {
"detail": {
"title": ""
"title": "Ersten Tag der Woche auswählen"
}
}
},
@@ -5652,23 +5678,23 @@
}
},
"fullPreferencesPage": {
"label": ""
"label": "Alle Einstellungen öffnen"
}
}
}
}
},
"media": {
"help": "",
"help": "Suche nach Filmen oder Serien zum Abfragen",
"requestMovie": "Einen Film anfordern",
"requestSeries": "Eine Serie anfordern",
"openIn": "In {kind} öffnen",
"group": {
"title": ""
"title": "Filme und Serien"
},
"action": {
"search": {
"label": "",
"label": "Suche nach Filmen oder Serien",
"description": "",
"disabled": {
"noIntegration": "",
@@ -6098,23 +6124,23 @@
"description": ""
},
"appsCreate": {
"title": "",
"title": "App hinzufügen",
"description": ""
},
"integrationsList": {
"title": "",
"title": "Ihre Integrationen",
"description": ""
},
"integrationsCreate": {
"title": "",
"title": "Integration hinzufügen",
"description": ""
},
"usersList": {
"title": "",
"title": "Ihre Benutzer",
"description": ""
},
"usersCreate": {
"title": "",
"title": "Benutzer erstellen",
"description": ""
}
},
@@ -6124,7 +6150,7 @@
"description": ""
},
"editMode": {
"title": "",
"title": "Bearbeitungsmodus",
"description": ""
},
"settings": {
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "Εφαρμογή",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "App",
"description": "Embeds an app into the board.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+5 -15
View File
@@ -4413,20 +4413,8 @@
"analytics": {
"title": "Analytics",
"general": {
"title": "Send anonymous analytics",
"text": "Homarr will send anonymized analytics using the open source software Umami. When enabled, we collect: Homarr version, database type (MySQL/PostgreSQL/SQLite), Docker/Kubernetes status, authentication methods enabled, and the number of each feature. All data is anonymous and aggregated - no personal information, URLs, names, or identifiable data is ever collected. This helps our open source team understand usage patterns and prioritize development."
},
"widgetData": {
"title": "Widget data",
"text": "Send which widgets (and their quantity) you have configured. Does not include URLs, names or any other data."
},
"integrationData": {
"title": "Integration data",
"text": "Send which integrations (and their quantity) you have configured. Does not include URLs, names or any other data."
},
"usersData": {
"title": "Users data",
"text": "Send the amount of users and whether you've activated SSO"
"title": "Help us improve Homarr",
"text": "This helps us figure out what people actually use so we know where to spend our time. We see stuff like how many widgets or integrations you have, your Homarr version, and what database you're on. That's it — no personal info, no URLs, no names, nothing that could identify you or your setup."
}
},
"crawlingAndIndexing": {
@@ -4954,7 +4942,9 @@
"updated": "Updated {when}",
"search": "Seach {count} containers",
"selected": "{selectCount} of {totalCount} containers selected",
"footer": "Total {count} containers"
"footer": "Total {count} containers",
"totalCpu": "Total CPU: {cpu}%",
"totalMemory": "Total Mem: {memory}"
},
"field": {
"name": {
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "Aplicación",
"description": "Insertar una aplicación en el tablero.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "Sovellus",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "App",
"description": "Intègre une application dans le tableau.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "אפליקציה",
"description": "הטמעת אפליקציה בלוח.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "Alkalmazás",
"description": "Alkalmazást ágyaz be a táblába.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+29 -3
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "Connetti prima un'integrazione",
"loading": "Caricamento...",
"placeholder": "Seleziona un'opzione",
"noResults": "Nessun risultato trovato",
"loadError": "Impossibile caricare le opzioni"
},
"app": {
"name": "App",
"description": "Incorpora un'app nella board.",
@@ -1740,11 +1747,11 @@
}
},
"archiveTeamWarrior": {
"name": "",
"description": "",
"name": "ArchiveTeam Warrior",
"description": "Monitora lo stato di ArchiveTeam Warrior e i lavori di archiviazione attivi.",
"option": {
"showBroadcastMessage": {
"label": ""
"label": "Mostra messaggi broadcast"
}
}
},
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "Nessun sistema trovato",
"error": {
"internalServerError": "Impossibile connettersi a Beszel. Controlla le tue impostazioni di integrazione."
},
"column": {
"system": "Sistema",
"cpu": "CPU",
@@ -3626,6 +3636,9 @@
"label": "Mostra versione agente"
}
},
"error": {
"internalServerError": "Impossibile connettersi a Beszel. Controlla le tue impostazioni di integrazione."
},
"metric": {
"cpu": "CPU",
"memory": "Memoria",
@@ -3652,6 +3665,9 @@
}
},
"empty": "Nessun avviso configurato",
"error": {
"internalServerError": "Impossibile connettersi a Beszel. Controlla le tue impostazioni di integrazione."
},
"history": "Cronologia",
"resolved": "Risolto",
"status": {
@@ -3663,6 +3679,10 @@
"name": "Statistiche Sistema Beszel",
"description": "Grafici a serie temporali per CPU, memoria, disco, rete e metriche dei container Docker",
"option": {
"systemId": {
"label": "Sistema",
"description": "Seleziona un sistema Beszel per visualizzare le statistiche per"
},
"timePeriod": {
"label": "Periodo di tempo"
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "Seleziona sistema",
"error": {
"internalServerError": "Impossibile connettersi a Beszel. Controlla le tue impostazioni di integrazione.",
"liveConnectionFailed": "Connessione Live non riuscita. L'istanza di Beszel potrebbe non supportare lo streaming in tempo reale.",
"switchToHistorical": "Passa alla visualizzazione storica",
"systemNotFound": "Il sistema selezionato non è stato trovato. Scegli un sistema diverso."
},
"chart": {
"cpu": {
"title": "Utilizzo CPU",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "アプリ",
"description": "アプリをボードに埋め込みます。",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "App",
"description": "Een app insluiten op het bord.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "App",
"description": "Bygger inn en app i tavlen.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "Aplikacja",
"description": "Dodaje aplikację do tablicy.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "Aplicativo",
"description": "Incorpora um aplicativo no quadro.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "Приложение",
"description": "Встраивает приложение в панель.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "Aplikácia",
"description": "Vloží aplikáciu do tabule.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "Uygulama",
"description": "Panelin içine uygulama yerleştirir.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+27 -1
View File
@@ -812,7 +812,7 @@
"singleValue": "",
"keyValue": "",
"table": "",
"statGrid": "",
"statGrid": "Кольорові картки статистики в сітці — як-от віджети Pi-Hole або Speedtest",
"progressBars": "",
"statusIndicator": "",
"countGrid": "",
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "Додаток",
"description": "Вбудовує додаток до дошки.",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "",
"description": "",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
+26
View File
@@ -1652,6 +1652,13 @@
}
},
"widget": {
"integrationSelect": {
"configureIntegrationFirst": "",
"loading": "",
"placeholder": "",
"noResults": "",
"loadError": ""
},
"app": {
"name": "應用程式",
"description": "將應用程式新增至面板中",
@@ -3570,6 +3577,9 @@
}
},
"noRecords": "",
"error": {
"internalServerError": ""
},
"column": {
"system": "",
"cpu": "",
@@ -3626,6 +3636,9 @@
"label": ""
}
},
"error": {
"internalServerError": ""
},
"metric": {
"cpu": "",
"memory": "",
@@ -3652,6 +3665,9 @@
}
},
"empty": "",
"error": {
"internalServerError": ""
},
"history": "",
"resolved": "",
"status": {
@@ -3663,6 +3679,10 @@
"name": "",
"description": "",
"option": {
"systemId": {
"label": "",
"description": ""
},
"timePeriod": {
"label": ""
},
@@ -3692,6 +3712,12 @@
}
},
"selectSystem": "",
"error": {
"internalServerError": "",
"liveConnectionFailed": "",
"switchToHistorical": "",
"systemNotFound": ""
},
"chart": {
"cpu": {
"title": "",
-3
View File
@@ -3,9 +3,6 @@ import { z } from "zod/v4";
export const settingsInitSchema = z.object({
analytics: z.object({
enableGeneral: z.boolean(),
enableWidgetData: z.boolean(),
enableIntegrationData: z.boolean(),
enableUserData: z.boolean(),
}),
crawlingAndIndexing: z.object({
noIndex: z.boolean(),
+29 -4
View File
@@ -200,6 +200,17 @@ export default function DockerWidget({ options, width, isEditMode }: WidgetCompo
const totalContainers = containers.length;
const totals = useMemo(() => {
return containers.reduce(
(acc, container) => {
acc.cpu += safeValue(container.cpuUsage);
acc.memory += safeValue(container.memoryUsage);
return acc;
},
{ cpu: 0, memory: 0 }
);
}, [containers]);
const columns = useMemo(() => createColumns(t), [t]);
const table = useTranslatedMantineReactTable({
@@ -261,12 +272,26 @@ export default function DockerWidget({ options, width, isEditMode }: WidgetCompo
}}
p={4}
>
<Group gap={4}>
<IconBrandDocker size={20} />
<Text size="sm">{t("table.footer", { count: totalContainers.toString() })}</Text>
<Group gap={4} wrap="nowrap">
<IconBrandDocker size={20} style={{ flexShrink: 0 }} />
<Text size="sm" truncate="end">
{t("table.footer", { count: totalContainers.toString() })}
</Text>
</Group>
<Text size="sm">{t("table.updated", { when: relativeTime })}</Text>
<Group gap="sm" wrap="wrap" justify="flex-end" style={{ flex: 1, minWidth: 0 }}>
<Text size="sm" style={{ whiteSpace: "nowrap" }}>
{t("table.totalCpu", { cpu: totals.cpu.toFixed(2) })}
</Text>
<Text size="sm" style={{ whiteSpace: "nowrap" }}>
{t("table.totalMemory", { memory: humanFileSize(totals.memory) })}
</Text>
<Text size="sm" style={{ whiteSpace: "nowrap" }}>
{t("table.updated", { when: relativeTime })}
</Text>
</Group>
</Group>
)}
</Stack>
@@ -529,6 +529,16 @@ export default function DownloadClientsWidget({
},
{
...columnsDefBase({ key: "time", showHeader: true }),
sortingFn: (rowA, rowB) => {
const timeA = rowA.getValue<ExtendedDownloadClientItem["time"]>("time");
const timeB = rowB.getValue<ExtendedDownloadClientItem["time"]>("time");
// Map time values to canonical sort keys:
// positive = ETA in ms (sort as-is, smaller = sooner)
// 0 = stalled/infinite (sort last in ascending = Infinity)
// negative = time since completion in ms (sort first in ascending = very negative)
const toSortKey = (time: number) => (time === 0 ? Infinity : time);
return toSortKey(timeA) - toSortKey(timeB);
},
Cell: ({ cell }) => {
const time = cell.getValue<ExtendedDownloadClientItem["time"]>();
return time === 0 ? <IconInfinity size={16} /> : <Text size="xs">{dayjs().add(time).fromNow()}</Text>;
+828 -1255
View File
File diff suppressed because it is too large. Load diff
+24 -23
View File
@@ -52,22 +52,22 @@ catalog:
"@testcontainers/mysql": ^12.0.2
"@testcontainers/postgresql": ^12.0.2
"@testcontainers/redis": ^12.0.2
"@tiptap/extension-color": 3.26.0
"@tiptap/extension-highlight": 3.26.0
"@tiptap/extension-image": 3.26.0
"@tiptap/extension-link": ^3.26.0
"@tiptap/extension-placeholder": ^3.26.0
"@tiptap/extension-table": 3.26.0
"@tiptap/extension-table-cell": 3.26.0
"@tiptap/extension-table-header": 3.26.0
"@tiptap/extension-table-row": 3.26.0
"@tiptap/extension-task-item": 3.26.0
"@tiptap/extension-task-list": 3.26.0
"@tiptap/extension-text-align": 3.26.0
"@tiptap/extension-text-style": 3.26.0
"@tiptap/extension-underline": 3.26.0
"@tiptap/react": ^3.26.0
"@tiptap/starter-kit": ^3.26.0
"@tiptap/extension-color": 3.26.1
"@tiptap/extension-highlight": 3.26.1
"@tiptap/extension-image": 3.26.1
"@tiptap/extension-link": ^3.26.1
"@tiptap/extension-placeholder": ^3.26.1
"@tiptap/extension-table": 3.26.1
"@tiptap/extension-table-cell": 3.26.1
"@tiptap/extension-table-header": 3.26.1
"@tiptap/extension-table-row": 3.26.1
"@tiptap/extension-task-item": 3.26.1
"@tiptap/extension-task-list": 3.26.1
"@tiptap/extension-text-align": 3.26.1
"@tiptap/extension-text-style": 3.26.1
"@tiptap/extension-underline": 3.26.1
"@tiptap/react": ^3.26.1
"@tiptap/starter-kit": ^3.26.1
"@trpc/client": ^11.17.0
"@trpc/next": ^11.17.0
"@trpc/react-query": ^11.17.0
@@ -92,7 +92,8 @@ catalog:
"@types/video.js": ^7.3.58
"@types/ws": ^8.18.1
"@types/xml2js": ^0.4.14
"@umami/node": ^0.4.0
posthog-js: ^1.255.0
posthog-node: ^4.17.0
"@vitejs/plugin-react": ^6.0.2
"@vitest/coverage-v8": ^4.1.8
"@vitest/ui": ^4.1.8
@@ -130,16 +131,16 @@ catalog:
glob: ^13.0.6
ical.js: ^2.2.1
ioredis: 5.11.1
isomorphic-dompurify: ^3.16.0
isomorphic-dompurify: ^3.17.0
jotai: ^2.20.1
jsdom: ^29.1.1
json5: ^2.2.3
jsonpath-plus: ^10.4.0
ldapts: 8.1.8
lodash.clonedeep: ^4.5.0
lucide-react: ^1.17.0
"mantine-contextmenu": ^9.2.1
mantine-datatable: ^9.2.2
lucide-react: ^1.18.0
"mantine-contextmenu": ^9.3.0
mantine-datatable: ^9.3.0
mantine-react-table: npm:mantine-react-table-open@9.0.3
mcp-handler: ^1.1.0
maria2: ^0.4.1
@@ -163,7 +164,7 @@ catalog:
react-quill-new: ^3.8.3
react-simple-code-editor: ^0.14.1
recharts: ^3.8.1
sass: ^1.100.0
sass: ^1.101.0
semantic-release: ^25.0.5
semver-parser: ^4.2.1
superjson: 2.2.6
@@ -216,7 +217,7 @@ overrides:
"prismjs@<1.30.0": ">=1.30.0"
"proxmox-api>undici": "7.27.1"
"react-is": "^19.2.7"
"rollup@>=4.0.0 <4.22.4": ">=4.61.1"
"rollup@>=4.0.0 <4.22.4": ">=4.62.0"
"sha.js@<=2.4.11": ">=2.4.12"
"tar-fs@>=3.0.0 <3.0.9": ">=3.1.2"
"tar-fs@>=2.0.0 <2.1.3": ">=3.1.2"
+1 -1
View File
@@ -1 +1 @@
[{"login":"ajnart","avatar_url":"https://avatars.githubusercontent.com/u/49837342?v=4"},{"login":"manuel-rw","avatar_url":"https://avatars.githubusercontent.com/u/30572287?v=4"},{"login":"Meierschlumpf","avatar_url":"https://avatars.githubusercontent.com/u/63781622?v=4"},{"login":"SeDemal","avatar_url":"https://avatars.githubusercontent.com/u/26098587?v=4"},{"login":"lammersbjorn","avatar_url":"https://avatars.githubusercontent.com/u/71191962?v=4"},{"login":"LarveyOfficial","avatar_url":"https://avatars.githubusercontent.com/u/39219859?v=4"},{"login":"c00ldude1oo","avatar_url":"https://avatars.githubusercontent.com/u/15677803?v=4"},{"login":"InterN0te","avatar_url":"https://avatars.githubusercontent.com/u/10882916?v=4"},{"login":"Aimsucks","avatar_url":"https://avatars.githubusercontent.com/u/1828486?v=4"},{"login":"JannesV","avatar_url":"https://avatars.githubusercontent.com/u/5984244?v=4"},{"login":"MauriceNino","avatar_url":"https://avatars.githubusercontent.com/u/18658092?v=4"},{"login":"hillaliy","avatar_url":"https://avatars.githubusercontent.com/u/950010?v=4"},{"login":"Skeeww","avatar_url":"https://avatars.githubusercontent.com/u/9639992?v=4"},{"login":"RichyHBM","avatar_url":"https://avatars.githubusercontent.com/u/5472275?v=4"},{"login":"Bonfire","avatar_url":"https://avatars.githubusercontent.com/u/5704760?v=4"},{"login":"wieli99","avatar_url":"https://avatars.githubusercontent.com/u/46794825?v=4"},{"login":"ishaanparlikar","avatar_url":"https://avatars.githubusercontent.com/u/43013132?v=4"},{"login":"Zareix","avatar_url":"https://avatars.githubusercontent.com/u/29818713?v=4"},{"login":"tuggan","avatar_url":"https://avatars.githubusercontent.com/u/4325608?v=4"},{"login":"Spillebulle","avatar_url":"https://avatars.githubusercontent.com/u/46653946?v=4"},{"login":"marektancak0106","avatar_url":"https://avatars.githubusercontent.com/u/25422667?v=4"},{"login":"spkesDE","avatar_url":"https://avatars.githubusercontent.com/u/1682314?v=4"},{"login":"j3lte","avatar_url":"https://avatars.githubusercontent.com/u/2557568?v=4"},{"login":"dslatt","avatar_url":"https://avatars.githubusercontent.com/u/5211001?v=4"},{"login":"Malong11-007","avatar_url":"https://avatars.githubusercontent.com/u/40298510?v=4"},{"login":"StefanB7","avatar_url":"https://avatars.githubusercontent.com/u/22056509?v=4"},{"login":"souravghosh01","avatar_url":"https://avatars.githubusercontent.com/u/37548139?v=4"},{"login":"SR3u","avatar_url":"https://avatars.githubusercontent.com/u/2380522?v=4"},{"login":"Rikpat","avatar_url":"https://avatars.githubusercontent.com/u/33869814?v=4"},{"login":"NormanJS","avatar_url":"https://avatars.githubusercontent.com/u/83409549?v=4"},{"login":"No-Maines-Land","avatar_url":"https://avatars.githubusercontent.com/u/20687725?v=4"},{"login":"stark1tty","avatar_url":"https://avatars.githubusercontent.com/u/69326376?v=4"},{"login":"Momcilo42","avatar_url":"https://avatars.githubusercontent.com/u/10118137?v=4"},{"login":"marius-arch","avatar_url":"https://avatars.githubusercontent.com/u/72494359?v=4"},{"login":"Lumilias","avatar_url":"https://avatars.githubusercontent.com/u/10852161?v=4"},{"login":"Havock94","avatar_url":"https://avatars.githubusercontent.com/u/7635248?v=4"},{"login":"Lollyde","avatar_url":"https://avatars.githubusercontent.com/u/11347524?v=4"},{"login":"krishnamuppaneni","avatar_url":"https://avatars.githubusercontent.com/u/4703366?v=4"},{"login":"devtobi","avatar_url":"https://avatars.githubusercontent.com/u/28538704?v=4"},{"login":"TyxTang","avatar_url":"https://avatars.githubusercontent.com/u/90897955?v=4"},{"login":"beanbag420","avatar_url":"https://avatars.githubusercontent.com/u/19630511?v=4"},{"login":"WillyJL","avatar_url":"https://avatars.githubusercontent.com/u/49810075?v=4"},{"login":"anonysoul","avatar_url":"https://avatars.githubusercontent.com/u/105715150?v=4"},{"login":"cospeedster","avatar_url":"https://avatars.githubusercontent.com/u/52749645?v=4"},{"login":"diederbert","avatar_url":"https://avatars.githubusercontent.com/u/162878798?v=4"},{"login":"digdilem","avatar_url":"https://avatars.githubusercontent.com/u/4052275?v=4"},{"login":"dinghino","avatar_url":"https://avatars.githubusercontent.com/u/14729459?v=4"},{"login":"gfomichev","avatar_url":"https://avatars.githubusercontent.com/u/1596146?v=4"},{"login":"gnattu","avatar_url":"https://avatars.githubusercontent.com/u/12995396?v=4"},{"login":"tuxpizza","avatar_url":"https://avatars.githubusercontent.com/u/84710786?v=4"},{"login":"xmarkurion","avatar_url":"https://avatars.githubusercontent.com/u/46654687?v=4"},{"login":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?v=4"},{"login":"taos15","avatar_url":"https://avatars.githubusercontent.com/u/122130728?v=4"},{"login":"arghyadipchak","avatar_url":"https://avatars.githubusercontent.com/u/32430374?v=4"},{"login":"AuthorShin","avatar_url":"https://avatars.githubusercontent.com/u/4959043?v=4"},{"login":"benniblot","avatar_url":"https://avatars.githubusercontentLine truncated
[{"login":"ajnart","avatar_url":"https://avatars.githubusercontent.com/u/49837342?v=4"},{"login":"manuel-rw","avatar_url":"https://avatars.githubusercontent.com/u/30572287?v=4"},{"login":"Meierschlumpf","avatar_url":"https://avatars.githubusercontent.com/u/63781622?v=4"},{"login":"SeDemal","avatar_url":"https://avatars.githubusercontent.com/u/26098587?v=4"},{"login":"lammersbjorn","avatar_url":"https://avatars.githubusercontent.com/u/71191962?v=4"},{"login":"LarveyOfficial","avatar_url":"https://avatars.githubusercontent.com/u/39219859?v=4"},{"login":"c00ldude1oo","avatar_url":"https://avatars.githubusercontent.com/u/15677803?v=4"},{"login":"InterN0te","avatar_url":"https://avatars.githubusercontent.com/u/10882916?v=4"},{"login":"Aimsucks","avatar_url":"https://avatars.githubusercontent.com/u/1828486?v=4"},{"login":"JannesV","avatar_url":"https://avatars.githubusercontent.com/u/5984244?v=4"},{"login":"MauriceNino","avatar_url":"https://avatars.githubusercontent.com/u/18658092?v=4"},{"login":"hillaliy","avatar_url":"https://avatars.githubusercontent.com/u/950010?v=4"},{"login":"Skeeww","avatar_url":"https://avatars.githubusercontent.com/u/9639992?v=4"},{"login":"RichyHBM","avatar_url":"https://avatars.githubusercontent.com/u/5472275?v=4"},{"login":"Bonfire","avatar_url":"https://avatars.githubusercontent.com/u/5704760?v=4"},{"login":"wieli99","avatar_url":"https://avatars.githubusercontent.com/u/46794825?v=4"},{"login":"ishaanparlikar","avatar_url":"https://avatars.githubusercontent.com/u/43013132?v=4"},{"login":"Zareix","avatar_url":"https://avatars.githubusercontent.com/u/29818713?v=4"},{"login":"tuggan","avatar_url":"https://avatars.githubusercontent.com/u/4325608?v=4"},{"login":"Spillebulle","avatar_url":"https://avatars.githubusercontent.com/u/46653946?v=4"},{"login":"marektancak0106","avatar_url":"https://avatars.githubusercontent.com/u/25422667?v=4"},{"login":"spkesDE","avatar_url":"https://avatars.githubusercontent.com/u/1682314?v=4"},{"login":"j3lte","avatar_url":"https://avatars.githubusercontent.com/u/2557568?v=4"},{"login":"dslatt","avatar_url":"https://avatars.githubusercontent.com/u/5211001?v=4"},{"login":"Malong11-007","avatar_url":"https://avatars.githubusercontent.com/u/40298510?v=4"},{"login":"StefanB7","avatar_url":"https://avatars.githubusercontent.com/u/22056509?v=4"},{"login":"souravghosh01","avatar_url":"https://avatars.githubusercontent.com/u/37548139?v=4"},{"login":"SR3u","avatar_url":"https://avatars.githubusercontent.com/u/2380522?v=4"},{"login":"Rikpat","avatar_url":"https://avatars.githubusercontent.com/u/33869814?v=4"},{"login":"NormanJS","avatar_url":"https://avatars.githubusercontent.com/u/83409549?v=4"},{"login":"No-Maines-Land","avatar_url":"https://avatars.githubusercontent.com/u/20687725?v=4"},{"login":"stark1tty","avatar_url":"https://avatars.githubusercontent.com/u/69326376?v=4"},{"login":"Momcilo42","avatar_url":"https://avatars.githubusercontent.com/u/10118137?v=4"},{"login":"marius-arch","avatar_url":"https://avatars.githubusercontent.com/u/72494359?v=4"},{"login":"Lumilias","avatar_url":"https://avatars.githubusercontent.com/u/10852161?v=4"},{"login":"Havock94","avatar_url":"https://avatars.githubusercontent.com/u/7635248?v=4"},{"login":"Lollyde","avatar_url":"https://avatars.githubusercontent.com/u/11347524?v=4"},{"login":"krishnamuppaneni","avatar_url":"https://avatars.githubusercontent.com/u/4703366?v=4"},{"login":"devtobi","avatar_url":"https://avatars.githubusercontent.com/u/28538704?v=4"},{"login":"TyxTang","avatar_url":"https://avatars.githubusercontent.com/u/90897955?v=4"},{"login":"beanbag420","avatar_url":"https://avatars.githubusercontent.com/u/19630511?v=4"},{"login":"WillyJL","avatar_url":"https://avatars.githubusercontent.com/u/49810075?v=4"},{"login":"anonysoul","avatar_url":"https://avatars.githubusercontent.com/u/105715150?v=4"},{"login":"cospeedster","avatar_url":"https://avatars.githubusercontent.com/u/52749645?v=4"},{"login":"diederbert","avatar_url":"https://avatars.githubusercontent.com/u/162878798?v=4"},{"login":"digdilem","avatar_url":"https://avatars.githubusercontent.com/u/4052275?v=4"},{"login":"dinghino","avatar_url":"https://avatars.githubusercontent.com/u/14729459?v=4"},{"login":"gfomichev","avatar_url":"https://avatars.githubusercontent.com/u/1596146?v=4"},{"login":"gnattu","avatar_url":"https://avatars.githubusercontent.com/u/12995396?v=4"},{"login":"tuxpizza","avatar_url":"https://avatars.githubusercontent.com/u/84710786?v=4"},{"login":"xmarkurion","avatar_url":"https://avatars.githubusercontent.com/u/46654687?v=4"},{"login":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?v=4"},{"login":"taos15","avatar_url":"https://avatars.githubusercontent.com/u/122130728?v=4"},{"login":"arghyadipchak","avatar_url":"https://avatars.githubusercontent.com/u/32430374?v=4"},{"login":"AuthorShin","avatar_url":"https://avatars.githubusercontent.com/u/4959043?v=4"},{"login":"benniblot","avatar_url":"https://avatars.githubusercontentLine truncated
+1 -1
View File
@@ -1 +1 @@
[{"id":"zaxon793-jy8gpl0v-d89pbrkd-emwl5v04","name":"Mike","slug":"guest-5da646e8","imageUrl":"https://images.opencollective.com/guest-5da646e8/avatar.png"},{"id":"ywz9j4av-god8pgwg-db36mr35-nxklb0e7","name":"Guest","slug":"guest-554ec68f","imageUrl":"https://images.opencollective.com/guest-554ec68f/avatar.png"},{"id":"mlo94zn7-x08dpo09-xlxpewga-3vjbrky5","name":"Robert Hermann","slug":"robert-hermann","imageUrl":"https://images.opencollective.com/robert-hermann/avatar.png"},{"id":"zaxon793-jy8gpl0n-8r3pbrkd-emwl5v04","name":"Sebastian Raubuch","slug":"sebastian-raubuch","imageUrl":"https://images.opencollective.com/sebastian-raubuch/avatar.png"},{"id":"nmlo94zn-7x08dpod-ykm6ewga-3vjbrky5","name":"Didier LUTHI","slug":"didier-luthi","imageUrl":"https://images.opencollective.com/didier-luthi/avatar.png"},{"id":"vedj9wro-z3a56dgk-z3z67blg-8x4m0ykn","name":"Guest","slug":"guest-b1459a68","imageUrl":"https://images.opencollective.com/guest-b1459a68/avatar.png"},{"id":"gm9bnk80-437xqry4-8vepvzeo-ljdayw5r","name":"Mohister","slug":"mohister","imageUrl":"https://images.opencollective.com/mohister/1d8a592/avatar.png"},{"id":"vrgbk357-l4x96e70-m0apomew-a0jdyzn8","name":"sidens","slug":"sidens","imageUrl":"https://images.opencollective.com/sidens/avatar.png"},{"id":"mlo94zn7-x08dpo0d-l7epewga-3vjbrky5","name":"Chris","slug":"guest-937065bb","imageUrl":"https://images.opencollective.com/guest-937065bb/avatar.png"},{"id":"k9mbw7y4-8r3zq3ol-7zlq0ej5-lavnodgx","name":"Nick W","slug":"guest-7501840a","imageUrl":"https://images.opencollective.com/guest-7501840a/avatar.png"},{"id":"e0adkjrv-8xwm69o8-5al67z5n-4l93bgoy","name":"Jeppedy","slug":"guest-ab78e46a","imageUrl":"https://images.opencollective.com/guest-ab78e46a/avatar.png"},{"id":"a47byg9n-xozdp8xo-jgm6mjlv-03rek5w8","name":"naru","slug":"guest-02fd264a","imageUrl":"https://images.opencollective.com/guest-02fd264a/avatar.png"},{"id":"3k0exgzn-m8yj64g3-ll865wao-9r7b4dlv","name":"Jared Hocutt","slug":"jared-hocutt","imageUrl":"https://images.opencollective.com/jared-hocutt/avatar.png"},{"id":"eng0kzdy-vor4pz8l-exopbma8-37xlw95j","name":"Incognito","slug":"user-e63f4a5b","imageUrl":"https://images.opencollective.com/user-e63f4a5b/avatar.png"},{"id":"8k03reyd-5agmq50v-8vyplbwo-z7j4nxv9","name":"dazi","slug":"guest-11663a46","imageUrl":"https://images.opencollective.com/guest-11663a46/avatar.png"},{"id":"vedj9wro-z3a56dgd-zwl67blg-8x4m0ykn","name":"ZoopaMario","slug":"zoopamario","imageUrl":"https://images.opencollective.com/zoopamario/bea900d/avatar.png"},{"id":"a47byg9n-xozdp8xe-xmb6mjlv-03rek5w8","name":"FlamebergUA","slug":"guest-a59fd500","imageUrl":"https://images.opencollective.com/guest-a59fd500/avatar.png"},{"id":"8k03reyd-5agmq50y-kzoplbwo-z7j4nxv9","name":"StLCards","slug":"guest-e1de33dc","imageUrl":"https://images.opencollective.com/guest-e1de33dc/avatar.png"},{"id":"ejoxl3az-45w9pa54-dk46y870-mgkbrvdn","name":"Varadha","slug":"guest-6f68eed9","imageUrl":"https://images.opencollective.com/guest-6f68eed9/avatar.png"},{"id":"jrkx5lmn-v904qjl0-3oz68bwa-7zdygoe3","name":"Guest","slug":"guest-6da419b5","imageUrl":"https://images.opencollective.com/guest-6da419b5/avatar.png"},{"id":"mywxoz34-09rl6k3z-lmlqvenb-dj7gk85a","name":"Guest","slug":"guest-122d7e0a","imageUrl":"https://images.opencollective.com/guest-122d7e0a/avatar.png"},{"id":"3z8arxve-ymko60vm-3eaqgl5n-bj9w704d","name":"Ricardo","slug":"ricardo34","imageUrl":"https://images.opencollective.com/ricardo34/avatar.png"},{"id":"e0adkjrv-8xwm69or-reo67z5n-4l93bgoy","name":"GoM","slug":"guest-3944feab","imageUrl":"https://images.opencollective.com/guest-3944feab/avatar.png"},{"id":"gm9bnk80-437xqrnr-r5o6vzeo-ljdayw5r","name":"Brent Maxwell","slug":"brentmaxwell","imageUrl":"https://images.opencollective.com/brentmaxwell/avatar.png"},{"id":"gnxdwzj3-le5mpwzd-ll0py8rv-bko04a97","name":"Eric G","slug":"guest-478270f1","imageUrl":"https://images.opencollective.com/guest-478270f1/avatar.png"},{"id":"v349mrwg-z75lpyjo-ez8pa08d-jeybknox","name":"ninja","slug":"guest-0bb6ba36","imageUrl":"https://images.opencollective.com/guest-0bb6ba36/avatar.png"},{"id":"ywz9j4av-god8pgw0-53y6mr35-nxklb0e7","name":"s11","slug":"guest-6e9a2588","imageUrl":"https://images.opencollective.com/guest-6e9a2588/avatar.png"},{"id":"mlo94zn7-x08dpo30-v73pewga-3vjbrky5","name":"Incognito","slug":"user-cbad11af","imageUrl":"https://images.opencollective.com/user-cbad11af/avatar.png"},{"id":"v349mrwg-z75lpy7l-yzgpa08d-jeybknox","name":"Ronald Simmons","slug":"ronald-simmons","imageUrl":"https://images.opencollective.com/ronald-simmons/avatar.png"},{"id":"7ywz9j4a-vgod8pgl-me9qmr35-nxklb0e7","name":"Joel","slug":"guest-3376ab02","imageUrl":"https://images.opencollective.com/guest-3376ab02/avatar.png"},{"id":"v349mrwg-z75lpyjw-kxzpa08d-jeybknox","name":"Gokay Yamankurt","slug":"gokay-yamankurt","imageUrl":"https://images.opencollective.com/gokay-yamankurt/avatar.png"},{"id":"v349mrwg-z75lpyjv-59rpa08d-jeybknox","name":"Rhiz3K","slug":"rhiz3k","imagLine truncated
[{"id":"zaxon793-jy8gpl0v-d89pbrkd-emwl5v04","name":"Mike","slug":"guest-5da646e8","imageUrl":"https://images.opencollective.com/guest-5da646e8/avatar.png"},{"id":"ywz9j4av-god8pgwg-db36mr35-nxklb0e7","name":"Guest","slug":"guest-554ec68f","imageUrl":"https://images.opencollective.com/guest-554ec68f/avatar.png"},{"id":"mlo94zn7-x08dpo09-xlxpewga-3vjbrky5","name":"Robert Hermann","slug":"robert-hermann","imageUrl":"https://images.opencollective.com/robert-hermann/avatar.png"},{"id":"zaxon793-jy8gpl0n-8r3pbrkd-emwl5v04","name":"Sebastian Raubuch","slug":"sebastian-raubuch","imageUrl":"https://images.opencollective.com/sebastian-raubuch/avatar.png"},{"id":"nmlo94zn-7x08dpod-ykm6ewga-3vjbrky5","name":"Didier LUTHI","slug":"didier-luthi","imageUrl":"https://images.opencollective.com/didier-luthi/avatar.png"},{"id":"vedj9wro-z3a56dgk-z3z67blg-8x4m0ykn","name":"Guest","slug":"guest-b1459a68","imageUrl":"https://images.opencollective.com/guest-b1459a68/avatar.png"},{"id":"gm9bnk80-437xqry4-8vepvzeo-ljdayw5r","name":"Mohister","slug":"mohister","imageUrl":"https://images.opencollective.com/mohister/1d8a592/avatar.png"},{"id":"vrgbk357-l4x96e70-m0apomew-a0jdyzn8","name":"sidens","slug":"sidens","imageUrl":"https://images.opencollective.com/sidens/avatar.png"},{"id":"mlo94zn7-x08dpo0d-l7epewga-3vjbrky5","name":"Chris","slug":"guest-937065bb","imageUrl":"https://images.opencollective.com/guest-937065bb/avatar.png"},{"id":"k9mbw7y4-8r3zq3ol-7zlq0ej5-lavnodgx","name":"Nick W","slug":"guest-7501840a","imageUrl":"https://images.opencollective.com/guest-7501840a/avatar.png"},{"id":"e0adkjrv-8xwm69o8-5al67z5n-4l93bgoy","name":"Jeppedy","slug":"guest-ab78e46a","imageUrl":"https://images.opencollective.com/guest-ab78e46a/avatar.png"},{"id":"a47byg9n-xozdp8xo-jgm6mjlv-03rek5w8","name":"naru","slug":"guest-02fd264a","imageUrl":"https://images.opencollective.com/guest-02fd264a/avatar.png"},{"id":"3k0exgzn-m8yj64g3-ll865wao-9r7b4dlv","name":"Jared Hocutt","slug":"jared-hocutt","imageUrl":"https://images.opencollective.com/jared-hocutt/avatar.png"},{"id":"eng0kzdy-vor4pz8l-exopbma8-37xlw95j","name":"Incognito","slug":"user-e63f4a5b","imageUrl":"https://images.opencollective.com/user-e63f4a5b/avatar.png"},{"id":"8k03reyd-5agmq50v-8vyplbwo-z7j4nxv9","name":"dazi","slug":"guest-11663a46","imageUrl":"https://images.opencollective.com/guest-11663a46/avatar.png"},{"id":"vedj9wro-z3a56dgd-zwl67blg-8x4m0ykn","name":"ZoopaMario","slug":"zoopamario","imageUrl":"https://images.opencollective.com/zoopamario/bea900d/avatar.png"},{"id":"a47byg9n-xozdp8xe-xmb6mjlv-03rek5w8","name":"FlamebergUA","slug":"guest-a59fd500","imageUrl":"https://images.opencollective.com/guest-a59fd500/avatar.png"},{"id":"8k03reyd-5agmq50y-kzoplbwo-z7j4nxv9","name":"StLCards","slug":"guest-e1de33dc","imageUrl":"https://images.opencollective.com/guest-e1de33dc/avatar.png"},{"id":"ejoxl3az-45w9pa54-dk46y870-mgkbrvdn","name":"Varadha","slug":"guest-6f68eed9","imageUrl":"https://images.opencollective.com/guest-6f68eed9/avatar.png"},{"id":"jrkx5lmn-v904qjl0-3oz68bwa-7zdygoe3","name":"Guest","slug":"guest-6da419b5","imageUrl":"https://images.opencollective.com/guest-6da419b5/avatar.png"},{"id":"mywxoz34-09rl6k3z-lmlqvenb-dj7gk85a","name":"Guest","slug":"guest-122d7e0a","imageUrl":"https://images.opencollective.com/guest-122d7e0a/avatar.png"},{"id":"3z8arxve-ymko60vm-3eaqgl5n-bj9w704d","name":"Ricardo","slug":"ricardo34","imageUrl":"https://images.opencollective.com/ricardo34/avatar.png"},{"id":"e0adkjrv-8xwm69or-reo67z5n-4l93bgoy","name":"GoM","slug":"guest-3944feab","imageUrl":"https://images.opencollective.com/guest-3944feab/avatar.png"},{"id":"gm9bnk80-437xqrnr-r5o6vzeo-ljdayw5r","name":"Brent Maxwell","slug":"brentmaxwell","imageUrl":"https://images.opencollective.com/brentmaxwell/avatar.png"},{"id":"gnxdwzj3-le5mpwzd-ll0py8rv-bko04a97","name":"Eric G","slug":"guest-478270f1","imageUrl":"https://images.opencollective.com/guest-478270f1/avatar.png"},{"id":"v349mrwg-z75lpyjo-ez8pa08d-jeybknox","name":"ninja","slug":"guest-0bb6ba36","imageUrl":"https://images.opencollective.com/guest-0bb6ba36/avatar.png"},{"id":"ywz9j4av-god8pgw0-53y6mr35-nxklb0e7","name":"s11","slug":"guest-6e9a2588","imageUrl":"https://images.opencollective.com/guest-6e9a2588/avatar.png"},{"id":"mlo94zn7-x08dpo30-v73pewga-3vjbrky5","name":"Incognito","slug":"user-cbad11af","imageUrl":"https://images.opencollective.com/user-cbad11af/avatar.png"},{"id":"v349mrwg-z75lpy7l-yzgpa08d-jeybknox","name":"Ronald Simmons","slug":"ronald-simmons","imageUrl":"https://images.opencollective.com/ronald-simmons/avatar.png"},{"id":"7ywz9j4a-vgod8pgl-me9qmr35-nxklb0e7","name":"Joel","slug":"guest-3376ab02","imageUrl":"https://images.opencollective.com/guest-3376ab02/avatar.png"},{"id":"v349mrwg-z75lpyjw-kxzpa08d-jeybknox","name":"Gokay Yamankurt","slug":"gokay-yamankurt","imageUrl":"https://images.opencollective.com/gokay-yamankurt/avatar.png"},{"id":"v349mrwg-z75lpyjv-59rpa08d-jeybknox","name":"Rhiz3K","slug":"rhiz3k","imagLine truncated
+1 -1
View File
@@ -1 +1 @@
[{"username":"carlchina","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/6697/medium/d22bbe7797bbeb30dbdc73a5648d329a_default.png"},{"username":"zielmann","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/7795/medium/ad22b8b8d5eb33e4154d53a454c862fd_default.png"},{"username":"Thalyn","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12494028/medium/5faf5acc945a874ed116c4567edaa09f_default.png"},{"username":"magnushj","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12503488/medium/68f32e33ea7b891960055c9f831f7344_default.png"},{"username":"almontegil","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12580457/medium/f4136cacbdfdb4c28ae7f85dc5f840db_default.png"},{"username":"andibing","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12664938/medium/b8be63e4dcb2e791ced1ffc9e3a049a5.jpg"},{"username":"gronare","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12680911/medium/c6eb14d1504156f34a158e507f73aa3d_default.png"},{"username":"SmartPhoneLover","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12701640/medium/ec95486662ec875cda080e778c3ff702.jpg"},{"username":"marcelotk_15","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12773227/medium/ecf6bea16ab0c873c131df2154ee9718_default.png"},{"username":"S3OD177","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13051544/medium/11dd990837f61f7e8f7d36b041a7fddb_default.png"},{"username":"marcg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13153301/medium/ebcf60fbf27deb148ec40a659566c6ff_default.png"},{"username":"BeersTeddy","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13185230/medium/2f1f4e1effe74a23422b195cbefb2a95_default.png"},{"username":"jamesmcmahon0","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13245578/medium/586aa873b4abddbd9abc6f3de99ab70e.jpeg"},{"username":"b1nar10","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13286752/medium/aaa1f083e04c572f953fde4563171e4a.jpeg"},{"username":"vannCN","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13330448/medium/9b8a9ee3611e51e951e22d5fd4eb7d8d.jpg"},{"username":"binswm","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13343482/medium/45dde0e6097b9b72705d2eba9dbbc276_default.png"},{"username":"SkewRam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13496556/medium/188f5c2deb7938eda51eb786cc4539ca.jpeg"},{"username":"raphcatarino","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13547726/medium/b003511e67df13a4b4b5689488fa8099.jpg"},{"username":"shillos5","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13600557/medium/b17650b2b84f829d54fa548c44c1ab27.jpeg"},{"username":"wolong98","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13641407/medium/f4634edc58c7857a357e5293543c15cf.jpg"},{"username":"spair0039","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14012333/medium/72430e96027c09c19141cac38eae4617.png"},{"username":"MajorMarcin","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14072183/medium/0a197e64bb92b6ea94cecbb607512c45.jpg"},{"username":"KosmoMoustache","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14103535/medium/51c438cdd9f86e8811c75f4869de479c.png"},{"username":"Soochaehwa","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14118689/medium/496a1ce63111547bf455a1e0a7ac75f1_default.png"},{"username":"garryfield","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14187035/medium/520c964706676045f6eeec1b08edc880.jpg"},{"username":"droidenko","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14444264/medium/4aa3a8e824f72bc9e5ec0d8de307095e.jpeg"},{"username":"maathis","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14489950/medium/6eeddf13a757ee35f78f1763f94d95e1.jpeg"},{"username":"bukvam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14546502/medium/a819dc40a13c57395a17dc46e847d3ce.jpg"},{"username":"gm.cinalli","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14670666/medium/2d466a0fdbda40764526be86c97c0ab4.jpeg"},{"username":"antoine2tt","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14722148/medium/f88d926900862dd59007ea4b3419cb9d.png"},{"username":"cretzen","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14799754/medium/3ba5c1805ec20c000d5810c07985afe9.jpg"},{"username":"ktKongTong","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14817246/medium/97cfc3c028dbdaf85ebd1102da71e58c.jpeg"},{"username":"marinkaberg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14861042/medium/2d5c4e62613f03082f3e645fa92efd59.jpeg"},{"username":"djismgaming","avatarUrl":"https://crowLine truncated
[{"username":"carlchina","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/6697/medium/d22bbe7797bbeb30dbdc73a5648d329a_default.png"},{"username":"zielmann","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/7795/medium/ad22b8b8d5eb33e4154d53a454c862fd_default.png"},{"username":"Thalyn","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12494028/medium/5faf5acc945a874ed116c4567edaa09f_default.png"},{"username":"magnushj","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12503488/medium/68f32e33ea7b891960055c9f831f7344_default.png"},{"username":"almontegil","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12580457/medium/f4136cacbdfdb4c28ae7f85dc5f840db_default.png"},{"username":"andibing","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12664938/medium/b8be63e4dcb2e791ced1ffc9e3a049a5.jpg"},{"username":"gronare","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12680911/medium/c6eb14d1504156f34a158e507f73aa3d_default.png"},{"username":"SmartPhoneLover","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12701640/medium/ec95486662ec875cda080e778c3ff702.jpg"},{"username":"marcelotk_15","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12773227/medium/ecf6bea16ab0c873c131df2154ee9718_default.png"},{"username":"S3OD177","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13051544/medium/11dd990837f61f7e8f7d36b041a7fddb_default.png"},{"username":"marcg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13153301/medium/ebcf60fbf27deb148ec40a659566c6ff_default.png"},{"username":"BeersTeddy","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13185230/medium/2f1f4e1effe74a23422b195cbefb2a95_default.png"},{"username":"jamesmcmahon0","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13245578/medium/586aa873b4abddbd9abc6f3de99ab70e.jpeg"},{"username":"b1nar10","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13286752/medium/aaa1f083e04c572f953fde4563171e4a.jpeg"},{"username":"vannCN","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13330448/medium/9b8a9ee3611e51e951e22d5fd4eb7d8d.jpg"},{"username":"binswm","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13343482/medium/45dde0e6097b9b72705d2eba9dbbc276_default.png"},{"username":"SkewRam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13496556/medium/188f5c2deb7938eda51eb786cc4539ca.jpeg"},{"username":"raphcatarino","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13547726/medium/b003511e67df13a4b4b5689488fa8099.jpg"},{"username":"shillos5","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13600557/medium/b17650b2b84f829d54fa548c44c1ab27.jpeg"},{"username":"wolong98","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13641407/medium/f4634edc58c7857a357e5293543c15cf.jpg"},{"username":"spair0039","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14012333/medium/72430e96027c09c19141cac38eae4617.png"},{"username":"MajorMarcin","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14072183/medium/0a197e64bb92b6ea94cecbb607512c45.jpg"},{"username":"KosmoMoustache","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14103535/medium/51c438cdd9f86e8811c75f4869de479c.png"},{"username":"Soochaehwa","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14118689/medium/496a1ce63111547bf455a1e0a7ac75f1_default.png"},{"username":"garryfield","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14187035/medium/520c964706676045f6eeec1b08edc880.jpg"},{"username":"droidenko","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14444264/medium/4aa3a8e824f72bc9e5ec0d8de307095e.jpeg"},{"username":"maathis","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14489950/medium/6eeddf13a757ee35f78f1763f94d95e1.jpeg"},{"username":"bukvam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14546502/medium/a819dc40a13c57395a17dc46e847d3ce.jpg"},{"username":"gm.cinalli","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14670666/medium/2d466a0fdbda40764526be86c97c0ab4.jpeg"},{"username":"antoine2tt","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14722148/medium/f88d926900862dd59007ea4b3419cb9d.png"},{"username":"cretzen","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14799754/medium/3ba5c1805ec20c000d5810c07985afe9.jpg"},{"username":"ktKongTong","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14817246/medium/97cfc3c028dbdaf85ebd1102da71e58c.jpeg"},{"username":"marinkaberg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14861042/medium/2d5c4e62613f03082f3e645fa92efd59.jpeg"},{"username":"djismgaming","avatarUrl":"https://crowLine truncated