Compare commits

..

3 Commits

Author SHA1 Message Date
Louis Lam
cde6db7444 WIP 2024-10-28 13:22:38 +08:00
Louis Lam
6efec6f0c9 WIP 2024-10-28 13:19:12 +08:00
Louis Lam
dccaf9dac3 WIP 2024-10-28 13:15:07 +08:00
127 changed files with 4556 additions and 8357 deletions

View File

@@ -32,6 +32,7 @@ tsconfig.json
/extra/healthcheck.exe /extra/healthcheck.exe
/extra/healthcheck /extra/healthcheck
/extra/exe-builder /extra/exe-builder
/extra/push-examples
/extra/uptime-kuma-push /extra/uptime-kuma-push
# Comment the following line if you want to rebuild the healthcheck binary # Comment the following line if you want to rebuild the healthcheck binary

View File

@@ -1,2 +0,0 @@
---
blank_issues_enabled: false

17
.github/ISSUE_TEMPLATE/security.md vendored Normal file
View File

@@ -0,0 +1,17 @@
---
name: "Security Issue"
about: "Just for alerting @louislam, do not provide any details here"
title: "Security Issue"
ref: "main"
labels:
- security
---
DO NOT PROVIDE ANY DETAILS HERE. Please privately report to https://github.com/louislam/uptime-kuma/security/advisories/new.
Why need this issue? It is because GitHub Advisory do not send a notification to @louislam, it is a workaround to do so.
Your GitHub Advisory URL:

View File

@@ -1,45 +0,0 @@
---
name: "ЁЯЫбя╕П Security Issue"
description: |
Notify Louis Lam about a security concern. Please do NOT include any sensitive details in this issue.
# title: "Security Issue"
labels: [security]
assignees: [louislam]
body:
- type: "markdown"
attributes:
value: |
## **тЪая╕П Report a Security Vulnerability**
### **IMPORTANT: DO NOT SHARE VULNERABILITY DETAILS HERE**
If you have discovered a security vulnerability, please report it securely using the GitHub Security Advisory.
**Note**: This issue is only for notifying the maintainers of the repository, as the GitHub Security Advisory does not automatically send notifications.
- **Confidentiality**: The information you provide in the GitHub Security Advisory will initially remain confidential. However, once the vulnerability is addressed, the advisory will be publicly disclosed on GitHub.
- **Access and Visibility**: Until the advisory is published, it will only be visible to the maintainers of the repository and invited collaborators.
- **Credit**: You will be automatically credited as a contributor for identifying and reporting the vulnerability. Your contribution will be reflected in the MITRE Credit System.
- **Important Reminder**: **Do not include any sensitive or detailed vulnerability information in this issue.** This issue is only for sharing the advisory URL to notify the maintainers of the repository, not for discussing the vulnerability itself.
**Thank you for helping us keep Uptime Kuma secure!**
## **Step 1: Submit a GitHub Security Advisory**
Right-click the link below and select `Open link in new tab` to access the page. This will keep the security issue open, allowing you to easily return and paste the Advisory URL here later.
тЮбя╕П [Create a New Security Advisory](https://github.com/louislam/uptime-kuma/security/advisories/new)
## **Step 2: Share the Advisory URL**
Once you've created your advisory, please share the URL below. This will notify Louis Lam and enable them to take the appropriate action.
- type: "textarea"
id: github-advisory-url
validations:
required: true
attributes:
label: "GitHub Advisory URL for @louislam"
placeholder: |
Please paste the GitHub Advisory URL here. Only the URL is required.
Example: https://github.com/louislam/uptime-kuma/security/advisories/GHSA-8h5r-7t6l-q3kz

View File

@@ -78,7 +78,7 @@ jobs:
e2e-test: e2e-test:
needs: [ ] needs: [ ]
runs-on: ubuntu-24.04-arm runs-on: ARM64
steps: steps:
- run: git config --global core.autocrlf false # Mainly for Windows - run: git config --global core.autocrlf false # Mainly for Windows
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@@ -62,7 +62,6 @@ Requirements:
- Platform - Platform
- тЬЕ Major Linux distros such as Debian, Ubuntu, CentOS, Fedora and ArchLinux etc. - тЬЕ Major Linux distros such as Debian, Ubuntu, CentOS, Fedora and ArchLinux etc.
- тЬЕ Windows 10 (x64), Windows Server 2012 R2 (x64) or higher - тЬЕ Windows 10 (x64), Windows Server 2012 R2 (x64) or higher
- тЭМ FreeBSD / OpenBSD / NetBSD
- тЭМ Replit / Heroku - тЭМ Replit / Heroku
- [Node.js](https://nodejs.org/en/download/) 18 / 20.4 - [Node.js](https://nodejs.org/en/download/) 18 / 20.4
- [npm](https://docs.npmjs.com/cli/) 9 - [npm](https://docs.npmjs.com/cli/) 9

View File

@@ -1,7 +0,0 @@
exports.up = function (knex) {
return knex("monitor").whereNull("json_path_operator").update("json_path_operator", "==");
};
exports.down = function (knex) {
// changing the json_path_operator back to null for all "==" is not possible anymore
// we have lost the context which fields have been set explicitely in >= v2.0 and which would need to be reverted
};

View File

@@ -1,13 +0,0 @@
// Fix #5721: Change proxy port column type to integer to support larger port numbers
exports.up = function (knex) {
return knex.schema
.alterTable("proxy", function (table) {
table.integer("port").alter();
});
};
exports.down = function (knex) {
return knex.schema.alterTable("proxy", function (table) {
table.smallint("port").alter();
});
};

View File

@@ -5,7 +5,7 @@ const util = require("../../src/util");
util.polyfill(); util.polyfill();
const version = process.env.RELEASE_BETA_VERSION; const version = process.env.VERSION;
console.log("Beta Version: " + version); console.log("Beta Version: " + version);

19
extra/env2arg.js Normal file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env node
const childProcess = require("child_process");
let env = process.env;
let cmd = process.argv[2];
let args = process.argv.slice(3);
let replacedArgs = [];
for (let arg of args) {
for (let key in env) {
arg = arg.replaceAll(`$${key}`, env[key]);
}
replacedArgs.push(arg);
}
let child = childProcess.spawn(cmd, replacedArgs);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);

1
extra/exe-builder/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
я╗┐packages/

View File

@@ -0,0 +1,35 @@
я╗┐<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.Tracing" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.1" newVersion="4.1.1.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.InteropServices" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,84 @@
я╗┐using System.ComponentModel;
namespace UptimeKuma {
partial class DownloadForm {
/// <summary>
/// Required designer variable.
/// </summary>
private IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DownloadForm));
this.progressBar = new System.Windows.Forms.ProgressBar();
this.label = new System.Windows.Forms.Label();
this.labelData = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// progressBar
//
this.progressBar.Location = new System.Drawing.Point(12, 12);
this.progressBar.Name = "progressBar";
this.progressBar.Size = new System.Drawing.Size(472, 41);
this.progressBar.TabIndex = 0;
//
// label
//
this.label.Location = new System.Drawing.Point(12, 59);
this.label.Name = "label";
this.label.Size = new System.Drawing.Size(472, 23);
this.label.TabIndex = 1;
this.label.Text = "Preparing...";
//
// labelData
//
this.labelData.Location = new System.Drawing.Point(12, 82);
this.labelData.Name = "labelData";
this.labelData.Size = new System.Drawing.Size(472, 23);
this.labelData.TabIndex = 2;
//
// DownloadForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(496, 117);
this.Controls.Add(this.labelData);
this.Controls.Add(this.label);
this.Controls.Add(this.progressBar);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "DownloadForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Uptime Kuma";
this.Load += new System.EventHandler(this.DownloadForm_Load);
this.ResumeLayout(false);
}
private System.Windows.Forms.Label labelData;
private System.Windows.Forms.Label label;
private System.Windows.Forms.ProgressBar progressBar;
#endregion
}
}

View File

@@ -0,0 +1,204 @@
я╗┐using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
namespace UptimeKuma {
public partial class DownloadForm : Form {
private readonly Queue<DownloadItem> downloadQueue = new();
private readonly WebClient webClient = new();
private DownloadItem currentDownloadItem;
public DownloadForm() {
InitializeComponent();
}
private void DownloadForm_Load(object sender, EventArgs e) {
webClient.DownloadProgressChanged += DownloadProgressChanged;
webClient.DownloadFileCompleted += DownloadFileCompleted;
label.Text = "Reading latest version...";
// Read json from https://uptime.kuma.pet/version
var versionJson = new WebClient().DownloadString("https://uptime.kuma.pet/version");
var versionObj = JsonConvert.DeserializeObject<Version>(versionJson);
var nodeVersion = versionObj.nodejs;
var uptimeKumaVersion = versionObj.latest;
var hasUpdateFile = File.Exists("update");
if (!Directory.Exists("node")) {
downloadQueue.Enqueue(new DownloadItem {
URL = $"https://nodejs.org/dist/v{nodeVersion}/node-v{nodeVersion}-win-x64.zip",
Filename = "node.zip",
TargetFolder = "node"
});
}
if (!Directory.Exists("core") || hasUpdateFile) {
// It is update, rename the core folder to core.old
if (Directory.Exists("core")) {
// Remove the old core.old folder
if (Directory.Exists("core.old")) {
Directory.Delete("core.old", true);
}
Directory.Move("core", "core.old");
}
downloadQueue.Enqueue(new DownloadItem {
URL = $"https://github.com/louislam/uptime-kuma/archive/refs/tags/{uptimeKumaVersion}.zip",
Filename = "core.zip",
TargetFolder = "core"
});
File.WriteAllText("version.json", versionJson);
// Delete the update file
if (hasUpdateFile) {
File.Delete("update");
}
}
DownloadNextFile();
}
void DownloadNextFile() {
if (downloadQueue.Count > 0) {
var item = downloadQueue.Dequeue();
currentDownloadItem = item;
// Download if the zip file is not existing
if (!File.Exists(item.Filename)) {
label.Text = item.URL;
webClient.DownloadFileAsync(new Uri(item.URL), item.Filename);
} else {
progressBar.Value = 100;
label.Text = "Use local " + item.Filename;
DownloadFileCompleted(null, null);
}
} else {
npmSetup();
}
}
void npmSetup() {
labelData.Text = "";
var npm = "..\\node\\npm.cmd";
var cmd = $"{npm} ci --production & {npm} run download-dist & exit";
var startInfo = new ProcessStartInfo {
FileName = "cmd.exe",
Arguments = $"/k \"{cmd}\"",
RedirectStandardOutput = false,
RedirectStandardError = false,
RedirectStandardInput = true,
UseShellExecute = false,
CreateNoWindow = false,
WorkingDirectory = "core"
};
var process = new Process();
process.StartInfo = startInfo;
process.EnableRaisingEvents = true;
process.Exited += (_, e) => {
progressBar.Value = 100;
if (process.ExitCode == 0) {
Task.Delay(2000).ContinueWith(_ => {
Application.Restart();
});
label.Text = "Done";
} else {
label.Text = "Failed, exit code: " + process.ExitCode;
}
};
process.Start();
label.Text = "Installing dependencies and download dist files";
progressBar.Value = 50;
process.WaitForExit();
}
void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) {
progressBar.Value = e.ProgressPercentage;
var total = e.TotalBytesToReceive / 1024;
var current = e.BytesReceived / 1024;
if (total > 0) {
labelData.Text = $"{current}KB/{total}KB";
}
}
void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) {
Extract(currentDownloadItem);
DownloadNextFile();
}
void Extract(DownloadItem item) {
if (Directory.Exists(item.TargetFolder)) {
var dir = new DirectoryInfo(item.TargetFolder);
dir.Delete(true);
}
if (Directory.Exists("temp")) {
var dir = new DirectoryInfo("temp");
dir.Delete(true);
}
labelData.Text = $"Extracting {item.Filename}...";
ZipFile.ExtractToDirectory(item.Filename, "temp");
string[] dirList;
// Move to the correct level
dirList = Directory.GetDirectories("temp");
if (dirList.Length > 0) {
var dir = dirList[0];
// As sometime ExtractToDirectory is still locking the directory, loop until ok
while (true) {
try {
Directory.Move(dir, item.TargetFolder);
break;
} catch (Exception exception) {
Thread.Sleep(1000);
}
}
} else {
MessageBox.Show("Unexcepted Error: Cannot move extracted files, folder not found.");
}
labelData.Text = $"Extracted";
if (Directory.Exists("temp")) {
var dir = new DirectoryInfo("temp");
dir.Delete(true);
}
File.Delete(item.Filename);
}
}
public class DownloadItem {
public string URL { get; set; }
public string Filename { get; set; }
public string TargetFolder { get; set; }
}
}

View File

@@ -0,0 +1,377 @@
я╗┐<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAMAMDAAAAEAIACoJQAANgAAACAgAAABACAAqBAAAN4lAAAQEAAAAQAgAGgEAACGNgAAKAAAADAA
AABgAAAAAQAgAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA////BPT09Bfu7u4e8fHxJPPz8yv19fUy9fX1M/Pz8yvx8fEk9vb2HPPz8xXMzMwFAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//
/wHv7+8f7u7uPPPz81Tx8fFs8fHxgPHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGB8fHxcfHx8V3x8fFI9PT0MOvr6w0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADy8vIU8fHxS/Dw8Hbx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fFr9PT0R/Dw8CIAAAABAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA8vLyFPHx8Vnx8fGB8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fFs9fX1Mb+/vwQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAICAgALy8vI88fHxfvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvLy8nby8vI8gICAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAzMzMBfHx8Vrx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8vLyYf///wwAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMzMwF8vLyYPHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8W/z8/MWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADv7+9R8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLw8PB26urqDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLy8ijx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgu7w7Ifj79ud2u7PtNLrw83P677dzeu85c3r
u+rM67rwzOu68c7rverQ68Dj0uvD3NbuyM3b7c+64u7apujv5ZPx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxXgAAAAEAAAAAAAAAAAAAAAAAAAAA4+PjCfDw
8Hfx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLd7tSmzeu92MbqsvvG6bH/xumy/8fq
s//H6rP/yOq0/8jqtf/J6rb/yeq2/8rrt//K67j/y+u4/8vruf/M67r/zOu7/83ru//Q7MDx1u7Kz9/t
163s8OuJ8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgu/v7y8AAAAAAAAAAAAA
AAAAAAAA7u7uPfHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC5PDdl8jqtuTE6a7/xOmv/8Xp
sP/G6bH/xumx/8bpsv/H6rP/x+qz/8jqtP/I6rX/yeq2/8nqtv/K67f/yuu4/8vruP/L67n/zOu6/8zr
u//N67v/zey8/87svf/P67742e3Mx+jv5ZLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvDw
8HWAgIACAAAAAAAAAACqqqoD8vLyc/Hx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLf7degxOiu+cPo
rf/D6a7/xOmu/8Xpr//F6bD/xumx/8bpsf/G6bL/x+qz/8fqs//I6rT/yOq1/8nqtv/J6rb/yuu3/8rr
uP/L67j/y+u5/8zruv/M67v/zeu7/83svP/O7L3/zuy9/87svfzc7tK28fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fEkAAAAAAAAAADz8/Mq8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgunv
5o3D6a/0wuis/8Lorf/D6K3/xOmu/8Tprv/F6a//xemw/8bpsf/G6bH/xumy/8fqs//H6rP/yOq0/8jq
tf/J6rb/yeq2/8rrt//K67j/y+u4/8vruf/M67r/zOu7/83ru//N7Lz/zuy9/87svf/O7L3/3e/TtPHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLy8vJNAAAAAAAAAADy8vJM8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgszqutDB6Kv/weir/8LorP/D6K3/w+it/8Tprv/E6a7/xemv/8XpsP/G6bH/xumx/8bp
sv/H6rP/x+qz/8jqtP/I6rX/yeq2/8nqtv/K67f/yuu4/8vruP/L67n/zOu6/8zru//N67v/zey8/87s
vf/O7L3/zuy++u3w6Yzx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLy8vJ1AAAAAAAAAADx8fFr8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC6O/kjsDoqvzA6Kr/weir/8Loq//C6Kz/w+it/8Porf/E6a7/xOmu/8Xp
r//F6bD/xumx/8bpsf/G6bL/x+qz/8fqtP/I6rT/yOq1/8nqtv/J6rb/yuu3/8rruP/L67n/y+u5/8zr
uv/M67v/zeu7/83svP/O7L3/zuy9/93u07Xx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC////Bv//
/wfx8fGB8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC1ezJsr/nqf/A56n/weiq/8Hoq//C6Kv/wuis/8Po
rf/D6K3/xOmu/8Pprv+856T/uOed/7bmmv+05Zf/teWZ/7jnnf+86KP/wOio/8fqs//J6rb/yeq2/8rr
t//K67j/y+u5/8vruf/M67r/zOu7/83ru//N7Lz/zuy9/9buyNLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8vLyE/Ly8hPx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGCy+q6zr/nqP/A56n/wOep/8Ho
qv/B6Kv/wuir/8LorP+u5Y//neF2/5bgav+V4Gr/luBr/5fhbP+Y4W7/meFv/5rhcf+b4nL/nOJ0/53i
dv+j5H//reaM/7nnnf/E6q//y+y4/8vruf/L67n/zOu6/8zru//N67v/zey8/9Lsxd/x8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC7+/vIPb29hzx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGCx+m03L/n
qP+/56j/wOep/8Dnqf/B6Kr/weir/7nmn/+R32T/kt9l/5PfZ/+U4Gj/leBq/5bga/+X4W3/mOFu/5nh
b/+a4XH/m+Jy/5zidP+d4nX/nuN3/5/jeP+f4nn/weqq/8rruP/L67n/y+u5/8zruv/M67v/zeu7/9Ls
w+Lx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8PDwI/Hx8SXx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGCxeix5L/nqP+/56j/v+eo/8Dnqf/A56n/weiq/7Pllv+Q3mP/kd9k/5LfZf+T32f/lOBo/5Xg
av+W4Gv/l+Ft/5jhbv+Z4W//muFx/5vicv+c4nT/neJ1/57jd/+f43j/xOmu/8rrt//K67j/y+u5/8vr
uf/M67r/zOu7/9Tsxtfx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC9PT0GO/v7yDx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGCx+m037/nqP+/56j/v+eo/7/nqP/A56n/wOip/7TmmP+P3mH/kN5j/5Hf
ZP+S32b/k99n/5TgaP+V4Gr/luBr/5fhbf+Y4W7/meFw/5rhcf+b4nL/nOJ0/53idf+h5Hz/yuu2/8nq
t//K67f/yuu4/8vruf/L67n/zOu6/9ftysrx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC7e3tDvT0
9Bfx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGCyOq117/nqP+/56j/v+eo/7/nqP+/56j/wOep/7vn
of+O3mD/j95h/5DeY/+R32T/kt9m/5PfZ/+U4Gj/leBq/5bga/+X4W3/mOFu/5nhcP+a4nH/m+Jy/5zi
dP+r5Yr/yOq1/8nqtv/J6rf/yuu3/8rruP/L67n/y+u5/9zu1LHx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLz8/OA////A+7u7g/x8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGCz+q+xb/nqP+/56j/v+eo/7/n
qP+/56j/v+eo/8Dnqf+S4Gb/jt5g/4/eYf+Q3mP/kd9k/5LfZv+T32f/lOBo/5Xgav+W4Gv/l+Ft/5jh
bv+Z4XD/muJx/5vic/+4553/yOq0/8jqtf/J6rb/yeq3/8rrt//K67j/y+u5/+bw4Zfx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fFrAAAAAP///wHz8/N88fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC1+zMrr/n
qP+/56j/v+eo/7/nqP+/56j/v+eo/7/nqP+f4Xn/jd5f/47eYP+P3mH/kN5j/5HfZP+S32b/k99n/5Tg
af+V4Gr/luBr/5fhbf+Y4W7/meFw/5vic//F6rD/x+q0/8jqtP/I6rX/yeq2/8nqt//K67f/zOu88u/x
74Px8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLv7+9QAAAAAAAAAADw8PBm8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC5e7gk7/nqP+/56j/v+eo/7/nqP+/56j/v+eo/7/nqP+u5I//jN1d/43eX/+O3mD/j95h/5De
Y/+R32T/kt9m/5PfZ/+U4Gn/leBq/5bga/+X4W3/mOFu/6rliP/G6rL/x+qz/8fqtP/I6rT/yOq1/8nq
tv/J6rf/1OzGy/Hx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YL19fUzAAAAAAAAAADy8vJO8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgsPoru2/56j/v+eo/7/nqP+/56j/v+eo/7/nqP++6Kf/j95i/4zd
Xf+N3l//jt5g/4/eYv+Q3mP/kd9k/5LfZv+T32f/lOBp/5Xgav+W4Gz/l+Ft/7voov/G6bL/xuqy/8fq
s//H6rT/yOq1/8jqtf/J6rb/4e/Zo/Hx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLw8PARAAAAAAAA
AADu7u4u8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgszpvMm/56j/v+eo/7/nqP+/56j/v+eo/7/n
qP+/56j/q+SL/4vdXP+M3V3/jd5f/47eYP+P3mL/kN9j/5HfZP+S32b/k99n/5Tgaf+V4Gr/qOOH/8Xp
sP/G6bH/xumy/8bqsv/H6rP/x+q0/8jqtf/K67jy8PHwhPHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8WoAAAAAAAAAAAAAAADo6OgL8fHxgfHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxguDv2J2/56j/v+eo/7/n
qP+/56j/v+eo/7/nqP+/56j/v+eo/6Xjgv+L3Vz/jN1d/43eX/+O3mD/j95i/5DfY/+R32T/kt9m/5Pf
Z/+k44D/xOmu/8XpsP/F6bD/xumx/8bpsv/G6rL/x+qz/8fqtP/W7cnB8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvPz80AAAAAAAAAAAAAAAAAAAAAA8PDwZ/Hx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLD6K/rv+eo/7/nqP+/56j/v+eo/7/nqP+/56j/v+eo/7/nqP+u5I//kt5n/4zdXf+N3l//jt5g/4/e
Yv+Q32P/luFs/67kj//D6K3/xOmu/8Tpr//F6bD/xemw/8bpsf/G6bL/xuqy/8fqtP7o7+WR8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvPz8xYAAAAAAAAAAAAAAAAAAAAA8vLyPPHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLV7ci0v+eo/7/nqP+/56j/v+eo/7/nqP+/56j/v+eo/7/nqP+/56j/wOio/7Xl
mv+u5I7/rOSM/67kj/+35pz/wumr/8Lorf/D6K3/w+it/8Tprv/E6a//xemw/8XpsP/G6bH/xumy/9Ds
wNPx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8vLyZQAAAAAAAAAAAAAAAAAAAAAAAAAA////DPHx
8YDx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGCx+m03L/nqP+/56j/v+eo/7/nqP+/56j/v+eo/7/n
qP+/56j/v+eo/7/nqP+/56j/wOep/8Doqv/B6Kr/weir/8LorP/C6K3/w+it/8Porv/E6a7/xOmv/8Xp
sP/F6bD/yOq18uvw6Yvx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC7+/vMQAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAPHx8Vzx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC6O/ij8LorPG/56j/v+eo/7/n
qP+/56j/v+eo/7/nqP+/56j/v+eo/7/nqP+/56j/v+eo/8Dnqf/A6Kr/weiq/8Hoq//C6Kz/wuit/8Po
rf/D6K7/xOmu/8Tpr//F6bH74u/anvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLw8PB6////BQAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPPz8yrx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxguHu
2pnB56v2v+eo/7/nqP+/56j/v+eo/7/nqP+/56j/v+eo/7/nqP+/56j/v+eo/7/nqP/A56n/wOiq/8Ho
q//B6Kv/wuis/8Lorf/D6K3/w+mu/8Tprv3b7dKq8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fFJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHy8vJf8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLi7tyXwumt8L/nqP+/56j/v+eo/7/nqP+/56j/v+eo/7/nqP+/56j/v+eo/7/n
qP+/56j/wOep/8Doqv/B6Kv/weir/8LorP/C6K3/xOiv+d7u1aTx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvLy8nb///8KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADv7+8Q8/Pze/Hx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC6/Dpiszqu82/56j/v+eo/7/nqP+/56j/v+eo/7/n
qP+/56j/v+eo/7/nqP+/56j/v+eo/8Dnqf/A6Kr/weir/8Hoq//H6bTj5e7elfHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvPz8yoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA9fX1MvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLe7tShx+mz3r/n
qP+/56j/v+eo/7/nqP+/56j/v+eo/7/nqP+/56j/v+eo/7/nqP/A56n/xumy5drtz6rv8e+D8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8vLyTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPHx8Unx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgubv45DU68e2y+q6z8XoseTD6a7uweir9MPpru7F6bHly+q50tLsxLrl796U8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLy8vJh////AwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wHx8fFZ8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8Wzf398IAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8D8/PzVfHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8PDwZujo
6AsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA////AfHx8Ujx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fFa////BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADz8/Mp8vLydvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8/PzfPHx8TcAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////CvLy8lDz8/N/8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvPz84Hx8fFa8PDwEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADw8PAR8vLyTvHx8X3x8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fF/8/PzVvT09BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wXz8/Mq8/PzU/Hx8XDx8fGB8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLy8vJz8fHxWO/v7y////8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8G7e3tHfLy
8ifu7u4u8PDwNPT09C/y8vIo7+/vH+Pj4wkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAP///////wAA////////AAD///////8AAP//gAf//wAA//gAAD//AAD/wAAAB/8AAP+A
AAAB/wAA/gAAAAB/AAD8AAAAAD8AAPgAAAAAHwAA8AAAAAAPAADwAAAAAAcAAOAAAAAABwAA4AAAAAAD
AADAAAAAAAMAAMAAAAAAAwAAwAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAA
AAAAAQAAgAAAAAABAACAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAABwAAwAAAAAAH
AADgAAAAAAcAAOAAAAAADwAA4AAAAAAPAADwAAAAAB8AAPAAAAAAHwAA+AAAAAA/AAD8AAAAAD8AAPwA
AAAAfwAA/gAAAAD/AAD/AAAAAf8AAP+AAAAD/wAA/8AAAAf/AAD/8AAAH/8AAP/8AAA//wAA//8AAf//
AAD//+AP//8AAP///////wAA////////AAD///////8AACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAgICAAu/v7xD09PQX7u7uHvDw8CP29vYb8vLyFOrq6gwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICA
gALy8vIm7+/vT/Pz82fz8/N98fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvDw8Hrw8PBm7+/vUPT0
9C3o6OgLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOPj
4wnz8/NC8vLydPHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YHy8vJj8/PzKoCAgAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADx8fEl8vLydfHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxcfHx8SUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA9PT0LfHx8YDx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8/PzgPLy8j0AAAABAAAAAAAA
AAAAAAAAAAAAAO3t7Rzx8fGA8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLr8OmM5O7emeTv
3Z7h79mj5fDem+nv45Tu8u6H8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvLy
8joAAAAAAAAAAAAAAAD///8E8fHxbvHx8YLx8fGC8fHxgvHx8YLx8fGC7vDshtns0K7N67zayeq288fq
s//I6rT/yOq1/8nqtv/K67f/y+u4/8vruf/P7L7w0+zF29vv0Lrn8OKX8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8/PzfvPz8xUAAAAAAAAAAPX19TLx8fGC8fHxgvHx8YLx8fGC8fHxgt3u1KXF6rHzxOmv/8Xp
sP/G6bH/xumy/8fqs//I6rT/yOq1/8nqtv/K67f/y+u4/8vruf/M67v/zey8/87svf/S7MPj4u7Zp/Hx
8YLx8fGC8fHxgvHx8YLx8fGC8/PzVQAAAAAAAAAA8fHxavHx8YLx8fGC8fHxgvHx8YLf7defwuis/cPo
rf/E6a7/xOmv/8XpsP/G6bH/xumy/8fqs//I6rT/yOq1/8nqtv/K67f/y+u4/8vruv/M67v/zey8/87s
vf/N67z/3e7SufHx8YLx8fGC8fHxgvHx8YLz8/N8////Bf///w3x8fGC8fHxgvHx8YLx8fGC8fHxgsXp
sOnB6Kv/wuis/8Porf/E6a7/xOmv/8XpsP/G6bH/xumy/8fqs//I6rT/yOq1/8nqtv/K67f/y+u4/8vr
uv/M67v/zey8/87svf/O67z96/Hoj/Hx8YLx8fGC8fHxgvHx8YLy8vIm8/PzK/Hx8YLx8fGC8fHxgvHx
8YLg79icwOep/8Hoqv/B6Kv/wuis/8Porf/E6a7/wuit/73opP+76KL/u+eh/77opv/D6a3/yeu1/8nq
tv/K67f/y+u5/8zruv/M67v/zey8/87svf/d7tSz8fHxgvHx8YLx8fGC8fHxgvHx8Tby8vI68fHxgvHx
8YLx8fGC8fHxgtTrxre/56j/wOep/8Hoqv/B6Kv/uOad/53idv+V4Gn/leBq/5fhbP+Y4W//muFx/5vi
c/+e4Xb/puWD/7PmlP/D6a3/y+u5/8zruv/M67v/zey8/9rtzsHx8fGC8fHxgvHx8YLx8fGC8/PzQfPz
80Lx8fGC8fHxgvHx8YLx8fGC0OvAwr/nqP+/56j/wOep/8Hoqv+o44b/kd9k/5LfZv+U4Gj/leBq/5fh
bf+Y4W//muFx/5vic/+d4nX/n+N3/7fnm//K67j/y+u5/8zruv/M67v/2u3QvPHx8YLx8fGC8fHxgvHx
8YLy8vI98/PzP/Hx8YLx8fGC8fHxgvHx8YLQ6sK/v+eo/7/nqP+/56j/wOep/6jjhv+P3mL/kd9k/5Lf
Zv+U4Gj/leBr/5fhbf+Y4W//muFx/5zic/+d4nX/v+mm/8nqt//K67j/y+u5/8zruv/f79au8fHxgvHx
8YLx8fGC8fHxgvX19TLx8fE38fHxgvHx8YLx8fGC8fHxgtTrybO/56j/v+eo/7/nqP+/56j/sOSS/47e
YP+P3mL/kd9k/5LfZv+U4Gj/leBr/5fhbf+Z4W//muJx/5/jd//H6bP/yeq2/8nqt//K67j/y+u5/+nv
45Tx8fGC8fHxgvHx8YLx8fGC7+/vIPHx8SXx8fGC8fHxgvHx8YLx8fGC4e/Zm7/nqP+/56j/v+eo/7/n
qP+956X/jt5h/47eYP+P3mL/kd9k/5LfZv+U4Gn/luBr/5fhbf+Z4W//q+aK/8fqs//I6rT/yeq2/8nq
t//N7Lvw8fHxgvHx8YLx8fGC8fHxgvPz84D///8G6+vrDfHx8YLx8fGC8fHxgvHx8YLv8e+Dweis87/n
qP+/56j/v+eo/7/nqP+d4XX/jN1e/47eYP+P3mL/kd9k/5PfZ/+U4Gn/luBr/5fhbf+86KP/xuqy/8fq
s//I6rX/yeq2/9Tsx8nx8fGC8fHxgvHx8YLx8fGC8PDwaAAAAAAAAAAA8fHxbPHx8YLx8fGC8fHxgvHx
8YLM6rrMv+eo/7/nqP+/56j/v+eo/7blmv+N3V//jN1e/47eYP+Q3mL/kd9k/5PfZ/+U4Gn/qeSH/8Xp
sP/G6bH/xuqy/8fqs//I6rX/5fDem/Hx8YLx8fGC8fHxgvHx8YLz8/M/AAAAAAAAAADz8/NB8fHxgvHx
8YLx8fGC8fHxgt3s06O/56j/v+eo/7/nqP+/56j/v+eo/7Xmmf+U32n/jN1e/47eYP+Q3mL/k99o/6zk
i//D6a7/xemv/8XpsP/G6bH/xuqy/8vqu+jx8fGC8fHxgvHx8YLx8fGC8fHxgvPz8xUAAAAAAAAAAPT0
9Bfx8fGC8fHxgvHx8YLx8fGC8fHvg8Tpsee/56j/v+eo/7/nqP+/56j/v+eo/7/nqP+35pz/suWV/7Xm
mf/A6Kj/wuit/8Porf/E6a7/xemv/8XpsP/G6bH/3e3UqvHx8YLx8fGC8fHxgvHx8YLw8PBmAAAAAAAA
AAAAAAAAAAAAAPHx8W7x8fGC8fHxgvHx8YLx8fGC4u7cmMHnqvm/56j/v+eo/7/nqP+/56j/v+eo/7/n
qP+/56j/wOep/8Hoqv/C6Kz/wuit/8Porf/E6a7/xemv/9Hrwszx8fGC8fHxgvHx8YLx8fGC8fHxgvX1
9TEAAAAAAAAAAAAAAAAAAAAA7u7uO/Hx8YLx8fGC8fHxgvHx8YLx8fGC3e7SpMHoqfq/56j/v+eo/7/n
qP+/56j/v+eo/7/nqP+/56j/wOip/8Hoq//C6Kz/wuit/8Porf/O67zV8PHwhPHx8YLx8fGC8fHxgvHx
8YLy8vJ2////BQAAAAAAAAAAAAAAAAAAAACqqqoD8PDwafHx8YLx8fGC8fHxgvHx8YLx8fGC4O/YnMTo
ruy/56j/v+eo/7/nqP+/56j/v+eo/7/nqP+/56j/wOip/8Hoq//C6Kz90uvEwe/x74Px8fGC8fHxgvHx
8YLx8fGC8fHxgvPz8ykAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADz8/MW8fHxfPHx8YLx8fGC8fHxgvHx
8YLx8fGC8PLuhdXtyLXF6bHlv+eo/7/nqP+/56j/v+eo/7/nqP/B6Kv0zeq8zOXv4JTx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLy8vJNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADy8vIm8fHxgPHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLs8OmJ4e/Zm93u06Pf7def5+/hkvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxXf///wIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADy8vIo8/PzffHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8VnMzMwFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAD29vYb8fHxbvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvPz83/v7+9BgICAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMzMwF8/PzQPLy8nnx8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgvPz84Hx8fFc9PT0GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////B/X19TLx8fFc8PDwevHx
8YLx8fGC8fHxgvHx8YLx8fGC8fHxgPHx8Wv09PRE9PT0FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA7+/vEPb29hvw8PAj7+/vH/T09Be/v78EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////8B///wAA//wAAD/wAAAP4AAAB+AA
AAfAAAADwAAAA4AAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAADwAAAA8AAAAPAAAAH4AAAB+AA
AA/wAAAP+AAAH/gAAD/+AAB//wAB///AA///+B////////////8oAAAAEAAAACAAAAABACAAAAAAAAAE
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////CfDw8BH///8GAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAAu7u7i7x8fFe8PDwevHx8YLx8fGC8fHxgvDw
8Hvx8fFs7+/vT/Dw8CMAAAABAAAAAAAAAAAAAAAA5ubmCvLy8l/x8fGC8fHxgvHx8YLx8fGC8fHxgvHx
8YLx8fGC8fHxgvHx8YLx8fGC8/PzZu7u7g8AAAAAAAAAAPHx8V3x8fGC8fHxgunv5o7Z7c200+vFytTs
xc7W7cnH2+7QueLu2qbu8OyH8fHxgvHx8YLx8fFu////BfHx8STx8fGC8fHxgtrtzq3D6a/8xemw/8bp
sv/I6rT/yeq2/8vruP/M67v/z+u++Nzu0bjx8fGC8fHxgu/v7zDx8fFI8fHxguzw6ojC56z3wuis/8Tp
rv/E6q3/weiq/8fqsv/J6rb/y+u5/8zru//N67z/6/HpjfHx8YLy8vJN8fHxXPHx8YLg79icv+eo/8Ho
qv+k4n//lOBo/5fhbf+a4XH/n+J5/7Pmlv/L67n/zOu7/+Xw353x8fGC8fHxXvHx8Vrx8fGC4O3Zm7/n
qP+/56j/nuF3/5HfZP+U4Gj/l+Ft/5ricf+x5pL/yeq3/8vruf/r8emN8fHxgu/v70/x8fFK8fHxguzw
6ojA6Kn8v+eo/6njiP+O3mD/kd9k/5Tgaf+X4W3/vuim/8jqtP/N67zr8fHxgvHx8YLy8vI68/PzK/Hx
8YLx8fGCx+m03L/nqP++6Kb/meBw/47eYP+S32X/q+SL/8XpsP/G6rL/1+zLvvHx8YLz8/OB8PDwEdXV
1Qbx8fF98fHxgt/t1Z/A56j9v+eo/7/nqP+656H/vuim/8Lorf/E6a7/yOq18Ovw6Yvx8fGC8vLyYwAA
AAAAAAAA8fHxR/Hx8YLx8fGC2O3NrMDnqfq/56j/v+eo/7/nqP/B6Kv/xumy7OTu3Zfx8fGC8/PzgfLy
8icAAAAAAAAAAP///wPz8/Nm8fHxgvHx8YLo7+SO0+zFuczquszM6bzJ1+zMru7w7Ibx8fGC8fHxgvHx
8UcAAAAAAAAAAAAAAAAAAAAA4+PjCfHx8Vzx8fGC8fHxgvHx8YLx8fGC8fHxgvHx8YLx8fGC8fHxgfPz
80D///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8/PzK/Ly8mDz8/N+8fHxgvHx8YLy8vJ68vLyUezs
7BsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAevr6w3j4+MJAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD8fwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIAB
AADAAwAAwAMAAOAHAADwDwAA/n8AAP//AAA=
</value>
</data>
</root>

View File

@@ -0,0 +1,3 @@
я╗┐<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura DisableCompression='true' IncludeDebugSymbols='false' />
</Weavers>

View File

@@ -0,0 +1,141 @@
я╗┐<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCompression" type="xs:boolean">
<xs:annotation>
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCleanup" type="xs:boolean">
<xs:annotation>
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -0,0 +1,262 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Win32;
using Newtonsoft.Json;
using UptimeKuma.Properties;
namespace UptimeKuma {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args) {
var cwd = Path.GetDirectoryName(Application.ExecutablePath);
if (cwd != null) {
Environment.CurrentDirectory = cwd;
}
bool isIntranet = args.Contains("--intranet");
if (isIntranet) {
Console.WriteLine("The --intranet argument was provided, so we will not try to access the internet. The first time this application runs you'll need to run it without the --intranet param or copy the result from another machine to the intranet server.");
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new UptimeKumaApplicationContext(isIntranet));
}
}
public class UptimeKumaApplicationContext : ApplicationContext
{
private static Mutex mutex = null;
const string appName = "Uptime Kuma";
private NotifyIcon trayIcon;
private Process process;
private MenuItem statusMenuItem;
private MenuItem runWhenStarts;
private MenuItem openMenuItem;
private RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
private readonly bool intranetOnly;
public UptimeKumaApplicationContext(bool intranetOnly) {
// Single instance only
bool createdNew;
mutex = new Mutex(true, appName, out createdNew);
if (!createdNew) {
return;
}
this.intranetOnly = intranetOnly;
var startingText = "Starting server...";
trayIcon = new NotifyIcon();
trayIcon.Text = startingText;
runWhenStarts = new MenuItem("Run when system starts", RunWhenStarts);
runWhenStarts.Checked = registryKey.GetValue(appName) != null;
statusMenuItem = new MenuItem(startingText);
statusMenuItem.Enabled = false;
openMenuItem = new MenuItem("Open", Open);
openMenuItem.Enabled = false;
trayIcon.Icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location);
trayIcon.ContextMenu = new ContextMenu(new MenuItem[] {
statusMenuItem,
openMenuItem,
//new("Debug Console", DebugConsole),
runWhenStarts,
new("Check for Update...", CheckForUpdate),
new("Visit GitHub...", VisitGitHub),
new("About", About),
new("Exit", Exit),
});
trayIcon.MouseDoubleClick += new MouseEventHandler(Open);
trayIcon.Visible = true;
var hasUpdateFile = File.Exists("update");
if (!hasUpdateFile && Directory.Exists("core") && Directory.Exists("node") && Directory.Exists("core/node_modules") && Directory.Exists("core/dist")) {
// Go go go
StartProcess();
} else {
DownloadFiles();
}
}
void DownloadFiles() {
if (intranetOnly) {
return;
}
var form = new DownloadForm();
form.Closed += Exit;
form.Show();
}
private void RunWhenStarts(object sender, EventArgs e) {
if (registryKey == null) {
MessageBox.Show("Error: Unable to set startup registry key.");
return;
}
if (runWhenStarts.Checked) {
registryKey.DeleteValue(appName, false);
runWhenStarts.Checked = false;
} else {
registryKey.SetValue(appName, Application.ExecutablePath);
runWhenStarts.Checked = true;
}
}
void StartProcess() {
var startInfo = new ProcessStartInfo {
FileName = "node/node.exe",
Arguments = "server/server.js --data-dir=\"../data/\"",
RedirectStandardOutput = false,
RedirectStandardError = false,
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = "core"
};
process = new Process();
process.StartInfo = startInfo;
process.EnableRaisingEvents = true;
process.Exited += ProcessExited;
try {
process.Start();
//Open(null, null);
// Async task to check if the server is ready
Task.Run(() => {
var runningText = "Server is running";
using TcpClient tcpClient = new TcpClient();
while (true) {
try {
tcpClient.Connect("127.0.0.1", 3001);
statusMenuItem.Text = runningText;
openMenuItem.Enabled = true;
trayIcon.Text = runningText;
break;
} catch (Exception) {
System.Threading.Thread.Sleep(2000);
}
}
});
} catch (Exception e) {
MessageBox.Show("Startup failed: " + e.Message, "Uptime Kuma Error");
}
}
void StopProcess() {
process?.Kill();
}
void Open(object sender, EventArgs e) {
Process.Start("http://localhost:3001");
}
void DebugConsole(object sender, EventArgs e) {
}
void CheckForUpdate(object sender, EventArgs e) {
if (intranetOnly) {
return;
}
// Check version.json exists
if (File.Exists("version.json")) {
// Load version.json and compare with the latest version from GitHub
var currentVersionObj = JsonConvert.DeserializeObject<Version>(File.ReadAllText("version.json"));
var versionJson = new WebClient().DownloadString("https://uptime.kuma.pet/version");
var latestVersionObj = JsonConvert.DeserializeObject<Version>(versionJson);
// Compare version, if the latest version is newer, then update
if (new System.Version(latestVersionObj.latest).CompareTo(new System.Version(currentVersionObj.latest)) > 0) {
var result = MessageBox.Show("A new version is available. Do you want to update?", "Update", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes) {
// Create a empty file `update`, so the app will download the core files again at startup
File.Create("update").Close();
trayIcon.Visible = false;
process?.Kill();
// Restart the app, it will download the core files again at startup
Application.Restart();
}
} else {
MessageBox.Show("You are using the latest version.");
}
}
}
void VisitGitHub(object sender, EventArgs e) {
if (intranetOnly) {
MessageBox.Show("You have parsed in --intranet so we will not try to access the internet or visit github.com, please go to https://github.com/louislam/uptime-kuma if you want to visit github.");
return;
}
Process.Start("https://github.com/louislam/uptime-kuma");
}
void About(object sender, EventArgs e)
{
MessageBox.Show("Uptime Kuma Windows Runtime v1.0.0" + Environment.NewLine + "┬й 2023 Louis Lam", "Info");
}
void Exit(object sender, EventArgs e)
{
// Hide tray icon, otherwise it will remain shown until user mouses over it
trayIcon.Visible = false;
process?.Kill();
Application.Exit();
}
void ProcessExited(object sender, EventArgs e) {
if (process.ExitCode != 0) {
var line = "";
while (!process.StandardOutput.EndOfStream)
{
line += process.StandardOutput.ReadLine();
}
MessageBox.Show("Uptime Kuma exited unexpectedly. Exit code: " + process.ExitCode + " " + line);
}
trayIcon.Visible = false;
Application.Exit();
}
}
}

View File

@@ -0,0 +1,36 @@
я╗┐using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Uptime Kuma")]
[assembly: AssemblyDescription("A portable executable for running Uptime Kuma")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Uptime Kuma")]
[assembly: AssemblyProduct("Uptime Kuma")]
[assembly: AssemblyCopyright("Copyright ┬й 2023 Louis Lam")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("86B40AFB-61FC-433D-8C31-650B0F32EA8F")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]

View File

@@ -0,0 +1,62 @@
я╗┐//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace UptimeKuma.Properties {
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder",
"4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance",
"CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState
.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if ((resourceMan == null)) {
global::System.Resources.ResourceManager temp =
new global::System.Resources.ResourceManager("UptimeKuma.Properties.Resources",
typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState
.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get { return resourceCulture; }
set { resourceCulture = value; }
}
}
}

View File

@@ -0,0 +1,117 @@
я╗┐<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,23 @@
я╗┐//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace UptimeKuma.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(
"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance =
((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get { return defaultInstance; }
}
}
}

View File

@@ -0,0 +1,7 @@
я╗┐<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,203 @@
я╗┐<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2DB53988-1D93-4AC0-90C4-96ADEAAC5C04}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>UptimeKuma</RootNamespace>
<AssemblyName>uptime-kuma</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<ApplicationIcon>..\..\public\favicon.ico</ApplicationIcon>
<LangVersion>9</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>COPY "$(SolutionDir)bin\Debug\uptime-kuma.exe" "%UserProfile%\Desktop\uptime-kuma-win64\"</PostBuildEvent>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.AppContext, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll</HintPath>
</Reference>
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Console, Version=4.0.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Console.4.3.1\lib\net46\System.Console.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=7.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Diagnostics.DiagnosticSource.7.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Diagnostics.Tracing, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll</HintPath>
</Reference>
<Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
</Reference>
<Reference Include="System.IO, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Linq, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Linq.4.3.0\lib\net463\System.Linq.dll</HintPath>
</Reference>
<Reference Include="System.Linq.Expressions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http, Version=4.1.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll</HintPath>
</Reference>
<Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Reflection, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath>
</Reference>
<Reference Include="System.Runtime, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Extensions, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.InteropServices, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
</Reference>
<Reference Include="System.Text.RegularExpressions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Text.RegularExpressions.4.3.1\lib\net463\System.Text.RegularExpressions.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Xml.ReaderWriter.4.3.1\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="DownloadForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="DownloadForm.Designer.cs">
<DependentUpon>DownloadForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Version.cs" />
<EmbeddedResource Include="DownloadForm.resx">
<DependentUpon>DownloadForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="..\..\public\favicon.ico">
<Link>favicon.ico</Link>
</None>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Content Include=".gitignore" />
<Content Include="app.manifest" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets'))" />
</Target>
<Import Project="packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" />
</Project>

View File

@@ -0,0 +1,16 @@
я╗┐
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UptimeKuma", "UptimeKuma.csproj", "{2DB53988-1D93-4AC0-90C4-96ADEAAC5C04}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2DB53988-1D93-4AC0-90C4-96ADEAAC5C04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2DB53988-1D93-4AC0-90C4-96ADEAAC5C04}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2DB53988-1D93-4AC0-90C4-96ADEAAC5C04}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2DB53988-1D93-4AC0-90C4-96ADEAAC5C04}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,3 @@
я╗┐<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=UptimeKuma_002FProperties_002FResources/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/ResxEditorPersonal/Initialized/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -0,0 +1,9 @@
я╗┐namespace UptimeKuma {
public class Version {
public string latest { get; set; }
public string slow { get; set; }
public string beta { get; set; }
public string nodejs { get; set; }
public string exe { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
я╗┐<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel element will disable file and registry virtualization.
Remove this element if your application requires this virtualization for backwards
compatibility.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

View File

@@ -0,0 +1,54 @@
я╗┐<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.NETCore.Platforms" version="7.0.0" targetFramework="net472" />
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net472" />
<package id="NETStandard.Library" version="2.0.3" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.2" targetFramework="net472" />
<package id="System.AppContext" version="4.3.0" targetFramework="net472" />
<package id="System.Console" version="4.3.1" targetFramework="net472" />
<package id="System.Diagnostics.DiagnosticSource" version="7.0.1" targetFramework="net472" />
<package id="System.Net.Http" version="4.3.4" targetFramework="net472" />
<package id="System.Runtime.Extensions" version="4.3.1" targetFramework="net472" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.1" targetFramework="net472" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.2" targetFramework="net472" />
<package id="System.Text.RegularExpressions" version="4.3.1" targetFramework="net472" />
<package id="System.Xml.ReaderWriter" version="4.3.1" targetFramework="net472" />
<package id="System.Memory" version="4.5.5" targetFramework="net472" />
<package id="System.Net.Primitives" version="4.3.1" targetFramework="net472" />
<package id="System.Runtime" version="4.3.1" targetFramework="net472" />
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
<package id="System.Collections" version="4.3.0" targetFramework="net472" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net472" />
<package id="System.Globalization" version="4.3.0" targetFramework="net472" />
<package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net472" />
<package id="System.IO" version="4.3.0" targetFramework="net472" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net472" />
<package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net472" />
<package id="System.IO.FileSystem" version="4.3.0" targetFramework="net472" />
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Linq" version="4.3.0" targetFramework="net472" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net472" />
<package id="System.Net.Sockets" version="4.3.0" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.ObjectModel" version="4.3.0" targetFramework="net472" />
<package id="System.Reflection" version="4.3.0" targetFramework="net472" />
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net472" />
<package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />
<package id="System.Runtime.Handles" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net472" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net472" />
<package id="System.Threading" version="4.3.0" targetFramework="net472" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net472" />
<package id="System.Threading.Timer" version="4.3.0" targetFramework="net472" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net472" />
</packages>

View File

@@ -15,6 +15,7 @@ if (newVersion) {
// Process package.json // Process package.json
pkg.version = newVersion; pkg.version = newVersion;
pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion); pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion);
pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion);
fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n"); fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n");
// Process README.md // Process README.md

6
extra/press-any-key.js Normal file
View File

@@ -0,0 +1,6 @@
console.log("Git Push and Publish the release note on github, then press any key to continue");
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.on("data", process.exit.bind(process, 0));

View File

@@ -1,64 +0,0 @@
import "dotenv/config";
import {
ver,
buildDist,
buildImage,
checkDocker,
checkTagExists,
checkVersionFormat,
getRepoNames,
pressAnyKey,
execSync, uploadArtifacts,
} from "./lib.mjs";
import semver from "semver";
const repoNames = getRepoNames();
const version = process.env.RELEASE_BETA_VERSION;
const githubToken = process.env.RELEASE_GITHUB_TOKEN;
console.log("RELEASE_BETA_VERSION:", version);
if (!githubToken) {
console.error("GITHUB_TOKEN is required");
process.exit(1);
}
// Check if the version is a valid semver
checkVersionFormat(version);
// Check if the semver identifier is "beta"
const semverIdentifier = semver.prerelease(version);
console.log("Semver identifier:", semverIdentifier);
if (semverIdentifier[0] !== "beta") {
console.error("VERSION should have a semver identifier of 'beta'");
process.exit(1);
}
// Check if docker is running
checkDocker();
// Check if the tag exists
await checkTagExists(repoNames, version);
// node extra/beta/update-version.js
execSync("node ./extra/beta/update-version.js");
// Build frontend dist
buildDist();
// Build slim image (rootless)
buildImage(repoNames, [ "beta-slim-rootless", ver(version, "slim-rootless") ], "rootless", "BASE_IMAGE=louislam/uptime-kuma:base2-slim");
// Build full image (rootless)
buildImage(repoNames, [ "beta-rootless", ver(version, "rootless") ], "rootless");
// Build slim image
buildImage(repoNames, [ "beta-slim", ver(version, "slim") ], "release", "BASE_IMAGE=louislam/uptime-kuma:base2-slim");
// Build full image
buildImage(repoNames, [ "beta", version ], "release");
await pressAnyKey();
// npm run upload-artifacts
uploadArtifacts(version, githubToken);

View File

@@ -1,57 +0,0 @@
import "dotenv/config";
import {
ver,
buildDist,
buildImage,
checkDocker,
checkTagExists,
checkVersionFormat,
getRepoNames,
pressAnyKey, execSync, uploadArtifacts
} from "./lib.mjs";
const repoNames = getRepoNames();
const version = process.env.RELEASE_VERSION;
const githubToken = process.env.RELEASE_GITHUB_TOKEN;
console.log("RELEASE_VERSION:", version);
if (!githubToken) {
console.error("GITHUB_TOKEN is required");
process.exit(1);
}
// Check if the version is a valid semver
checkVersionFormat(version);
// Check if docker is running
checkDocker();
// Check if the tag exists
await checkTagExists(repoNames, version);
// node extra/beta/update-version.js
execSync("node extra/update-version.js");
// Build frontend dist
buildDist();
// Build slim image (rootless)
buildImage(repoNames, [ "2-slim-rootless", ver(version, "slim-rootless") ], "rootless", "BASE_IMAGE=louislam/uptime-kuma:base2-slim");
// Build full image (rootless)
buildImage(repoNames, [ "2-rootless", ver(version, "rootless") ], "rootless");
// Build slim image
buildImage(repoNames, [ "next-slim", "2-slim", ver(version, "slim") ], "release", "BASE_IMAGE=louislam/uptime-kuma:base2-slim");
// Build full image
buildImage(repoNames, [ "next", "2", version ], "release");
await pressAnyKey();
// npm run upload-artifacts
uploadArtifacts(version, githubToken);
// node extra/update-wiki-version.js
execSync("node extra/update-wiki-version.js");

View File

@@ -1,251 +0,0 @@
import "dotenv/config";
import * as childProcess from "child_process";
import semver from "semver";
export const dryRun = process.env.RELEASE_DRY_RUN === "1";
if (dryRun) {
console.info("Dry run enabled.");
}
/**
* Check if docker is running
* @returns {void}
*/
export function checkDocker() {
try {
childProcess.execSync("docker ps");
} catch (error) {
console.error("Docker is not running. Please start docker and try again.");
process.exit(1);
}
}
/**
* Get Docker Hub repository name
*/
export function getRepoNames() {
if (process.env.RELEASE_REPO_NAMES) {
// Split by comma
return process.env.RELEASE_REPO_NAMES.split(",").map((name) => name.trim());
}
return [
"louislam/uptime-kuma",
"ghcr.io/louislam/uptime-kuma",
];
}
/**
* Build frontend dist
* @returns {void}
*/
export function buildDist() {
if (!dryRun) {
childProcess.execSync("npm run build", { stdio: "inherit" });
} else {
console.info("[DRY RUN] npm run build");
}
}
/**
* Build docker image and push to Docker Hub
* @param {string[]} repoNames Docker Hub repository names
* @param {string[]} tags Docker image tags
* @param {string} target Dockerfile's target name
* @param {string} buildArgs Docker build args
* @param {string} dockerfile Path to Dockerfile
* @param {string} platform Build platform
* @returns {void}
*/
export function buildImage(repoNames, tags, target, buildArgs = "", dockerfile = "docker/dockerfile", platform = "linux/amd64,linux/arm64,linux/arm/v7") {
let args = [
"buildx",
"build",
"-f",
dockerfile,
"--platform",
platform,
];
for (let repoName of repoNames) {
// Add tags
for (let tag of tags) {
args.push("-t", `${repoName}:${tag}`);
}
}
args = [
...args,
"--target",
target,
];
// Add build args
if (buildArgs) {
args.push("--build-arg", buildArgs);
}
args = [
...args,
".",
"--push",
];
if (!dryRun) {
childProcess.spawnSync("docker", args, { stdio: "inherit" });
} else {
console.log(`[DRY RUN] docker ${args.join(" ")}`);
}
}
/**
* Check if the version already exists on Docker Hub
* TODO: use semver to compare versions if it is greater than the previous?
* @param {string[]} repoNames repository name (Only check the name with single slash)
* @param {string} version Version to check
* @returns {void}
*/
export async function checkTagExists(repoNames, version) {
// Skip if the tag is not on Docker Hub
// louislam/uptime-kuma
let dockerHubRepoNames = repoNames.filter((name) => {
return name.split("/").length === 2;
});
for (let repoName of dockerHubRepoNames) {
await checkTagExistsSingle(repoName, version);
}
}
/**
* Check if the version already exists on Docker Hub
* @param {string} repoName repository name
* @param {string} version Version to check
* @returns {Promise<void>}
*/
export async function checkTagExistsSingle(repoName, version) {
console.log(`Checking if version ${version} exists on Docker Hub:`, repoName);
// Get a list of tags from the Docker Hub repository
let tags = [];
// It is mainly to check my careless mistake that I forgot to update the release version in .env, so `page_size` is set to 100 is enough, I think.
const response = await fetch(`https://hub.docker.com/v2/repositories/${repoName}/tags/?page_size=100`);
if (response.ok) {
const data = await response.json();
tags = data.results.map((tag) => tag.name);
} else {
console.error("Failed to get tags from Docker Hub");
process.exit(1);
}
// Check if the version already exists
if (tags.includes(version)) {
console.error(`Version ${version} already exists`);
process.exit(1);
}
}
/**
* Check the version format
* @param {string} version Version to check
* @returns {void}
*/
export function checkVersionFormat(version) {
if (!version) {
console.error("VERSION is required");
process.exit(1);
}
// Check the version format, it should be a semver and must be like this: "2.0.0-beta.0"
if (!semver.valid(version)) {
console.error("VERSION is not a valid semver version");
process.exit(1);
}
}
/**
* Press any key to continue
* @returns {Promise<void>}
*/
export function pressAnyKey() {
console.log("Git Push and Publish the release note on github, then press any key to continue");
process.stdin.setRawMode(true);
process.stdin.resume();
return new Promise(resolve => process.stdin.once("data", data => {
process.stdin.setRawMode(false);
process.stdin.pause();
resolve();
}));
}
/**
* Append version identifier
* @param {string} version Version
* @param {string} identifier Identifier
* @returns {string} Version with identifier
*/
export function ver(version, identifier) {
const obj = semver.parse(version);
if (obj.prerelease.length === 0) {
obj.prerelease = [ identifier ];
} else {
obj.prerelease[0] = [ obj.prerelease[0], identifier ].join("-");
}
return obj.format();
}
/**
* Upload artifacts to GitHub
* docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain
* @param {string} version Version
* @param {string} githubToken GitHub token
* @returns {void}
*/
export function uploadArtifacts(version, githubToken) {
let args = [
"buildx",
"build",
"-f",
"docker/dockerfile",
"--platform",
"linux/amd64",
"-t",
"louislam/uptime-kuma:upload-artifact",
"--build-arg",
`VERSION=${version}`,
"--build-arg",
"GITHUB_TOKEN",
"--target",
"upload-artifact",
".",
"--progress",
"plain",
];
if (!dryRun) {
childProcess.spawnSync("docker", args, {
stdio: "inherit",
env: {
...process.env,
GITHUB_TOKEN: githubToken,
},
});
} else {
console.log(`[DRY RUN] docker ${args.join(" ")}`);
}
}
/**
* Execute a command
* @param {string} cmd Command to execute
* @returns {void}
*/
export function execSync(cmd) {
if (!dryRun) {
childProcess.execSync(cmd, { stdio: "inherit" });
} else {
console.info(`[DRY RUN] ${cmd}`);
}
}

View File

@@ -1,16 +0,0 @@
import { buildDist, buildImage, checkDocker, getRepoNames } from "./lib.mjs";
// Docker Hub repository name
const repoNames = getRepoNames();
// Check if docker is running
checkDocker();
// Build frontend dist (it will build on the host machine, TODO: build on a container?)
buildDist();
// Build full image (rootless)
buildImage(repoNames, [ "nightly2-rootless" ], "nightly-rootless");
// Build full image
buildImage(repoNames, [ "nightly2" ], "nightly");

View File

@@ -1,6 +0,0 @@
import { uploadArtifacts } from "./lib.mjs";
const version = process.env.RELEASE_BETA_VERSION;
const githubToken = process.env.RELEASE_GITHUB_TOKEN;
uploadArtifacts(version, githubToken);

View File

@@ -1,6 +0,0 @@
import { uploadArtifacts } from "./lib.mjs";
const version = process.env.RELEASE_VERSION;
const githubToken = process.env.RELEASE_GITHUB_TOKEN;
uploadArtifacts(version, githubToken);

9
extra/test-docker.js Normal file
View File

@@ -0,0 +1,9 @@
// Check if docker is running
const { exec } = require("child_process");
exec("docker ps", (err, stdout, stderr) => {
if (err) {
console.error("Docker is not running. Please start docker and try again.");
process.exit(1);
}
});

View File

@@ -5,7 +5,7 @@ const util = require("../src/util");
util.polyfill(); util.polyfill();
const newVersion = process.env.RELEASE_VERSION; const newVersion = process.env.VERSION;
console.log("New Version: " + newVersion); console.log("New Version: " + newVersion);

View File

@@ -1,7 +1,7 @@
const childProcess = require("child_process"); const childProcess = require("child_process");
const fs = require("fs"); const fs = require("fs");
const newVersion = process.env.RELEASE_VERSION; const newVersion = process.env.VERSION;
if (!newVersion) { if (!newVersion) {
console.log("Missing version"); console.log("Missing version");

5035
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "uptime-kuma", "name": "uptime-kuma",
"version": "2.0.0-beta.1", "version": "2.0.0-dev",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -34,14 +34,20 @@
"playwright-show-report": "playwright show-report ./private/playwright-report", "playwright-show-report": "playwright show-report ./private/playwright-report",
"tsc": "tsc", "tsc": "tsc",
"vite-preview-dist": "vite preview --host --config ./config/vite.config.js", "vite-preview-dist": "vite preview --host --config ./config/vite.config.js",
"build-docker": "npm run build && npm run build-docker-full && npm run build-docker-slim",
"build-docker-base": "docker buildx build -f docker/debian-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base2 --target base2 . --push", "build-docker-base": "docker buildx build -f docker/debian-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base2 --target base2 . --push",
"build-docker-base-slim": "docker buildx build -f docker/debian-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base2-slim --target base2-slim . --push", "build-docker-base-slim": "docker buildx build -f docker/debian-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base2-slim --target base2-slim . --push",
"build-docker-builder-go": "docker buildx build -f docker/builder-go.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:builder-go . --push", "build-docker-builder-go": "docker buildx build -f docker/builder-go.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:builder-go . --push",
"build-docker-slim": "node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:next-slim -t louislam/uptime-kuma:2-slim -t louislam/uptime-kuma:$VERSION-slim --target release --build-arg BASE_IMAGE=louislam/uptime-kuma:base2-slim . --push",
"build-docker-full": "node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:next -t louislam/uptime-kuma:2 -t louislam/uptime-kuma:$VERSION --target release . --push",
"build-docker-nightly": "node ./extra/test-docker.js && npm run build && docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly2 --target nightly . --push",
"build-docker-slim-rootless": "node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:2-slim-rootless -t louislam/uptime-kuma:$VERSION-slim-rootless --target rootless --build-arg BASE_IMAGE=louislam/uptime-kuma:base2-slim . --push",
"build-docker-full-rootless": "node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:2-rootless -t louislam/uptime-kuma:$VERSION-rootless --target rootless . --push",
"build-docker-nightly-rootless": "node ./extra/test-docker.js && npm run build && docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly2-rootless --target nightly-rootless . --push",
"build-docker-nightly-local": "npm run build && docker build -f docker/dockerfile -t louislam/uptime-kuma:nightly2 --target nightly .", "build-docker-nightly-local": "npm run build && docker build -f docker/dockerfile -t louislam/uptime-kuma:nightly2 --target nightly .",
"build-docker-pr-test": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64 -t louislam/uptime-kuma:pr-test2 --target pr-test2 . --push", "build-docker-pr-test": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64 -t louislam/uptime-kuma:pr-test2 --target pr-test2 . --push",
"upload-artifacts": "node extra/release/upload-artifacts.mjs", "upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain",
"upload-artifacts-beta": "node extra/release/upload-artifacts-beta.mjs", "setup": "git checkout 1.23.14 && npm ci --production && npm run download-dist",
"setup": "git checkout 1.23.16 && npm ci --omit dev && npm run download-dist",
"download-dist": "node extra/download-dist.js", "download-dist": "node extra/download-dist.js",
"mark-as-nightly": "node extra/mark-as-nightly.js", "mark-as-nightly": "node extra/mark-as-nightly.js",
"reset-password": "node extra/reset-password.js", "reset-password": "node extra/reset-password.js",
@@ -52,9 +58,8 @@
"simple-postgres": "docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=postgres postgres", "simple-postgres": "docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=postgres postgres",
"simple-mariadb": "docker run --rm -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mariadb# mariadb", "simple-mariadb": "docker run --rm -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mariadb# mariadb",
"update-language-files": "cd extra/update-language-files && node index.js && cross-env-shell eslint ../../src/languages/$npm_config_language.js --fix", "update-language-files": "cd extra/update-language-files && node index.js && cross-env-shell eslint ../../src/languages/$npm_config_language.js --fix",
"release-final": "node ./extra/release/final.mjs", "release-final": "node ./extra/test-docker.js && node extra/update-version.js && npm run build-docker && node ./extra/press-any-key.js && npm run upload-artifacts && node ./extra/update-wiki-version.js",
"release-beta": "node ./extra/release/beta.mjs", "release-beta": "node ./extra/test-docker.js && node extra/beta/update-version.js && npm run build && node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:$VERSION -t louislam/uptime-kuma:beta . --target release --push && node ./extra/press-any-key.js && npm run upload-artifacts",
"release-nightly": "node ./extra/release/nightly.mjs",
"git-remove-tag": "git tag -d", "git-remove-tag": "git tag -d",
"build-dist-and-restart": "npm run build && npm run start-server-dev", "build-dist-and-restart": "npm run build && npm run start-server-dev",
"start-pr-test": "node extra/checkout-pr.js && npm install && npm run dev", "start-pr-test": "node extra/checkout-pr.js && npm install && npm run dev",
@@ -72,7 +77,7 @@
"@louislam/sqlite3": "15.1.6", "@louislam/sqlite3": "15.1.6",
"@vvo/tzdb": "^6.125.0", "@vvo/tzdb": "^6.125.0",
"args-parser": "~1.3.0", "args-parser": "~1.3.0",
"axios": "~0.29.0", "axios": "~0.28.1",
"badge-maker": "~3.3.1", "badge-maker": "~3.3.1",
"bcryptjs": "~2.4.3", "bcryptjs": "~2.4.3",
"chardet": "~1.4.0", "chardet": "~1.4.0",
@@ -95,8 +100,8 @@
"html-escaper": "^3.0.3", "html-escaper": "^3.0.3",
"http-cookie-agent": "~5.0.4", "http-cookie-agent": "~5.0.4",
"http-graceful-shutdown": "~3.1.7", "http-graceful-shutdown": "~3.1.7",
"http-proxy-agent": "~7.0.2", "http-proxy-agent": "~5.0.0",
"https-proxy-agent": "~7.0.6", "https-proxy-agent": "~5.0.1",
"iconv-lite": "~0.6.3", "iconv-lite": "~0.6.3",
"isomorphic-ws": "^5.0.0", "isomorphic-ws": "^5.0.0",
"jsesc": "~3.0.2", "jsesc": "~3.0.2",
@@ -104,7 +109,7 @@
"jsonwebtoken": "~9.0.0", "jsonwebtoken": "~9.0.0",
"jwt-decode": "~3.1.2", "jwt-decode": "~3.1.2",
"kafkajs": "^2.2.4", "kafkajs": "^2.2.4",
"knex": "~3.1.0", "knex": "^2.4.2",
"limiter": "~2.1.0", "limiter": "~2.1.0",
"liquidjs": "^10.7.0", "liquidjs": "^10.7.0",
"marked": "^14.0.0", "marked": "^14.0.0",
@@ -112,13 +117,13 @@
"mongodb": "~4.17.1", "mongodb": "~4.17.1",
"mqtt": "~4.3.7", "mqtt": "~4.3.7",
"mssql": "~11.0.0", "mssql": "~11.0.0",
"mysql2": "~3.11.3", "mysql2": "~3.9.6",
"nanoid": "~3.3.4", "nanoid": "~3.3.4",
"net-snmp": "^3.11.2", "net-snmp": "^3.11.2",
"node-cloudflared-tunnel": "~1.0.9", "node-cloudflared-tunnel": "~1.0.9",
"node-radius-client": "~1.0.0", "node-radius-client": "~1.0.0",
"nodemailer": "~6.9.13", "nodemailer": "~6.9.13",
"nostr-tools": "^2.10.4", "nostr-tools": "^1.13.1",
"notp": "~2.0.3", "notp": "~2.0.3",
"openid-client": "^5.4.2", "openid-client": "^5.4.2",
"password-hash": "~1.2.2", "password-hash": "~1.2.2",
@@ -135,7 +140,7 @@
"semver": "~7.5.4", "semver": "~7.5.4",
"socket.io": "~4.8.0", "socket.io": "~4.8.0",
"socket.io-client": "~4.8.0", "socket.io-client": "~4.8.0",
"socks-proxy-agent": "~8.0.5", "socks-proxy-agent": "6.1.1",
"tar": "~6.2.1", "tar": "~6.2.1",
"tcp-ping": "~0.1.1", "tcp-ping": "~0.1.1",
"thirty-two": "~1.0.2", "thirty-two": "~1.0.2",
@@ -143,7 +148,7 @@
"ws": "^8.13.0" "ws": "^8.13.0"
}, },
"devDependencies": { "devDependencies": {
"@actions/github": "~6.0.0", "@actions/github": "~5.1.1",
"@fortawesome/fontawesome-svg-core": "~1.2.36", "@fortawesome/fontawesome-svg-core": "~1.2.36",
"@fortawesome/free-regular-svg-icons": "~5.15.4", "@fortawesome/free-regular-svg-icons": "~5.15.4",
"@fortawesome/free-solid-svg-icons": "~5.15.4", "@fortawesome/free-solid-svg-icons": "~5.15.4",
@@ -169,7 +174,7 @@
"cross-env": "~7.0.3", "cross-env": "~7.0.3",
"delay": "^5.0.0", "delay": "^5.0.0",
"dns2": "~2.0.1", "dns2": "~2.0.1",
"dompurify": "~3.2.4", "dompurify": "~3.1.7",
"eslint": "~8.14.0", "eslint": "~8.14.0",
"eslint-plugin-jsdoc": "~46.4.6", "eslint-plugin-jsdoc": "~46.4.6",
"eslint-plugin-vue": "~8.7.1", "eslint-plugin-vue": "~8.7.1",
@@ -179,7 +184,7 @@
"postcss-html": "~1.5.0", "postcss-html": "~1.5.0",
"postcss-rtlcss": "~3.7.2", "postcss-rtlcss": "~3.7.2",
"postcss-scss": "~4.0.4", "postcss-scss": "~4.0.4",
"prismjs": "~1.30.0", "prismjs": "~1.29.0",
"qrcode": "~1.5.0", "qrcode": "~1.5.0",
"rollup-plugin-visualizer": "^5.6.0", "rollup-plugin-visualizer": "^5.6.0",
"sass": "~1.42.1", "sass": "~1.42.1",
@@ -190,14 +195,14 @@
"testcontainers": "^10.13.1", "testcontainers": "^10.13.1",
"typescript": "~4.4.4", "typescript": "~4.4.4",
"v-pagination-3": "~0.1.7", "v-pagination-3": "~0.1.7",
"vite": "~5.4.15", "vite": "~5.2.8",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vite-plugin-vue-devtools": "^7.0.15", "vite-plugin-vue-devtools": "^7.0.15",
"vue": "~3.4.2", "vue": "~3.4.2",
"vue-chartjs": "~5.2.0", "vue-chartjs": "~5.2.0",
"vue-confirm-dialog": "~1.0.2", "vue-confirm-dialog": "~1.0.2",
"vue-contenteditable": "~3.0.4", "vue-contenteditable": "~3.0.4",
"vue-i18n": "~9.14.3", "vue-i18n": "~9.2.2",
"vue-image-crop-upload": "~3.0.3", "vue-image-crop-upload": "~3.0.3",
"vue-multiselect": "~3.0.0-alpha.2", "vue-multiselect": "~3.0.0-alpha.2",
"vue-prism-editor": "~2.0.0-alpha.2", "vue-prism-editor": "~2.0.0-alpha.2",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -10,7 +10,6 @@ const { Settings } = require("./settings");
const { UptimeCalculator } = require("./uptime-calculator"); const { UptimeCalculator } = require("./uptime-calculator");
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const { SimpleMigrationServer } = require("./utils/simple-migration-server"); const { SimpleMigrationServer } = require("./utils/simple-migration-server");
const KumaColumnCompiler = require("./utils/knex/lib/dialects/mysql2/schema/mysql2-columncompiler");
/** /**
* Database & App Data Folder * Database & App Data Folder
@@ -199,14 +198,6 @@ class Database {
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
static async connect(testMode = false, autoloadModels = true, noLog = false) { static async connect(testMode = false, autoloadModels = true, noLog = false) {
// Patch "mysql2" knex client
// Workaround: Tried extending the ColumnCompiler class, but it didn't work for unknown reasons, so I override the function via prototype
const { getDialectByNameOrAlias } = require("knex/lib/dialects");
const mysql2 = getDialectByNameOrAlias("mysql2");
mysql2.prototype.columnCompiler = function () {
return new KumaColumnCompiler(this, ...arguments);
};
const acquireConnectionTimeout = 120 * 1000; const acquireConnectionTimeout = 120 * 1000;
let dbConfig; let dbConfig;
try { try {
@@ -296,7 +287,7 @@ class Database {
client: "mysql2", client: "mysql2",
connection: { connection: {
socketPath: embeddedMariaDB.socketPath, socketPath: embeddedMariaDB.socketPath,
user: embeddedMariaDB.username, user: "node",
database: "kuma", database: "kuma",
timezone: "Z", timezone: "Z",
typeCast: function (field, next) { typeCast: function (field, next) {
@@ -892,13 +883,11 @@ class Database {
AND important = 0 AND important = 0
AND time < ${sqlHourOffset} AND time < ${sqlHourOffset}
AND id NOT IN ( AND id NOT IN (
SELECT id FROM ( -- written this way for Maria's support
SELECT id SELECT id
FROM heartbeat FROM heartbeat
WHERE monitor_id = ? WHERE monitor_id = ?
ORDER BY time DESC ORDER BY time DESC
LIMIT ? LIMIT ?
) AS limited_ids
) )
`, [ `, [
monitor.id, monitor.id,

View File

@@ -14,15 +14,9 @@ class EmbeddedMariaDB {
mariadbDataDir = "/app/data/mariadb"; mariadbDataDir = "/app/data/mariadb";
runDir = "/app/data/run"; runDir = "/app/data/run/mariadb";
socketPath = this.runDir + "/mariadb.sock"; socketPath = this.runDir + "/mysqld.sock";
/**
* The username to connect to the MariaDB
* @type {string}
*/
username = null;
/** /**
* @type {ChildProcessWithoutNullStreams} * @type {ChildProcessWithoutNullStreams}
@@ -52,42 +46,16 @@ class EmbeddedMariaDB {
/** /**
* Start the embedded MariaDB * Start the embedded MariaDB
* @throws {Error} If the current user is not "node" or "root"
* @returns {Promise<void>|void} A promise that resolves when the MariaDB is started or void if it is already started * @returns {Promise<void>|void} A promise that resolves when the MariaDB is started or void if it is already started
*/ */
start() { start() {
// Check if the current user is "node" or "root"
this.username = require("os").userInfo().username;
if (this.username !== "node" && this.username !== "root") {
throw new Error("Embedded Mariadb supports only 'node' or 'root' user, but the current user is: " + this.username);
}
this.initDB();
this.startChildProcess();
return new Promise((resolve) => {
let interval = setInterval(() => {
if (this.started) {
clearInterval(interval);
resolve();
} else {
log.info("mariadb", "Waiting for Embedded MariaDB to start...");
}
}, 1000);
});
}
/**
* Start the child process
* @returns {void}
*/
startChildProcess() {
if (this.childProcess) { if (this.childProcess) {
log.info("mariadb", "Already started"); log.info("mariadb", "Already started");
return; return;
} }
this.initDB();
this.running = true; this.running = true;
log.info("mariadb", "Starting Embedded MariaDB"); log.info("mariadb", "Starting Embedded MariaDB");
this.childProcess = childProcess.spawn(this.exec, [ this.childProcess = childProcess.spawn(this.exec, [
@@ -95,8 +63,6 @@ class EmbeddedMariaDB {
"--datadir=" + this.mariadbDataDir, "--datadir=" + this.mariadbDataDir,
`--socket=${this.socketPath}`, `--socket=${this.socketPath}`,
`--pid-file=${this.runDir}/mysqld.pid`, `--pid-file=${this.runDir}/mysqld.pid`,
// Don't add the following option, the mariadb will not report message to the console, which affects initDBAfterStarted()
// "--log-error=" + `${this.mariadbDataDir}/mariadb-error.log`,
]); ]);
this.childProcess.on("close", (code) => { this.childProcess.on("close", (code) => {
@@ -106,8 +72,8 @@ class EmbeddedMariaDB {
log.info("mariadb", "Stopped Embedded MariaDB: " + code); log.info("mariadb", "Stopped Embedded MariaDB: " + code);
if (code !== 0) { if (code !== 0) {
log.error("mariadb", "Try to restart Embedded MariaDB as it is not stopped by user"); log.info("mariadb", "Try to restart Embedded MariaDB as it is not stopped by user");
this.startChildProcess(); this.start();
} }
}); });
@@ -120,7 +86,7 @@ class EmbeddedMariaDB {
}); });
let handler = (data) => { let handler = (data) => {
log.info("mariadb", data.toString("utf-8")); log.debug("mariadb", data.toString("utf-8"));
if (data.toString("utf-8").includes("ready for connections")) { if (data.toString("utf-8").includes("ready for connections")) {
this.initDBAfterStarted(); this.initDBAfterStarted();
} }
@@ -128,6 +94,17 @@ class EmbeddedMariaDB {
this.childProcess.stdout.on("data", handler); this.childProcess.stdout.on("data", handler);
this.childProcess.stderr.on("data", handler); this.childProcess.stderr.on("data", handler);
return new Promise((resolve) => {
let interval = setInterval(() => {
if (this.started) {
clearInterval(interval);
resolve();
} else {
log.info("mariadb", "Waiting for Embedded MariaDB to start...");
}
}, 1000);
});
} }
/** /**
@@ -152,11 +129,9 @@ class EmbeddedMariaDB {
recursive: true, recursive: true,
}); });
let result = childProcess.spawnSync("mariadb-install-db", [ let result = childProcess.spawnSync("mysql_install_db", [
"--user=node", "--user=node",
"--auth-root-socket-user=node", "--ldata=" + this.mariadbDataDir,
"--datadir=" + this.mariadbDataDir,
"--auth-root-authentication-method=socket",
]); ]);
if (result.status !== 0) { if (result.status !== 0) {
@@ -168,17 +143,6 @@ class EmbeddedMariaDB {
} }
} }
// Check the owner of the mariadb directory, and change it if necessary
let stat = fs.statSync(this.mariadbDataDir);
if (stat.uid !== 1000 || stat.gid !== 1000) {
fs.chownSync(this.mariadbDataDir, 1000, 1000);
}
// Check the permission of the mariadb directory, and change it if it is not 755
if (stat.mode !== 0o755) {
fs.chmodSync(this.mariadbDataDir, 0o755);
}
if (!fs.existsSync(this.runDir)) { if (!fs.existsSync(this.runDir)) {
log.info("mariadb", `Embedded MariaDB: ${this.runDir} is not found, create one now.`); log.info("mariadb", `Embedded MariaDB: ${this.runDir} is not found, create one now.`);
fs.mkdirSync(this.runDir, { fs.mkdirSync(this.runDir, {
@@ -186,13 +150,6 @@ class EmbeddedMariaDB {
}); });
} }
stat = fs.statSync(this.runDir);
if (stat.uid !== 1000 || stat.gid !== 1000) {
fs.chownSync(this.runDir, 1000, 1000);
}
if (stat.mode !== 0o755) {
fs.chmodSync(this.runDir, 0o755);
}
} }
/** /**
@@ -202,7 +159,7 @@ class EmbeddedMariaDB {
async initDBAfterStarted() { async initDBAfterStarted() {
const connection = mysql.createConnection({ const connection = mysql.createConnection({
socketPath: this.socketPath, socketPath: this.socketPath,
user: this.username, user: "node",
}); });
let result = await connection.execute("CREATE DATABASE IF NOT EXISTS `kuma`"); let result = await connection.execute("CREATE DATABASE IF NOT EXISTS `kuma`");

View File

@@ -1434,7 +1434,7 @@ class Monitor extends BeanModel {
for (let notification of notificationList) { for (let notification of notificationList) {
try { try {
log.debug("monitor", "Sending to " + notification.name); log.debug("monitor", "Sending to " + notification.name);
await Notification.send(JSON.parse(notification.config), `[${this.name}][${this.url}] ${certType} certificate ${certCN} will expire in ${daysRemaining} days`); await Notification.send(JSON.parse(notification.config), `[${this.name}][${this.url}] ${certType} certificate ${certCN} will be expired in ${daysRemaining} days`);
sent = true; sent = true;
} catch (e) { } catch (e) {
log.error("monitor", "Cannot send cert notification to " + notification.name); log.error("monitor", "Cannot send cert notification to " + notification.name);
@@ -1522,7 +1522,7 @@ class Monitor extends BeanModel {
*/ */
static async getMonitorTag(monitorIDs) { static async getMonitorTag(monitorIDs) {
return await R.getAll(` return await R.getAll(`
SELECT monitor_tag.monitor_id, monitor_tag.tag_id, monitor_tag.value, tag.name, tag.color SELECT monitor_tag.monitor_id, monitor_tag.tag_id, tag.name, tag.color
FROM monitor_tag FROM monitor_tag
JOIN tag ON monitor_tag.tag_id = tag.id JOIN tag ON monitor_tag.tag_id = tag.id
WHERE monitor_tag.monitor_id IN (${monitorIDs.map((_) => "?").join(",")}) WHERE monitor_tag.monitor_id IN (${monitorIDs.map((_) => "?").join(",")})
@@ -1567,8 +1567,6 @@ class Monitor extends BeanModel {
} }
tagsMap.get(row.monitor_id).push({ tagsMap.get(row.monitor_id).push({
tag_id: row.tag_id, tag_id: row.tag_id,
monitor_id: row.monitor_id,
value: row.value,
name: row.name, name: row.name,
color: row.color color: row.color
}); });

View File

@@ -485,7 +485,7 @@ function ApiCache() {
} }
if (typeof duration === "string") { if (typeof duration === "string") {
let split = duration.match(/^([\d\.,]+)\s?([a-zA-Z]+)$/); let split = duration.match(/^([\d\.,]+)\s?(\w+)$/);
if (split.length === 3) { if (split.length === 3) {
let len = parseFloat(split[1]); let len = parseFloat(split[1]);

View File

@@ -240,14 +240,6 @@ class RealBrowserMonitorType extends MonitorType {
const context = await browser.newContext(); const context = await browser.newContext();
const page = await context.newPage(); const page = await context.newPage();
// Prevent Local File Inclusion
// Accept only http:// and https://
// https://github.com/louislam/uptime-kuma/security/advisories/GHSA-2qgm-m29m-cj2h
let url = new URL(monitor.url);
if (url.protocol !== "http:" && url.protocol !== "https:") {
throw new Error("Invalid url protocol, only http and https are allowed.");
}
const res = await page.goto(monitor.url, { const res = await page.goto(monitor.url, {
waitUntil: "networkidle", waitUntil: "networkidle",
timeout: monitor.interval * 1000 * 0.8, timeout: monitor.interval * 1000 * 0.8,

View File

@@ -17,7 +17,7 @@ class AliyunSMS extends NotificationProvider {
if (heartbeatJSON != null) { if (heartbeatJSON != null) {
let msgBody = JSON.stringify({ let msgBody = JSON.stringify({
name: monitorJSON["name"], name: monitorJSON["name"],
time: heartbeatJSON["localDateTime"], time: heartbeatJSON["time"],
status: this.statusToString(heartbeatJSON["status"]), status: this.statusToString(heartbeatJSON["status"]),
msg: heartbeatJSON["msg"], msg: heartbeatJSON["msg"],
}); });

View File

@@ -72,7 +72,6 @@ class GoogleChat extends NotificationProvider {
// construct json data // construct json data
let data = { let data = {
fallbackText: chatHeader["title"],
cardsV2: [ cardsV2: [
{ {
card: { card: {

View File

@@ -1,10 +1,11 @@
const NotificationProvider = require("./notification-provider"); const NotificationProvider = require("./notification-provider");
const { const {
finalizeEvent, relayInit,
Relay, getPublicKey,
kinds, getEventHash,
getSignature,
nip04, nip04,
nip19, nip19
} = require("nostr-tools"); } = require("nostr-tools");
// polyfills for node versions // polyfills for node versions
@@ -30,6 +31,7 @@ class Nostr extends NotificationProvider {
const createdAt = Math.floor(Date.now() / 1000); const createdAt = Math.floor(Date.now() / 1000);
const senderPrivateKey = await this.getPrivateKey(notification.sender); const senderPrivateKey = await this.getPrivateKey(notification.sender);
const senderPublicKey = getPublicKey(senderPrivateKey);
const recipientsPublicKeys = await this.getPublicKeys(notification.recipients); const recipientsPublicKeys = await this.getPublicKeys(notification.recipients);
// Create NIP-04 encrypted direct message event for each recipient // Create NIP-04 encrypted direct message event for each recipient
@@ -37,41 +39,34 @@ class Nostr extends NotificationProvider {
for (const recipientPublicKey of recipientsPublicKeys) { for (const recipientPublicKey of recipientsPublicKeys) {
const ciphertext = await nip04.encrypt(senderPrivateKey, recipientPublicKey, msg); const ciphertext = await nip04.encrypt(senderPrivateKey, recipientPublicKey, msg);
let event = { let event = {
kind: kinds.EncryptedDirectMessage, kind: 4,
pubkey: senderPublicKey,
created_at: createdAt, created_at: createdAt,
tags: [[ "p", recipientPublicKey ]], tags: [[ "p", recipientPublicKey ]],
content: ciphertext, content: ciphertext,
}; };
const signedEvent = finalizeEvent(event, senderPrivateKey); event.id = getEventHash(event);
events.push(signedEvent); event.sig = getSignature(event, senderPrivateKey);
events.push(event);
} }
// Publish events to each relay // Publish events to each relay
const relays = notification.relays.split("\n"); const relays = notification.relays.split("\n");
let successfulRelays = 0; let successfulRelays = 0;
// Connect to each relay
for (const relayUrl of relays) { for (const relayUrl of relays) {
const relay = await Relay.connect(relayUrl); const relay = relayInit(relayUrl);
let eventIndex = 0;
// Authenticate to the relay, if required
try { try {
await relay.publish(events[0]); await relay.connect();
eventIndex = 1;
} catch (error) {
if (relay.challenge) {
await relay.auth(async (evt) => {
return finalizeEvent(evt, senderPrivateKey);
});
}
}
try {
for (let i = eventIndex; i < events.length; i++) {
await relay.publish(events[i]);
}
successfulRelays++; successfulRelays++;
// Publish events
for (const event of events) {
relay.publish(event);
}
} catch (error) { } catch (error) {
console.error(`Failed to publish event to ${relayUrl}:`, error); continue;
} finally { } finally {
relay.close(); relay.close();
} }
@@ -95,7 +90,7 @@ class Nostr extends NotificationProvider {
const { data } = senderDecodeResult; const { data } = senderDecodeResult;
return data; return data;
} catch (error) { } catch (error) {
throw new Error(`Failed to decode private key for sender ${sender}: ${error.message}`); throw new Error(`Failed to get private key: ${error.message}`);
} }
} }
@@ -114,10 +109,10 @@ class Nostr extends NotificationProvider {
if (type === "npub") { if (type === "npub") {
publicKeys.push(data); publicKeys.push(data);
} else { } else {
throw new Error(`Recipient ${recipient} is not an npub`); throw new Error("not an npub");
} }
} catch (error) { } catch (error) {
throw new Error(`Error decoding recipient ${recipient}: ${error}`); throw new Error(`Error decoding recipient: ${error}`);
} }
} }
return publicKeys; return publicKeys;

View File

@@ -1,6 +1,3 @@
const { Liquid } = require("liquidjs");
const { DOWN } = require("../../src/util");
class NotificationProvider { class NotificationProvider {
/** /**
@@ -52,50 +49,6 @@ class NotificationProvider {
} }
} }
/**
* Renders a message template with notification context
* @param {string} template the template
* @param {string} msg the message that will be included in the context
* @param {?object} monitorJSON Monitor details (For Up/Down/Cert-Expiry only)
* @param {?object} heartbeatJSON Heartbeat details (For Up/Down only)
* @returns {Promise<string>} rendered template
*/
async renderTemplate(template, msg, monitorJSON, heartbeatJSON) {
const engine = new Liquid();
const parsedTpl = engine.parse(template);
// Let's start with dummy values to simplify code
let monitorName = "Monitor Name not available";
let monitorHostnameOrURL = "testing.hostname";
if (monitorJSON !== null) {
monitorName = monitorJSON["name"];
monitorHostnameOrURL = this.extractAddress(monitorJSON);
}
let serviceStatus = "тЪая╕П Test";
if (heartbeatJSON !== null) {
serviceStatus = (heartbeatJSON["status"] === DOWN) ? "ЁЯФ┤ Down" : "тЬЕ Up";
}
const context = {
// for v1 compatibility, to be removed in v3
"STATUS": serviceStatus,
"NAME": monitorName,
"HOSTNAME_OR_URL": monitorHostnameOrURL,
// variables which are officially supported
"status": serviceStatus,
"name": monitorName,
"hostnameOrURL": monitorHostnameOrURL,
monitorJSON,
heartbeatJSON,
msg,
};
return engine.render(parsedTpl, context);
}
/** /**
* Throws an error * Throws an error
* @param {any} error The error to throw * @param {any} error The error to throw

View File

@@ -11,8 +11,7 @@ class PushDeer extends NotificationProvider {
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
const okMsg = "Sent Successfully."; const okMsg = "Sent Successfully.";
const serverUrl = notification.pushdeerServer || "https://api2.pushdeer.com"; const serverUrl = notification.pushdeerServer || "https://api2.pushdeer.com";
// capture group below is nessesary to prevent an ReDOS-attack const url = `${serverUrl.trim().replace(/\/*$/, "")}/message/push`;
const url = `${serverUrl.trim().replace(/([^/])\/+$/, "$1")}/message/push`;
let valid = msg != null && monitorJSON != null && heartbeatJSON != null; let valid = msg != null && monitorJSON != null && heartbeatJSON != null;

View File

@@ -1,56 +0,0 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { DOWN, UP } = require("../../src/util");
class PushPlus extends NotificationProvider {
name = "PushPlus";
/**
* @inheritdoc
* @param {BeanModel} notification Notification object
* @param {string} msg Message content
* @param {?object} monitorJSON Monitor details
* @param {?object} heartbeatJSON Heartbeat details
* @returns {Promise<string>} Success message
*/
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
const okMsg = "Sent Successfully.";
const url = "https://www.pushplus.plus/send";
try {
const config = {
headers: {
"Content-Type": "application/json",
},
};
const params = {
"token": notification.pushPlusSendKey,
"title": this.checkStatus(heartbeatJSON, monitorJSON),
"content": msg,
"template": "html"
};
await axios.post(url, params, config);
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
/**
* Get the formatted title for message
* @param {?object} heartbeatJSON Heartbeat details (For Up/Down only)
* @param {?object} monitorJSON Monitor details (For Up/Down only)
* @returns {string} Formatted title
*/
checkStatus(heartbeatJSON, monitorJSON) {
let title = "UptimeKuma Message";
if (heartbeatJSON != null && heartbeatJSON["status"] === UP) {
title = "UptimeKuma Monitor Up " + monitorJSON["name"];
}
if (heartbeatJSON != null && heartbeatJSON["status"] === DOWN) {
title = "UptimeKuma Monitor Down " + monitorJSON["name"];
}
return title;
}
}
module.exports = PushPlus;

View File

@@ -1,7 +1,7 @@
const NotificationProvider = require("./notification-provider"); const NotificationProvider = require("./notification-provider");
const axios = require("axios"); const axios = require("axios");
const { setSettings, setting } = require("../util-server"); const { setSettings, setting } = require("../util-server");
const { getMonitorRelativeURL, UP, log } = require("../../src/util"); const { getMonitorRelativeURL, UP } = require("../../src/util");
class Slack extends NotificationProvider { class Slack extends NotificationProvider {
name = "slack"; name = "slack";
@@ -50,7 +50,6 @@ class Slack extends NotificationProvider {
const address = this.extractAddress(monitorJSON); const address = this.extractAddress(monitorJSON);
if (address) { if (address) {
try {
actions.push({ actions.push({
"type": "button", "type": "button",
"text": { "text": {
@@ -58,12 +57,8 @@ class Slack extends NotificationProvider {
"text": "Visit site", "text": "Visit site",
}, },
"value": "Site", "value": "Site",
"url": new URL(address), "url": address,
}); });
} catch (e) {
log.debug("slack", `Failed to parse address ${address} as URL`);
}
} }
return actions; return actions;

View File

@@ -1,5 +1,7 @@
const nodemailer = require("nodemailer"); const nodemailer = require("nodemailer");
const NotificationProvider = require("./notification-provider"); const NotificationProvider = require("./notification-provider");
const { DOWN } = require("../../src/util");
const { Liquid } = require("liquidjs");
class SMTP extends NotificationProvider { class SMTP extends NotificationProvider {
name = "smtp"; name = "smtp";
@@ -51,11 +53,15 @@ class SMTP extends NotificationProvider {
const customSubject = notification.customSubject?.trim() || ""; const customSubject = notification.customSubject?.trim() || "";
const customBody = notification.customBody?.trim() || ""; const customBody = notification.customBody?.trim() || "";
const context = this.generateContext(msg, monitorJSON, heartbeatJSON);
const engine = new Liquid();
if (customSubject !== "") { if (customSubject !== "") {
subject = await this.renderTemplate(customSubject, msg, monitorJSON, heartbeatJSON); const tpl = engine.parse(customSubject);
subject = await engine.render(tpl, context);
} }
if (customBody !== "") { if (customBody !== "") {
body = await this.renderTemplate(customBody, msg, monitorJSON, heartbeatJSON); const tpl = engine.parse(customBody);
body = await engine.render(tpl, context);
} }
} }
@@ -72,6 +78,43 @@ class SMTP extends NotificationProvider {
return okMsg; return okMsg;
} }
/**
* Generate context for LiquidJS
* @param {string} msg the message that will be included in the context
* @param {?object} monitorJSON Monitor details (For Up/Down/Cert-Expiry only)
* @param {?object} heartbeatJSON Heartbeat details (For Up/Down only)
* @returns {{STATUS: string, status: string, HOSTNAME_OR_URL: string, hostnameOrUrl: string, NAME: string, name: string, monitorJSON: ?object, heartbeatJSON: ?object, msg: string}} the context
*/
generateContext(msg, monitorJSON, heartbeatJSON) {
// Let's start with dummy values to simplify code
let monitorName = "Monitor Name not available";
let monitorHostnameOrURL = "testing.hostname";
if (monitorJSON !== null) {
monitorName = monitorJSON["name"];
monitorHostnameOrURL = this.extractAddress(monitorJSON);
}
let serviceStatus = "тЪая╕П Test";
if (heartbeatJSON !== null) {
serviceStatus = (heartbeatJSON["status"] === DOWN) ? "ЁЯФ┤ Down" : "тЬЕ Up";
}
return {
// for v1 compatibility, to be removed in v3
"STATUS": serviceStatus,
"NAME": monitorName,
"HOSTNAME_OR_URL": monitorHostnameOrURL,
// variables which are officially supported
"status": serviceStatus,
"name": monitorName,
"hostnameOrURL": monitorHostnameOrURL,
monitorJSON,
heartbeatJSON,
msg,
};
}
} }
module.exports = SMTP; module.exports = SMTP;

View File

@@ -9,7 +9,7 @@ class Telegram extends NotificationProvider {
*/ */
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
const okMsg = "Sent Successfully."; const okMsg = "Sent Successfully.";
const url = notification.telegramServerUrl ?? "https://api.telegram.org"; const url = "https://api.telegram.org";
try { try {
let params = { let params = {
@@ -22,14 +22,6 @@ class Telegram extends NotificationProvider {
params.message_thread_id = notification.telegramMessageThreadID; params.message_thread_id = notification.telegramMessageThreadID;
} }
if (notification.telegramUseTemplate) {
params.text = await this.renderTemplate(notification.telegramTemplate, msg, monitorJSON, heartbeatJSON);
if (notification.telegramTemplateParseMode !== "plain") {
params.parse_mode = notification.telegramTemplateParseMode;
}
}
await axios.get(`${url}/bot${notification.telegramBotToken}/sendMessage`, { await axios.get(`${url}/bot${notification.telegramBotToken}/sendMessage`, {
params: params, params: params,
}); });

View File

@@ -1,40 +0,0 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
class WAHA extends NotificationProvider {
name = "waha";
/**
* @inheritdoc
*/
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
const okMsg = "Sent Successfully.";
try {
const config = {
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"X-Api-Key": notification.wahaApiKey,
}
};
let data = {
"session": notification.wahaSession,
"chatId": notification.wahaChatId,
"text": msg,
};
let url = notification.wahaApiUrl.replace(/([^/])\/+$/, "$1") + "/api/sendText";
await axios.post(url, data, config);
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = WAHA;

View File

@@ -1,6 +1,7 @@
const NotificationProvider = require("./notification-provider"); const NotificationProvider = require("./notification-provider");
const axios = require("axios"); const axios = require("axios");
const FormData = require("form-data"); const FormData = require("form-data");
const { Liquid } = require("liquidjs");
class Webhook extends NotificationProvider { class Webhook extends NotificationProvider {
name = "webhook"; name = "webhook";
@@ -27,7 +28,17 @@ class Webhook extends NotificationProvider {
config.headers = formData.getHeaders(); config.headers = formData.getHeaders();
data = formData; data = formData;
} else if (notification.webhookContentType === "custom") { } else if (notification.webhookContentType === "custom") {
data = await this.renderTemplate(notification.webhookCustomBody, msg, monitorJSON, heartbeatJSON); // Initialize LiquidJS and parse the custom Body Template
const engine = new Liquid();
const tpl = engine.parse(notification.webhookCustomBody);
// Insert templated values into Body
data = await engine.render(tpl,
{
msg,
heartbeatJSON,
monitorJSON
});
} }
if (notification.webhookAdditionalHeaders) { if (notification.webhookAdditionalHeaders) {

View File

@@ -24,7 +24,7 @@ class Whapi extends NotificationProvider {
"body": msg, "body": msg,
}; };
let url = (notification.whapiApiUrl || "https://gate.whapi.cloud/").replace(/([^/])\/+$/, "$1") + "/messages/text"; let url = (notification.whapiApiUrl || "https://gate.whapi.cloud/").replace(/\/+$/, "") + "/messages/text";
await axios.post(url, data, config); await axios.post(url, data, config);

View File

@@ -1,57 +0,0 @@
const NotificationProvider = require("./notification-provider");
const { DOWN, UP } = require("../../src/util");
const { default: axios } = require("axios");
class YZJ extends NotificationProvider {
name = "YZJ";
/**
* @inheritdoc
*/
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
try {
if (heartbeatJSON !== null) {
msg = `${this.statusToString(heartbeatJSON["status"])} ${monitorJSON["name"]} \n> ${heartbeatJSON["msg"]}\n> Time (${heartbeatJSON["timezone"]}): ${heartbeatJSON["localDateTime"]}`;
}
const config = {
headers: {
"Content-Type": "application/json",
},
};
const params = {
content: msg
};
// yzjtype=0 => general robot
const url = `${notification.yzjWebHookUrl}?yzjtype=0&yzjtoken=${notification.yzjToken}`;
const result = await axios.post(url, params, config);
if (!result.data?.success) {
throw new Error(result.data?.errmsg ?? "yzj's server did not respond with the expected result");
}
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
/**
* Convert status constant to string
* @param {string} status The status constant
* @returns {string} status
*/
statusToString(status) {
switch (status) {
case DOWN:
return "тЭМ";
case UP:
return "тЬЕ";
default:
return status;
}
}
}
module.exports = YZJ;

View File

@@ -39,7 +39,6 @@ const PromoSMS = require("./notification-providers/promosms");
const Pushbullet = require("./notification-providers/pushbullet"); const Pushbullet = require("./notification-providers/pushbullet");
const PushDeer = require("./notification-providers/pushdeer"); const PushDeer = require("./notification-providers/pushdeer");
const Pushover = require("./notification-providers/pushover"); const Pushover = require("./notification-providers/pushover");
const PushPlus = require("./notification-providers/pushplus");
const Pushy = require("./notification-providers/pushy"); const Pushy = require("./notification-providers/pushy");
const RocketChat = require("./notification-providers/rocket-chat"); const RocketChat = require("./notification-providers/rocket-chat");
const SerwerSMS = require("./notification-providers/serwersms"); const SerwerSMS = require("./notification-providers/serwersms");
@@ -65,13 +64,11 @@ const ServerChan = require("./notification-providers/serverchan");
const ZohoCliq = require("./notification-providers/zoho-cliq"); const ZohoCliq = require("./notification-providers/zoho-cliq");
const SevenIO = require("./notification-providers/sevenio"); const SevenIO = require("./notification-providers/sevenio");
const Whapi = require("./notification-providers/whapi"); const Whapi = require("./notification-providers/whapi");
const WAHA = require("./notification-providers/waha");
const GtxMessaging = require("./notification-providers/gtx-messaging"); const GtxMessaging = require("./notification-providers/gtx-messaging");
const Cellsynt = require("./notification-providers/cellsynt"); const Cellsynt = require("./notification-providers/cellsynt");
const Onesender = require("./notification-providers/onesender"); const Onesender = require("./notification-providers/onesender");
const Wpush = require("./notification-providers/wpush"); const Wpush = require("./notification-providers/wpush");
const SendGrid = require("./notification-providers/send-grid"); const SendGrid = require("./notification-providers/send-grid");
const YZJ = require("./notification-providers/yzj");
class Notification { class Notification {
@@ -129,7 +126,6 @@ class Notification {
new Pushbullet(), new Pushbullet(),
new PushDeer(), new PushDeer(),
new Pushover(), new Pushover(),
new PushPlus(),
new Pushy(), new Pushy(),
new RocketChat(), new RocketChat(),
new ServerChan(), new ServerChan(),
@@ -155,12 +151,10 @@ class Notification {
new ZohoCliq(), new ZohoCliq(),
new SevenIO(), new SevenIO(),
new Whapi(), new Whapi(),
new WAHA(),
new GtxMessaging(), new GtxMessaging(),
new Cellsynt(), new Cellsynt(),
new Wpush(), new Wpush(),
new SendGrid(), new SendGrid()
new YZJ()
]; ];
for (let item of list) { for (let item of list) {
if (! item.name) { if (! item.name) {

View File

@@ -1,7 +1,7 @@
const { R } = require("redbean-node"); const { R } = require("redbean-node");
const { HttpProxyAgent } = require("http-proxy-agent"); const HttpProxyAgent = require("http-proxy-agent");
const { HttpsProxyAgent } = require("https-proxy-agent"); const HttpsProxyAgent = require("https-proxy-agent");
const { SocksProxyAgent } = require("socks-proxy-agent"); const SocksProxyAgent = require("socks-proxy-agent");
const { debug } = require("../src/util"); const { debug } = require("../src/util");
const { UptimeKumaServer } = require("./uptime-kuma-server"); const { UptimeKumaServer } = require("./uptime-kuma-server");
const { CookieJar } = require("tough-cookie"); const { CookieJar } = require("tough-cookie");
@@ -100,17 +100,17 @@ class Proxy {
let jar = new CookieJar(); let jar = new CookieJar();
const proxyOptions = { const proxyOptions = {
protocol: proxy.protocol,
host: proxy.host,
port: proxy.port,
cookies: { jar }, cookies: { jar },
}; };
const proxyUrl = new URL(`${proxy.protocol}://${proxy.host}:${proxy.port}`);
if (proxy.auth) { if (proxy.auth) {
proxyUrl.username = proxy.username; proxyOptions.auth = `${proxy.username}:${proxy.password}`;
proxyUrl.password = proxy.password;
} }
debug(`Proxy URL: ${proxyUrl.toString()}`); debug(`Proxy Options: ${JSON.stringify(proxyOptions)}`);
debug(`HTTP Agent Options: ${JSON.stringify(httpAgentOptions)}`); debug(`HTTP Agent Options: ${JSON.stringify(httpAgentOptions)}`);
debug(`HTTPS Agent Options: ${JSON.stringify(httpsAgentOptions)}`); debug(`HTTPS Agent Options: ${JSON.stringify(httpsAgentOptions)}`);
@@ -122,15 +122,15 @@ class Proxy {
// eslint-disable-next-line no-case-declarations // eslint-disable-next-line no-case-declarations
const HttpsCookieProxyAgent = createCookieAgent(HttpsProxyAgent); const HttpsCookieProxyAgent = createCookieAgent(HttpsProxyAgent);
httpAgent = new HttpCookieProxyAgent(proxyUrl.toString(), { httpAgent = new HttpCookieProxyAgent({
...(httpAgentOptions || {}), ...httpAgentOptions || {},
...proxyOptions,
});
httpsAgent = new HttpsCookieProxyAgent(proxyUrl.toString(), {
...(httpsAgentOptions || {}),
...proxyOptions, ...proxyOptions,
}); });
httpsAgent = new HttpsCookieProxyAgent({
...httpsAgentOptions || {},
...proxyOptions,
});
break; break;
case "socks": case "socks":
case "socks5": case "socks5":
@@ -138,9 +138,10 @@ class Proxy {
case "socks4": case "socks4":
// eslint-disable-next-line no-case-declarations // eslint-disable-next-line no-case-declarations
const SocksCookieProxyAgent = createCookieAgent(SocksProxyAgent); const SocksCookieProxyAgent = createCookieAgent(SocksProxyAgent);
agent = new SocksCookieProxyAgent(proxyUrl.toString(), { agent = new SocksCookieProxyAgent({
...httpAgentOptions, ...httpAgentOptions,
...httpsAgentOptions, ...httpsAgentOptions,
...proxyOptions,
tls: { tls: {
rejectUnauthorized: httpsAgentOptions.rejectUnauthorized, rejectUnauthorized: httpsAgentOptions.rejectUnauthorized,
}, },

View File

@@ -15,13 +15,11 @@ const server = UptimeKumaServer.getInstance();
router.get("/status/:slug", cache("5 minutes"), async (request, response) => { router.get("/status/:slug", cache("5 minutes"), async (request, response) => {
let slug = request.params.slug; let slug = request.params.slug;
slug = slug.toLowerCase();
await StatusPage.handleStatusPageResponse(response, server.indexHTML, slug); await StatusPage.handleStatusPageResponse(response, server.indexHTML, slug);
}); });
router.get("/status/:slug/rss", cache("5 minutes"), async (request, response) => { router.get("/status/:slug/rss", cache("5 minutes"), async (request, response) => {
let slug = request.params.slug; let slug = request.params.slug;
slug = slug.toLowerCase();
await StatusPage.handleStatusPageRSSResponse(response, slug); await StatusPage.handleStatusPageRSSResponse(response, slug);
}); });
@@ -39,7 +37,6 @@ router.get("/status-page", cache("5 minutes"), async (request, response) => {
router.get("/api/status-page/:slug", cache("5 minutes"), async (request, response) => { router.get("/api/status-page/:slug", cache("5 minutes"), async (request, response) => {
allowDevAllOrigin(response); allowDevAllOrigin(response);
let slug = request.params.slug; let slug = request.params.slug;
slug = slug.toLowerCase();
try { try {
// Get Status Page // Get Status Page
@@ -72,7 +69,6 @@ router.get("/api/status-page/heartbeat/:slug", cache("1 minutes"), async (reques
let uptimeList = {}; let uptimeList = {};
let slug = request.params.slug; let slug = request.params.slug;
slug = slug.toLowerCase();
let statusPageID = await StatusPage.slugToID(slug); let statusPageID = await StatusPage.slugToID(slug);
let monitorIDList = await R.getCol(` let monitorIDList = await R.getCol(`
@@ -115,7 +111,6 @@ router.get("/api/status-page/heartbeat/:slug", cache("1 minutes"), async (reques
router.get("/api/status-page/:slug/manifest.json", cache("1440 minutes"), async (request, response) => { router.get("/api/status-page/:slug/manifest.json", cache("1440 minutes"), async (request, response) => {
allowDevAllOrigin(response); allowDevAllOrigin(response);
let slug = request.params.slug; let slug = request.params.slug;
slug = slug.toLowerCase();
try { try {
// Get Status Page // Get Status Page
@@ -150,8 +145,7 @@ router.get("/api/status-page/:slug/manifest.json", cache("1440 minutes"), async
// overall status-page status badge // overall status-page status badge
router.get("/api/status-page/:slug/badge", cache("5 minutes"), async (request, response) => { router.get("/api/status-page/:slug/badge", cache("5 minutes"), async (request, response) => {
allowDevAllOrigin(response); allowDevAllOrigin(response);
let slug = request.params.slug; const slug = request.params.slug;
slug = slug.toLowerCase();
const statusPageID = await StatusPage.slugToID(slug); const statusPageID = await StatusPage.slugToID(slug);
const { const {
label, label,

View File

@@ -220,9 +220,6 @@ module.exports.statusPageSocketHandler = (socket) => {
// Delete groups that are not in the list // Delete groups that are not in the list
log.debug("socket", "Delete groups that are not in the list"); log.debug("socket", "Delete groups that are not in the list");
if (groupIDList.length === 0) {
await R.exec("DELETE FROM `group` WHERE status_page_id = ?", [ statusPage.id ]);
} else {
const slots = groupIDList.map(() => "?").join(","); const slots = groupIDList.map(() => "?").join(",");
const data = [ const data = [
@@ -230,7 +227,6 @@ module.exports.statusPageSocketHandler = (socket) => {
statusPage.id statusPage.id
]; ];
await R.exec(`DELETE FROM \`group\` WHERE id NOT IN (${slots}) AND status_page_id = ?`, data); await R.exec(`DELETE FROM \`group\` WHERE id NOT IN (${slots}) AND status_page_id = ?`, data);
}
const server = UptimeKumaServer.getInstance(); const server = UptimeKumaServer.getInstance();
@@ -292,7 +288,6 @@ module.exports.statusPageSocketHandler = (socket) => {
ok: true, ok: true,
msg: "successAdded", msg: "successAdded",
msgi18n: true, msgi18n: true,
slug: slug
}); });
} catch (error) { } catch (error) {

View File

@@ -1,22 +0,0 @@
const ColumnCompilerMySQL = require("knex/lib/dialects/mysql/schema/mysql-columncompiler");
const { formatDefault } = require("knex/lib/formatter/formatterUtils");
const { log } = require("../../../../../../../src/util");
class KumaColumnCompiler extends ColumnCompilerMySQL {
/**
* Override defaultTo method to handle default value for TEXT fields
* @param {any} value Value
* @returns {string|void} Default value (Don't understand why it can return void or string, but it's the original code, lol)
*/
defaultTo(value) {
if (this.type === "text" && typeof value === "string") {
log.debug("defaultTo", `${this.args[0]}: ${this.type} ${value} ${typeof value}`);
// MySQL 8.0 is required and only if the value is written as an expression: https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html
// MariaDB 10.2 is required: https://mariadb.com/kb/en/text/
return `default (${formatDefault(value, this.type, this.client)})`;
}
return super.defaultTo.apply(this, arguments);
}
}
module.exports = KumaColumnCompiler;

View File

@@ -619,7 +619,7 @@ $shadow-box-padding: 20px;
bottom: 0; bottom: 0;
margin-left: -$shadow-box-padding; margin-left: -$shadow-box-padding;
margin-right: -$shadow-box-padding; margin-right: -$shadow-box-padding;
z-index: 10; z-index: 100;
background-color: rgba(white, 0.2); background-color: rgba(white, 0.2);
backdrop-filter: blur(2px); backdrop-filter: blur(2px);
border-radius: 0 0 10px 10px; border-radius: 0 0 10px 10px;

View File

@@ -73,6 +73,12 @@ export default {
} }
}, },
created() {
if (this.model.length === 0) {
this.addCondition();
}
},
methods: { methods: {
getNewGroup() { getNewGroup() {
return { return {

View File

@@ -163,7 +163,6 @@ export default {
"ZohoCliq": "ZohoCliq", "ZohoCliq": "ZohoCliq",
"SevenIO": "SevenIO", "SevenIO": "SevenIO",
"whapi": "WhatsApp (Whapi)", "whapi": "WhatsApp (Whapi)",
"waha": "WhatsApp (WAHA)",
"gtxmessaging": "GtxMessaging", "gtxmessaging": "GtxMessaging",
"Cellsynt": "Cellsynt", "Cellsynt": "Cellsynt",
"SendGrid": "SendGrid" "SendGrid": "SendGrid"
@@ -182,10 +181,8 @@ export default {
"SMSManager": "SmsManager (smsmanager.cz)", "SMSManager": "SmsManager (smsmanager.cz)",
"WeCom": "WeCom (ф╝Бф╕Ъх╛оф┐бч╛дцЬ║хЩиф║║)", "WeCom": "WeCom (ф╝Бф╕Ъх╛оф┐бч╛дцЬ║хЩиф║║)",
"ServerChan": "ServerChan (ServerщЕ▒)", "ServerChan": "ServerChan (ServerщЕ▒)",
"PushPlus": "PushPlus (цОищАБхКа)",
"smsc": "SMSC", "smsc": "SMSC",
"WPush": "WPush(wpush.cn)", "WPush": "WPush(wpush.cn)",
"YZJ": "YZJ (ф║Сф╣Лхо╢шЗкхоЪф╣ЙцЬ║хЩиф║║)"
}; };
// Sort by notification name // Sort by notification name

View File

@@ -197,7 +197,7 @@ export default {
return tagOptions; return tagOptions;
}, },
selectedTags() { selectedTags() {
return this.preSelectedTags.concat(this.newTags).filter(tag => !this.deleteTags.find(monitorTag => monitorTag.tag_id === tag.tag_id)); return this.preSelectedTags.concat(this.newTags).filter(tag => !this.deleteTags.find(monitorTag => monitorTag.id === tag.id));
}, },
colorOptions() { colorOptions() {
return colorOptions(this); return colorOptions(this);

View File

@@ -1,75 +0,0 @@
<template>
<div class="form-text mb-2">
<i18n-t tag="div" keypath="liquidIntroduction">
<a href="https://liquidjs.com/" target="_blank">{{ $t("documentation") }}</a>
</i18n-t>
<code v-pre>{{ msg }}</code>: {{ $t("templateMsg") }}<br />
<code v-pre>{{ name }}</code>: {{ $t("templateServiceName") }}<br />
<code v-pre>{{ status }}</code>: {{ $t("templateStatus") }}<br />
<code v-pre>{{ hostnameOrURL }}</code>: {{ $t("templateHostnameOrURL") }}<br />
<code v-pre>{{ heartbeatJSON }}</code>: {{ $t("templateHeartbeatJSON") }} <b>({{ $t("templateLimitedToUpDownNotifications") }})</b><br />
<code v-pre>{{ monitorJSON }}</code>: {{ $t("templateMonitorJSON") }} <b>({{ $t("templateLimitedToUpDownCertNotifications") }})</b><br />
</div>
<input
:id="id"
ref="templatedInput"
v-model="model"
type="text"
class="form-control"
:placeholder="placeholder"
:required="required"
autocomplete="false"
>
</template>
<script>
export default {
props: {
/**
* The value of the templated input.
*/
modelValue: {
type: String,
default: ""
},
/**
* id for the templated input.
*/
id: {
type: String,
required: true,
},
/**
* Whether the templated input is required.
* @example true
*/
required: {
type: Boolean,
required: true,
},
/**
* Placeholder text for the templated input.
*/
placeholder: {
type: String,
default: ""
},
},
emits: [ "update:modelValue" ],
computed: {
/**
* Send value update to parent on change.
*/
model: {
get() {
return this.modelValue;
},
set(value) {
this.$emit("update:modelValue", value);
}
}
},
};
</script>

View File

@@ -1,80 +0,0 @@
<template>
<div class="form-text mb-2">
<i18n-t tag="div" keypath="liquidIntroduction">
<a href="https://liquidjs.com/" target="_blank">{{ $t("documentation") }}</a>
</i18n-t>
<code v-pre>{{ msg }}</code>: {{ $t("templateMsg") }}<br />
<code v-pre>{{ name }}</code>: {{ $t("templateServiceName") }}<br />
<code v-pre>{{ status }}</code>: {{ $t("templateStatus") }}<br />
<code v-pre>{{ hostnameOrURL }}</code>: {{ $t("templateHostnameOrURL") }}<br />
<code v-pre>{{ heartbeatJSON }}</code>: {{ $t("templateHeartbeatJSON") }} <b>({{ $t("templateLimitedToUpDownNotifications") }})</b><br />
<code v-pre>{{ monitorJSON }}</code>: {{ $t("templateMonitorJSON") }} <b>({{ $t("templateLimitedToUpDownCertNotifications") }})</b><br />
</div>
<textarea
:id="id"
ref="templatedTextarea"
v-model="model"
class="form-control"
:placeholder="placeholder"
:required="required"
autocomplete="false"
></textarea>
</template>
<script>
export default {
props: {
/**
* The value of the templated textarea.
*/
modelValue: {
type: String,
default: ""
},
/**
* id for the templated textarea.
*/
id: {
type: String,
required: true,
},
/**
* Whether the templated textarea is required.
* @example true
*/
required: {
type: Boolean,
required: true,
},
/**
* Placeholder text for the templated textarea.
*/
placeholder: {
type: String,
default: ""
},
},
emits: [ "update:modelValue" ],
computed: {
/**
* Send value update to parent on change.
*/
model: {
get() {
return this.modelValue;
},
set(value) {
this.$emit("update:modelValue", value);
}
}
},
};
</script>
<style lang="scss" scoped>
textarea {
min-height: 150px;
}
</style>

View File

@@ -1,19 +0,0 @@
<template>
<div class="mb-3">
<label for="pushPlus-sendkey" class="form-label">{{ $t("SendKey") }}</label>
<HiddenInput id="pushPlus-sendkey" v-model="$parent.notification.pushPlusSendKey" :required="true" autocomplete="new-password"></HiddenInput>
</div>
<i18n-t tag="div" keypath="More info on:" class="mb-3 form-text">
<a href="https://www.pushplus.plus/" target="_blank">https://www.pushplus.plus/</a>
</i18n-t>
</template>
<script>
import HiddenInput from "../HiddenInput.vue";
export default {
components: {
HiddenInput,
},
};
</script>

View File

@@ -67,15 +67,25 @@
<input id="to-bcc" v-model="$parent.notification.smtpBCC" type="text" class="form-control" autocomplete="false" :required="!hasRecipient"> <input id="to-bcc" v-model="$parent.notification.smtpBCC" type="text" class="form-control" autocomplete="false" :required="!hasRecipient">
</div> </div>
<p class="form-text">
<i18n-t tag="div" keypath="smtpLiquidIntroduction" class="form-text mb-3">
<a href="https://liquidjs.com/" target="_blank">{{ $t("documentation") }}</a>
</i18n-t>
<code v-pre>{{name}}</code>: {{ $t("emailTemplateServiceName") }}<br />
<code v-pre>{{msg}}</code>: {{ $t("emailTemplateMsg") }}<br />
<code v-pre>{{status}}</code>: {{ $t("emailTemplateStatus") }}<br />
<code v-pre>{{heartbeatJSON}}</code>: {{ $t("emailTemplateHeartbeatJSON") }}<b>{{ $t("emailTemplateLimitedToUpDownNotification") }}</b><br />
<code v-pre>{{monitorJSON}}</code>: {{ $t("emailTemplateMonitorJSON") }} <b>{{ $t("emailTemplateLimitedToUpDownNotification") }}</b><br />
<code v-pre>{{hostnameOrURL}}</code>: {{ $t("emailTemplateHostnameOrURL") }}<br />
</p>
<div class="mb-3"> <div class="mb-3">
<label for="subject-email" class="form-label">{{ $t("emailCustomSubject") }}</label> <label for="subject-email" class="form-label">{{ $t("emailCustomSubject") }}</label>
<TemplatedInput id="subject-email" v-model="$parent.notification.customSubject" :required="false" placeholder=""></TemplatedInput> <input id="subject-email" v-model="$parent.notification.customSubject" type="text" class="form-control" autocomplete="false" placeholder="">
<div class="form-text">{{ $t("leave blank for default subject") }}</div> <div class="form-text">{{ $t("leave blank for default subject") }}</div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="body-email" class="form-label">{{ $t("emailCustomBody") }}</label> <label for="body-email" class="form-label">{{ $t("emailCustomBody") }}</label>
<TemplatedTextarea id="body-email" v-model="$parent.notification.customBody" :required="false" placeholder=""></TemplatedTextarea> <textarea id="body-email" v-model="$parent.notification.customBody" type="text" class="form-control" autocomplete="false" placeholder=""></textarea>
<div class="form-text">{{ $t("leave blank for default body") }}</div> <div class="form-text">{{ $t("leave blank for default body") }}</div>
</div> </div>
@@ -114,15 +124,11 @@
<script> <script>
import HiddenInput from "../HiddenInput.vue"; import HiddenInput from "../HiddenInput.vue";
import TemplatedInput from "../TemplatedInput.vue";
import TemplatedTextarea from "../TemplatedTextarea.vue";
import ToggleSection from "../ToggleSection.vue"; import ToggleSection from "../ToggleSection.vue";
export default { export default {
components: { components: {
HiddenInput, HiddenInput,
TemplatedInput,
TemplatedTextarea,
ToggleSection, ToggleSection,
}, },
computed: { computed: {

View File

@@ -5,20 +5,20 @@
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="sendgrid-from-email" class="form-label">{{ $t("From Email") }}</label> <label for="sendgrid-from-email" class="form-label">{{ $t("From Email") }}</label>
<input id="sendgrid-from-email" v-model="$parent.notification.sendgridFromEmail" type="text" class="form-control" required> <input id="sendgrid-from-email" v-model="$parent.notification.sendgridFromEmail" type="email" class="form-control" required>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="sendgrid-to-email" class="form-label">{{ $t("To Email") }}</label> <label for="sendgrid-to-email" class="form-label">{{ $t("To Email") }}</label>
<input id="sendgrid-to-email" v-model="$parent.notification.sendgridToEmail" type="text" class="form-control" required> <input id="sendgrid-to-email" v-model="$parent.notification.sendgridToEmail" type="email" class="form-control" required>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="sendgrid-cc-email" class="form-label">{{ $t("smtpCC") }}</label> <label for="sendgrid-cc-email" class="form-label">{{ $t("smtpCC") }}</label>
<input id="sendgrid-cc-email" v-model="$parent.notification.sendgridCcEmail" type="text" class="form-control"> <input id="sendgrid-cc-email" v-model="$parent.notification.sendgridCcEmail" type="email" class="form-control">
<div class="form-text">{{ $t("Separate multiple email addresses with commas") }}</div> <div class="form-text">{{ $t("Separate multiple email addresses with commas") }}</div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="sendgrid-bcc-email" class="form-label">{{ $t("smtpBCC") }}</label> <label for="sendgrid-bcc-email" class="form-label">{{ $t("smtpBCC") }}</label>
<input id="sendgrid-bcc-email" v-model="$parent.notification.sendgridBccEmail" type="text" class="form-control"> <input id="sendgrid-bcc-email" v-model="$parent.notification.sendgridBccEmail" type="email" class="form-control">
<small class="form-text text-muted">{{ $t("Separate multiple email addresses with commas") }}</small> <small class="form-text text-muted">{{ $t("Separate multiple email addresses with commas") }}</small>
</div> </div>
<div class="mb-3"> <div class="mb-3">

View File

@@ -4,9 +4,6 @@
<input id="slack-webhook-url" v-model="$parent.notification.slackwebhookURL" type="text" class="form-control" required> <input id="slack-webhook-url" v-model="$parent.notification.slackwebhookURL" type="text" class="form-control" required>
<label for="slack-username" class="form-label">{{ $t("Username") }}</label> <label for="slack-username" class="form-label">{{ $t("Username") }}</label>
<input id="slack-username" v-model="$parent.notification.slackusername" type="text" class="form-control"> <input id="slack-username" v-model="$parent.notification.slackusername" type="text" class="form-control">
<div class="form-text">
{{ $t("aboutSlackUsername") }}
</div>
<label for="slack-iconemo" class="form-label">{{ $t("Icon Emoji") }}</label> <label for="slack-iconemo" class="form-label">{{ $t("Icon Emoji") }}</label>
<input id="slack-iconemo" v-model="$parent.notification.slackiconemo" type="text" class="form-control"> <input id="slack-iconemo" v-model="$parent.notification.slackiconemo" type="text" class="form-control">
<label for="slack-channel" class="form-label">{{ $t("Channel Name") }}</label> <label for="slack-channel" class="form-label">{{ $t("Channel Name") }}</label>

View File

@@ -33,56 +33,6 @@
<input id="message_thread_id" v-model="$parent.notification.telegramMessageThreadID" type="text" class="form-control"> <input id="message_thread_id" v-model="$parent.notification.telegramMessageThreadID" type="text" class="form-control">
<p class="form-text">{{ $t("telegramMessageThreadIDDescription") }}</p> <p class="form-text">{{ $t("telegramMessageThreadIDDescription") }}</p>
<label for="server_url" class="form-label">{{ $t("telegramServerUrl") }}</label>
<input id="server_url" v-model="$parent.notification.telegramServerUrl" type="text" class="form-control">
<div class="form-text">
<i18n-t keypath="telegramServerUrlDescription">
<a
href="https://core.telegram.org/bots/api#using-a-local-bot-api-server"
target="_blank"
>{{ $t("here") }}</a>
<a
href="https://api.telegram.org"
target="_blank"
>https://api.telegram.org</a>
</i18n-t>
</div>
</div>
<div class="mb-3">
<div class="form-check form-switch">
<input v-model="$parent.notification.telegramUseTemplate" class="form-check-input" type="checkbox">
<label class="form-check-label">{{ $t("telegramUseTemplate") }}</label>
</div>
<div class="form-text">
{{ $t("telegramUseTemplateDescription") }}
</div>
</div>
<template v-if="$parent.notification.telegramUseTemplate">
<div class="mb-3">
<label class="form-label" for="message_parse_mode">{{ $t("Message Format") }}</label>
<select
id="message_parse_mode"
v-model="$parent.notification.telegramTemplateParseMode"
class="form-select"
required
>
<option value="plain">{{ $t("Plain Text") }}</option>
<option value="HTML">HTML</option>
<option value="MarkdownV2">MarkdownV2</option>
</select>
<i18n-t tag="p" keypath="telegramTemplateFormatDescription" class="form-text">
<a href="https://core.telegram.org/bots/api#formatting-options" target="_blank">{{ $t("documentation") }}</a>
</i18n-t>
<label class="form-label" for="message_template">{{ $t('Message Template') }}</label>
<TemplatedTextarea id="message_template" v-model="$parent.notification.telegramTemplate" :required="true" :placeholder="telegramTemplatedTextareaPlaceholder"></TemplatedTextarea>
</div>
</template>
<div class="mb-3">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input v-model="$parent.notification.telegramSendSilently" class="form-check-input" type="checkbox"> <input v-model="$parent.notification.telegramSendSilently" class="form-check-input" type="checkbox">
<label class="form-check-label">{{ $t("telegramSendSilently") }}</label> <label class="form-check-label">{{ $t("telegramSendSilently") }}</label>
@@ -107,27 +57,11 @@
<script> <script>
import HiddenInput from "../HiddenInput.vue"; import HiddenInput from "../HiddenInput.vue";
import TemplatedTextarea from "../TemplatedTextarea.vue";
import axios from "axios"; import axios from "axios";
export default { export default {
components: { components: {
HiddenInput, HiddenInput,
TemplatedTextarea,
},
computed: {
telegramTemplatedTextareaPlaceholder() {
return this.$t("Example:", [
`
Uptime Kuma Alert{% if monitorJSON %} - {{ monitorJSON['name'] }}{% endif %}
{{ msg }}
`,
]);
}
},
mounted() {
this.$parent.notification.telegramServerUrl ||= "https://api.telegram.org";
}, },
methods: { methods: {
/** /**
@@ -146,7 +80,7 @@ Uptime Kuma Alert{% if monitorJSON %} - {{ monitorJSON['name'] }}{% endif %}
} }
} }
return `${this.$parent.notification.telegramServerUrl}/bot${token}/getUpdates`; return `https://api.telegram.org/bot${token}/getUpdates`;
}, },
/** /**
@@ -181,9 +115,3 @@ Uptime Kuma Alert{% if monitorJSON %} - {{ monitorJSON['name'] }}{% endif %}
} }
}; };
</script> </script>
<style lang="scss" scoped>
textarea {
min-height: 150px;
}
</style>

View File

@@ -1,38 +0,0 @@
<template>
<div class="mb-3">
<label for="waha-api-url" class="form-label">{{ $t("API URL") }}</label>
<input id="waha-api-url" v-model="$parent.notification.wahaApiUrl" placeholder="http://localhost:3000/" type="url" class="form-control" required>
<div class="form-text">{{ $t("wayToGetWahaApiUrl") }}</div>
</div>
<div class="mb-3">
<label for="waha-api-key" class="form-label">{{ $t("API Key") }}</label>
<HiddenInput id="waha-api-key" v-model="$parent.notification.wahaApiKey" :required="false" autocomplete="new-password"></HiddenInput>
<div class="form-text">{{ $t("wayToGetWahaApiKey") }}</div>
</div>
<div class="mb-3">
<label for="waha-session" class="form-label">{{ $t("wahaSession") }}</label>
<input id="waha-session" v-model="$parent.notification.wahaSession" type="text" placeholder="default" class="form-control" required>
<div class="form-text">{{ $t("wayToGetWahaSession") }}</div>
</div>
<div class="mb-3">
<label for="waha-chat-id" class="form-label">{{ $t("wahaChatId") }}</label>
<input id="waha-chat-id" v-model="$parent.notification.wahaChatId" type="text" pattern="^[\d-]{10,31}$" class="form-control" required>
<div class="form-text">{{ $t("wayToWriteWahaChatId", ["00117612345678", "00117612345678@c.us", "123456789012345678@g.us"]) }}</div>
</div>
<i18n-t tag="div" keypath="More info on:" class="mb-3 form-text">
<a href="https://waha.devlike.pro/" target="_blank">https://waha.devlike.pro/</a>
</i18n-t>
</template>
<script>
import HiddenInput from "../HiddenInput.vue";
export default {
components: {
HiddenInput,
}
};
</script>

View File

@@ -32,7 +32,20 @@
</template> </template>
</i18n-t> </i18n-t>
<template v-else-if="$parent.notification.webhookContentType == 'custom'"> <template v-else-if="$parent.notification.webhookContentType == 'custom'">
<TemplatedTextarea id="customBody" v-model="$parent.notification.webhookCustomBody" :required="true" :placeholder="customBodyPlaceholder"></TemplatedTextarea> <i18n-t tag="div" keypath="liquidIntroduction" class="form-text">
<a href="https://liquidjs.com/" target="_blank">{{ $t("documentation") }}</a>
</i18n-t>
<code v-pre>{{msg}}</code>: {{ $t("templateMsg") }}<br />
<code v-pre>{{heartbeatJSON}}</code>: {{ $t("templateHeartbeatJSON") }} <b>({{ $t("templateLimitedToUpDownNotifications") }})</b><br />
<code v-pre>{{monitorJSON}}</code>: {{ $t("templateMonitorJSON") }} <b>({{ $t("templateLimitedToUpDownCertNotifications") }})</b><br />
<textarea
id="customBody"
v-model="$parent.notification.webhookCustomBody"
class="form-control"
:placeholder="customBodyPlaceholder"
required
></textarea>
</template> </template>
</div> </div>
@@ -54,12 +67,7 @@
</template> </template>
<script> <script>
import TemplatedTextarea from "../TemplatedTextarea.vue";
export default { export default {
components: {
TemplatedTextarea,
},
data() { data() {
return { return {
showAdditionalHeadersField: this.$parent.notification.webhookAdditionalHeaders != null, showAdditionalHeadersField: this.$parent.notification.webhookAdditionalHeaders != null,

View File

@@ -1,19 +0,0 @@
<template>
<div class="mb-3">
<label for="yzjWebHookUrl" class="form-label">{{ $t("YZJ Webhook URL") }}<span style="color: red;"><sup>*</sup></span></label>
<input id="yzjWebHookUrl" v-model="$parent.notification.yzjWebHookUrl" type="url" class="form-control" required />
<i18n-t class="form-text" keypath="wayToGetTeamsURL">
<a href="https://www.yunzhijia.com/opendocs/docs.html#/tutorial/index/robot" target="_blank">{{ $t("here") }}</a>
</i18n-t>
</div>
<div class="mb-3">
<label for="yzjToken" class="form-label">{{ $t("YZJ Robot Token") }}<span style="color: red;"><sup>*</sup></span></label>
<HiddenInput id="yzjToken" v-model="$parent.notification.yzjToken" :required="true" autocomplete="new-password"></HiddenInput>
<i18n-t class="form-text" keypath="wayToGetLineNotifyToken">
<a href="https://www.yunzhijia.com/opendocs/docs.html#/server-api/im/index?id=%e6%8e%a5%e5%8f%a3%e5%9c%b0%e5%9d%80%e5%92%8c%e6%8e%88%e6%9d%83%e7%a0%81" target="_blank">{{ $t("here") }}</a>
</i18n-t>
</div>
</template>
<script setup lang="ts">
import HiddenInput from "../HiddenInput.vue";
</script>

View File

@@ -39,7 +39,6 @@ import PromoSMS from "./PromoSMS.vue";
import Pushbullet from "./Pushbullet.vue"; import Pushbullet from "./Pushbullet.vue";
import PushDeer from "./PushDeer.vue"; import PushDeer from "./PushDeer.vue";
import Pushover from "./Pushover.vue"; import Pushover from "./Pushover.vue";
import PushPlus from "./PushPlus.vue";
import Pushy from "./Pushy.vue"; import Pushy from "./Pushy.vue";
import RocketChat from "./RocketChat.vue"; import RocketChat from "./RocketChat.vue";
import ServerChan from "./ServerChan.vue"; import ServerChan from "./ServerChan.vue";
@@ -64,12 +63,10 @@ import ZohoCliq from "./ZohoCliq.vue";
import Splunk from "./Splunk.vue"; import Splunk from "./Splunk.vue";
import SevenIO from "./SevenIO.vue"; import SevenIO from "./SevenIO.vue";
import Whapi from "./Whapi.vue"; import Whapi from "./Whapi.vue";
import WAHA from "./WAHA.vue";
import Cellsynt from "./Cellsynt.vue"; import Cellsynt from "./Cellsynt.vue";
import WPush from "./WPush.vue"; import WPush from "./WPush.vue";
import SIGNL4 from "./SIGNL4.vue"; import SIGNL4 from "./SIGNL4.vue";
import SendGrid from "./SendGrid.vue"; import SendGrid from "./SendGrid.vue";
import YZJ from "./YZJ.vue";
/** /**
* Manage all notification form. * Manage all notification form.
@@ -117,7 +114,6 @@ const NotificationFormList = {
"PushByTechulus": TechulusPush, "PushByTechulus": TechulusPush,
"PushDeer": PushDeer, "PushDeer": PushDeer,
"pushover": Pushover, "pushover": Pushover,
"PushPlus": PushPlus,
"pushy": Pushy, "pushy": Pushy,
"rocket.chat": RocketChat, "rocket.chat": RocketChat,
"serwersms": SerwerSMS, "serwersms": SerwerSMS,
@@ -142,12 +138,10 @@ const NotificationFormList = {
"ZohoCliq": ZohoCliq, "ZohoCliq": ZohoCliq,
"SevenIO": SevenIO, "SevenIO": SevenIO,
"whapi": Whapi, "whapi": Whapi,
"waha": WAHA,
"gtxmessaging": GtxMessaging, "gtxmessaging": GtxMessaging,
"Cellsynt": Cellsynt, "Cellsynt": Cellsynt,
"WPush": WPush, "WPush": WPush,
"SendGrid": SendGrid, "SendGrid": SendGrid,
"YZJ": YZJ,
}; };
export default NotificationFormList; export default NotificationFormList;

View File

@@ -31,7 +31,6 @@ const languageList = {
"sv-SE": "Svenska", "sv-SE": "Svenska",
"tr-TR": "T├╝rk├зe", "tr-TR": "T├╝rk├зe",
"ko-KR": "эХЬъ╡ньЦ┤", "ko-KR": "эХЬъ╡ньЦ┤",
"lt": "Lietuvi┼│",
"ru-RU": "╨а╤Г╤Б╤Б╨║╨╕╨╣", "ru-RU": "╨а╤Г╤Б╤Б╨║╨╕╨╣",
"zh-CN": "чоАф╜Уф╕нцЦЗ", "zh-CN": "чоАф╜Уф╕нцЦЗ",
"pl": "Polski", "pl": "Polski",

View File

@@ -733,12 +733,5 @@
"Remove the expiry notification": "╪е╪▓╪з┘Д╪й ╪к┘Ж╪и┘К┘З ┘К┘И┘Е ╪к╪з╪▒┘К╪о ╪з┘Д╪е┘Ж╪к┘З╪з╪б", "Remove the expiry notification": "╪е╪▓╪з┘Д╪й ╪к┘Ж╪и┘К┘З ┘К┘И┘Е ╪к╪з╪▒┘К╪о ╪з┘Д╪е┘Ж╪к┘З╪з╪б",
"tailscalePingWarning": "┘Е┘Ж ╪г╪м┘Д ╪з╪│╪к╪о╪п╪з┘Е ┘Е╪▒╪з┘В╪и╪й Tailscale Ping╪М ╪к╪н╪к╪з╪м ╪е┘Д┘Й ╪к╪л╪и┘К╪к Uptime Kuma ╪и╪п┘И┘Ж Docker ┘И┘Г╪░┘Д┘Г ╪к╪л╪и┘К╪к ╪╣┘Е┘К┘Д Tailscale ╪╣┘Д┘Й ╪з┘Д╪о╪з╪п┘Е ╪з┘Д╪о╪з╪╡ ╪и┘Г.", "tailscalePingWarning": "┘Е┘Ж ╪г╪м┘Д ╪з╪│╪к╪о╪п╪з┘Е ┘Е╪▒╪з┘В╪и╪й Tailscale Ping╪М ╪к╪н╪к╪з╪м ╪е┘Д┘Й ╪к╪л╪и┘К╪к Uptime Kuma ╪и╪п┘И┘Ж Docker ┘И┘Г╪░┘Д┘Г ╪к╪л╪и┘К╪к ╪╣┘Е┘К┘Д Tailscale ╪╣┘Д┘Й ╪з┘Д╪о╪з╪п┘Е ╪з┘Д╪о╪з╪╡ ╪и┘Г.",
"Clone Monitor": "┘Ж╪│╪о ╪з┘Д┘Е╪▒╪з┘В╪и╪й", "Clone Monitor": "┘Ж╪│╪о ╪з┘Д┘Е╪▒╪з┘В╪и╪й",
"telegramMessageThreadIDDescription": "┘Е╪╣╪▒┘Б ┘Б╪▒┘К╪п ╪з╪о╪к┘К╪з╪▒┘К ┘Д╪│┘Д╪│┘Д╪й ╪з┘Д╪▒╪│╪з╪ж┘Д ╪з┘Д┘Е╪│╪к┘З╪п┘Б╪й (╪з┘Д┘Е┘И╪╢┘И╪╣) ┘Б┘К ╪з┘Д┘Е┘Ж╪к╪п┘Й╪Ы ┘Д┘Е╪м┘Е┘И╪╣╪з╪к ╪з┘Д┘Е┘Ж╪к╪п┘Й ╪з┘Д┘Г╪и╪▒┘Й ┘Б┘В╪╖", "telegramMessageThreadIDDescription": "┘Е╪╣╪▒┘Б ┘Б╪▒┘К╪п ╪з╪о╪к┘К╪з╪▒┘К ┘Д╪│┘Д╪│┘Д╪й ╪з┘Д╪▒╪│╪з╪ж┘Д ╪з┘Д┘Е╪│╪к┘З╪п┘Б╪й (╪з┘Д┘Е┘И╪╢┘И╪╣) ┘Б┘К ╪з┘Д┘Е┘Ж╪к╪п┘Й╪Ы ┘Д┘Е╪м┘Е┘И╪╣╪з╪к ╪з┘Д┘Е┘Ж╪к╪п┘Й ╪з┘Д┘Г╪и╪▒┘Й ┘Б┘В╪╖"
"emailCustomBody": "┘Ж╪╡ ┘Е╪о╪╡╪╡",
"emailTemplateStatus": "╪з┘Д╪н╪з┘Д╪й",
"leave blank for default subject": "╪з╪к╪▒┘Г ┘Б╪з╪▒╪║╪з┘Л ┘Д┘К╪к┘Е ╪к╪╣┘К┘К┘Ж ╪з┘Д┘Е┘И╪╢┘И╪╣ ╪к┘Д┘В╪з╪ж┘К╪з┘Л",
"leave blank for default body": "╪з╪к╪▒┘Г ┘Б╪з╪▒╪║╪з┘Л ┘Д┘К╪к┘Е ╪к╪╣┘К┘К┘Ж ╪з┘Д┘Ж╪╡ ╪к┘Д┘В╪з╪ж┘К╪з┘Л",
"emailTemplateServiceName": "╪з╪│┘Е ╪з┘Д╪о╪п┘Е╪й",
"emailTemplateHostnameOrURL": "╪з╪│┘Е ╪з┘Д┘Е╪╢┘К┘Б ╪г┘И ╪╣┘Ж┘И╪з┘Ж URL",
"smspartnerPhoneNumber": "╪▒┘В┘Е ╪з┘Д┘З╪з╪к┘Б"
} }

View File

@@ -1088,34 +1088,5 @@
"From": "╨Ю╤В", "From": "╨Ю╤В",
"Can be found on:": "╨Ь╨╛╨╢╤В╨╡ ╨┤╨░ ╤Б╨╡ ╨╛╤В╨║╤А╨╕╨╡╤В╨╡ ╨╜╨░: {0}", "Can be found on:": "╨Ь╨╛╨╢╤В╨╡ ╨┤╨░ ╤Б╨╡ ╨╛╤В╨║╤А╨╕╨╡╤В╨╡ ╨╜╨░: {0}",
"The phone number of the recipient in E.164 format.": "╨в╨╡╨╗╨╡╤Д╨╛╨╜╨╜╨╕╤П╤В ╨╜╨╛╨╝╨╡╤А ╨╜╨░ ╨┐╨╛╨╗╤Г╤З╨░╤В╨╡╨╗╤П ╨▓╤К╨▓ ╤Д╨╛╤А╨╝╨░╤В E.164.", "The phone number of the recipient in E.164 format.": "╨в╨╡╨╗╨╡╤Д╨╛╨╜╨╜╨╕╤П╤В ╨╜╨╛╨╝╨╡╤А ╨╜╨░ ╨┐╨╛╨╗╤Г╤З╨░╤В╨╡╨╗╤П ╨▓╤К╨▓ ╤Д╨╛╤А╨╝╨░╤В E.164.",
"Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "╨Ш╨┤╨╡╨╜╤В╨╕╤Д╨╕╨║╨░╤Ж╨╕╨╛╨╜╨╡╨╜ ╨╜╨╛╨╝╨╡╤А ╨╜╨░ ╨┐╨╛╨┤╨░╤В╨╡╨╗╤П ╨╜╨░ ╤В╨╡╨║╤Б╤В╨░ ╨╕╨╗╨╕ ╤В╨╡╨╗╨╡╤Д╨╛╨╜╨╡╨╜ ╨╜╨╛╨╝╨╡╤А ╨▓╤К╨▓ ╤Д╨╛╤А╨╝╨░╤В E.164, ╨▓ ╤Б╨╗╤Г╤З╨░╨╣, ╤З╨╡ ╨╢╨╡╨╗╨░╨╡╤В╨╡ ╨┤╨░ ╨┐╨╛╨╗╤Г╤З╨░╨▓╨░╤В╨╡ ╨╛╤В╨│╨╛╨▓╨╛╤А╨╕.", "Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "╨Ш╨┤╨╡╨╜╤В╨╕╤Д╨╕╨║╨░╤Ж╨╕╨╛╨╜╨╡╨╜ ╨╜╨╛╨╝╨╡╤А ╨╜╨░ ╨┐╨╛╨┤╨░╤В╨╡╨╗╤П ╨╜╨░ ╤В╨╡╨║╤Б╤В╨░ ╨╕╨╗╨╕ ╤В╨╡╨╗╨╡╤Д╨╛╨╜╨╡╨╜ ╨╜╨╛╨╝╨╡╤А ╨▓╤К╨▓ ╤Д╨╛╤А╨╝╨░╤В E.164, ╨▓ ╤Б╨╗╤Г╤З╨░╨╣, ╤З╨╡ ╨╢╨╡╨╗╨░╨╡╤В╨╡ ╨┤╨░ ╨┐╨╛╨╗╤Г╤З╨░╨▓╨░╤В╨╡ ╨╛╤В╨│╨╛╨▓╨╛╤А╨╕."
"rabbitmqNodesRequired": "╨Ь╨╛╨╗╤П, ╨╖╨░╨┤╨░╨╣╤В╨╡ ╨▓╤К╨╖╨╗╨╕╤В╨╡ ╨╖╨░ ╤В╨╛╨╖╨╕ ╨╝╨╛╨╜╨╕╤В╨╛╤А.",
"rabbitmqNodesInvalid": "╨Ь╨╛╨╗╤П, ╨╕╨╖╨┐╨╛╨╗╨╖╨▓╨░╨╣╤В╨╡ ╨┐╤К╨╗╨╜╨╕╤П URL ╨░╨┤╤А╨╡╤Б (╨╖╨░╨┐╨╛╤З╨▓╨░╤Й ╤Б 'http') ╨╖╨░ RabbitMQ ╨▓╤К╨╖╨╗╨╕.",
"RabbitMQ Password": "RabbitMQ ╨┐╨░╤А╨╛╨╗╨░",
"RabbitMQ Username": "RabbitMQ ╨┐╨╛╤В╤А╨╡╨▒╨╕╤В╨╡╨╗",
"SendGrid API Key": "SendGrid API ╨║╨╗╤О╤З",
"Separate multiple email addresses with commas": "╨а╨░╨╖╨┤╨╡╨╗╤П╨╣╤В╨╡ ╨╛╤В╨┤╨╡╨╗╨╜╨╕╤В╨╡ ╨╕╨╝╨╡╨╣╨╗ ╨░╨┤╤А╨╡╤Б╨╕ ╤Б╤К╤Б ╨╖╨░╨┐╨╡╤В╨░╨╕",
"RabbitMQ Nodes": "╨Т╤К╨╖╨╗╨╕ ╨╖╨░ ╤Г╨┐╤А╨░╨▓╨╗╨╡╨╜╨╕╨╡ ╨╜╨░ RabbitMQ",
"rabbitmqNodesDescription": "╨Т╤К╨▓╨╡╨┤╨╡╤В╨╡ URL ╨░╨┤╤А╨╡╤Б╨░ ╨╜╨░ ╨▓╤К╨╖╨╗╨╕╤В╨╡ ╨╖╨░ ╤Г╨┐╤А╨░╨▓╨╗╨╡╨╜╨╕╨╡ ╨╜╨░ RabbitMQ, ╨▓╨║╨╗╤О╤З╨╕╤В╨╡╨╗╨╜╨╛ ╨┐╤А╨╛╤В╨╛╨║╨╛╨╗ ╨╕ ╨┐╨╛╤А╤В. ╨Я╤А╨╕╨╝╨╡╤А: {0}",
"rabbitmqHelpText": "╨Ч╨░ ╨┤╨░ ╨╕╨╖╨┐╨╛╨╗╨╖╨▓╨░╤В╨╡ ╨╝╨╛╨╜╨╕╤В╨╛╤А╨░, ╤Й╨╡ ╤В╤А╤П╨▒╨▓╨░ ╨┤╨░ ╨░╨║╤В╨╕╨▓╨╕╤А╨░╤В╨╡ ╨┤╨╛╨▒╨░╨▓╨║╨░╤В╨░ ╨╖╨░ ╤Г╨┐╤А╨░╨▓╨╗╨╡╨╜╨╕╨╡ ╨▓╤К╨▓ ╨▓╨░╤И╨░╤В╨░ ╨╜╨░╤Б╤В╤А╨╛╨╣╨║╨░ ╨╜╨░ RabbitMQ. ╨Ч╨░ ╨┐╨╛╨▓╨╡╤З╨╡ ╨╕╨╜╤Д╨╛╤А╨╝╨░╤Ж╨╕╤П ╨╝╨╛╨╗╤П, ╨▓╨╕╨╢╤В╨╡ {rabitmq_documentation}.",
"aboutSlackUsername": "╨Я╤А╨╛╨╝╨╡╨╜╤П ╨┐╨╛╨║╨░╨╖╨▓╨░╨╜╨╛╤В╨╛ ╨╕╨╝╨╡ ╨╜╨░ ╨┐╨╛╨┤╨░╤В╨╡╨╗╤П ╨╜╨░ ╤Б╤К╨╛╨▒╤Й╨╡╨╜╨╕╨╡╤В╨╛. ╨Р╨║╨╛ ╨╢╨╡╨╗╨░╨╡╤В╨╡ ╨┤╨░ ╤Б╨┐╨╛╨╝╨╡╨╜╨╡╤В╨╡ ╨╜╤П╨║╨╛╨│╨╛, ╨▓╨╝╨╡╤Б╤В╨╛ ╤В╨╛╨▓╨░ ╨│╨╛ ╨▓╨║╨╗╤О╤З╨╡╤В╨╡ ╨▓ ╨┐╤А╨╕╤П╤В╨╡╨╗╤Б╨║╨╛╤В╨╛ ╨╕╨╝╨╡.",
"YZJ Robot Token": "YZJ Robot ╤В╨╛╨║╨╡╨╜ ╨║╨╛╨┤",
"YZJ Webhook URL": "YZJ ╨г╨╡╨▒ ╨║╤Г╨║╨░ URL ╨░╨┤╤А╨╡╤Б",
"templateServiceName": "╨╕╨╝╨╡ ╨╜╨░ ╤Г╤Б╨╗╤Г╨│╨░╤В╨░",
"templateHostnameOrURL": "╨╕╨╝╨╡ ╨╜╨░ ╤Е╨╛╤Б╤В╨░ ╨╕╨╗╨╕ URL ╨░╨┤╤А╨╡╤Б",
"Plain Text": "╨Ю╨▒╨╕╨║╨╜╨╛╨▓╨╡╨╜ ╤В╨╡╨║╤Б╤В",
"Message Template": "╨и╨░╨▒╨╗╨╛╨╜ ╨╖╨░ ╤Б╤К╨╛╨▒╤Й╨╡╨╜╨╕╨╡",
"templateStatus": "╤Б╤В╨░╤В╤Г╤Б",
"telegramUseTemplate": "╨Ш╨╖╨┐╨╛╨╗╨╖╨▓╨░╨╣ ╨┐╨╡╤А╤Б╨╛╨╜╨░╨╗╨╕╨╖╨╕╤А╨░╨╜ ╤И╨░╨▒╨╗╨╛╨╜ ╨╖╨░ ╤Б╤К╨╛╨▒╤Й╨╡╨╜╨╕╨╡",
"telegramUseTemplateDescription": "╨Р╨║╨╛ ╨╡ ╨░╨║╤В╨╕╨▓╨╕╤А╨░╨╜╨╛, ╤Б╤К╨╛╨▒╤Й╨╡╨╜╨╕╨╡╤В╨╛ ╤Й╨╡ ╨▒╤К╨┤╨╡ ╨╕╨╖╨┐╤А╨░╤В╨╡╨╜╨╛ ╤З╤А╨╡╨╖ ╨┐╨╡╤А╤Б╨╛╨╜╨░╨╗╨╕╨╖╨╕╤А╨░╨╜ ╤И╨░╨▒╨╗╨╛╨╜.",
"telegramTemplateFormatDescription": "Telegram ╨┐╨╛╨╖╨▓╨╛╨╗╤П╨▓╨░ ╨╕╨╖╨┐╨╛╨╗╨╖╨▓╨░╨╜╨╡╤В╨╛ ╨╜╨░ ╤А╨░╨╖╨╗╨╕╤З╨╜╨╕ \"markup\" ╨╡╨╖╨╕╤Ж╨╕ ╨╖╨░ ╤Б╤К╨╛╨▒╤Й╨╡╨╜╨╕╤П╤В╨░. ╨Т╨╕╨╢╤В╨╡ Telegram {0} ╨╖╨░ ╨┤╨╡╤В╨░╨╣╨╗╨╕.",
"Template Format": "╨д╨╛╤А╨╝╨░╤В ╨╜╨░ ╤И╨░╨▒╨╗╨╛╨╜╨░",
"wayToGetWahaApiUrl": "╨Т╨░╤И╨╕╤П╤В WAHA URL ╨░╨┤╤А╨╡╤Б.",
"wahaSession": "╨б╨╡╤Б╨╕╤П",
"wahaChatId": "╨з╨░╤В ID (╤В╨╡╨╗╨╡╤Д╨╛╨╜╨╡╨╜ ╨╜╨╛╨╝╨╡╤А / ID ╨╜╨░ ╨║╨╛╨╜╤В╨░╨║╤В / ID ╨╜╨░ ╨│╤А╤Г╨┐╨░)",
"wayToGetWahaApiKey": "API ╨║╨╗╤О╤З╤К╤В, ╨╡ ╤Б╤В╨╛╨╣╨╜╨╛╤Б╤В╤В╨░ ╨╜╨░ ╨┐╤А╨╛╨╝╨╡╨╜╨╗╨╕╨▓╨░╤В╨░ WHATSAPP_API_KEY, ╨║╨╛╤П╤В╨╛ ╤Б╤В╨╡ ╨╕╨╖╨┐╨╛╨╗╨╖╨▓╨░╨╗╨╕ ╨╖╨░ ╤Б╤В╨░╤А╤В╨╕╤А╨░╨╜╨╡ ╨╜╨░ WAHA.",
"wayToWriteWahaChatId": "╨в╨╡╨╗╨╡╤Д╨╛╨╜╨╜╨╕╤П╤В ╨╜╨╛╨╝╨╡╤А ╤Б ╨╝╨╡╨╢╨┤╤Г╨╜╨░╤А╨╛╨┤╨╜╨╕╤П ╨┐╤А╨╡╤Д╨╕╨║╤Б, ╨╜╨╛ ╨▒╨╡╨╖ ╨╖╨╜╨░╨║╨░ ╨┐╨╗╤О╤Б ╨▓ ╨╜╨░╤З╨░╨╗╨╛╤В╨╛ ({0}), ID ╨╜╨░ ╨║╨╛╨╜╤В╨░╨║╤В╨░ ({1}) ╨╕╨╗╨╕ ID ╨╜╨░ ╨│╤А╤Г╨┐╨░╤В╨░ ({2}). ╨Ш╨╖╨▓╨╡╤Б╤В╨╕╤П╤В╨░ ╤Б╨╡ ╨╕╨╖╨┐╤А╨░╤Й╨░╤В ╨┤╨╛ ╤В╨╛╨▓╨░ ╤З╨░╤В ID ╨╛╤В WAHA ╤Б╨╡╤Б╨╕╤П.",
"wayToGetWahaSession": "╨Ю╤В ╤В╨░╨╖╨╕ ╤Б╨╡╤Б╨╕╤П WAHA ╨╕╨╖╨┐╤А╨░╤Й╨░ ╨╕╨╖╨▓╨╡╤Б╤В╨╕╤П ╨┤╨╛ ╤З╨░╤В ID. ╨Ь╨╛╨╢╨╡╤В╨╡ ╨┤╨░ ╨│╨╛ ╨╜╨░╨╝╨╡╤А╨╕╤В╨╡ ╨▓ ╤В╨░╨▒╨╗╨╛╤В╨╛ ╨╖╨░ ╤Г╨┐╤А╨░╨▓╨╗╨╡╨╜╨╕╨╡ ╨╜╨░ WAHA.",
"telegramServerUrlDescription": "╨Ч╨░ ╨┐╤А╨╡╨╝╨░╤Е╨▓╨░╨╜╨╡ ╨╜╨░ API ╨▒╨╛╤В ╨╛╨│╤А╨░╨╜╨╕╤З╨╡╨╜╨╕╤П╤В╨░ ╨╖╨░ Telegram ╨╕╨╗╨╕ ╨╖╨░ ╨┐╨╛╨╗╤Г╤З╨░╨▓╨░╨╜╨╡ ╨╜╨░ ╨┤╨╛╤Б╤В╤К╨┐ ╨▓ ╨▒╨╗╨╛╨║╨╕╤А╨░╨╜╨╕ ╨╖╨╛╨╜╨╕ (╨Ъ╨╕╤В╨░╨╣, ╨Ш╤А╨░╨╜ ╨╕ ╨┤╤А.). ╨Ч╨░ ╨┐╨╛╨▓╨╡╤З╨╡ ╨╕╨╜╤Д╨╛╤А╨╝╨░╤Ж╨╕╤П ╤Й╤А╨░╨║╨╜╨╡╤В╨╡ ╨▓╤К╤А╤Е╤Г {0}. ╨Я╨╛ ╨┐╨╛╨┤╤А╨░╨╖╨▒╨╕╤А╨░╨╜╨╡: {1}",
"telegramServerUrl": "(╨Я╨╛ ╨╕╨╖╨▒╨╛╤А) URL ╨░╨┤╤А╨╡╤Б ╨╜╨░ ╤Б╤К╤А╨▓╤К╤А╨░"
} }

View File

@@ -1,10 +1,10 @@
{ {
"setupDatabaseChooseDatabase": "ржЖржкржирж┐ ржХрзЛржи ржбрж╛ржЯрж╛ржмрзЗржЬржЯрж┐ ржмрзНржпржмрж╣рж╛рж░ ржХрж░рждрзЗ ржЪрж╛ржи?", "setupDatabaseChooseDatabase": "ржЖржкржирж┐ ржХрзЛржи ржбрж╛ржЯрж╛ржмрзЗржЬржЯрж┐ ржмрзНржпржмрж╣рж╛рж░ ржХрж░рждрзЗ ржЪрж╛ржи?",
"setupDatabaseEmbeddedMariaDB": "ржЖржкржирж╛ржХрзЗ ржХрж┐ржЫрзБ рж╕рзЗржЯржЖржк ржХрж░рж╛рж░ ржкрзНрж░ржпрж╝рзЛржЬржи ржирзЗржЗред ржПржЗ ржбржХрж╛рж░ ржЗржорзЗржЬрзЗ рж╕рзНржмржпрж╝ржВржХрзНрж░рж┐ржпрж╝ржнрж╛ржмрзЗ MariaDB ржПржорзНржмрзЗржб ржПржмржВ ржХржиржлрж┐ржЧрж╛рж░ ржХрж░рж╛ рж╣ржпрж╝рзЗржЫрзЗред Uptime Kuma ржПржЗ ржбрж╛ржЯрж╛ржмрзЗржЬрзЗрж░ рж╕рж╛ржерзЗ ржЗржЙржирж┐ржХрзНрж╕ рж╕ржХрзЗржЯрзЗрж░ ржорж╛ржзрзНржпржорзЗ рж╕ржВржпрзБржХрзНржд рж╣ржмрзЗред", "setupDatabaseEmbeddedMariaDB": "ржЖржкржирж╛ржХрзЗ ржХрж┐ржЫрзБ ржирж┐ржпрзБржХрзНржд ржХрж░рждрзЗ рж╣ржмрзЗ ржирж╛ред ржПржЗ ржбржХрж╛рж░ ржЗржорзЗржЬржЯрж┐ (Docker image) рж╕рзНржмржпрж╝ржВржХрзНрж░рж┐ржпрж╝ржнрж╛ржмрзЗ ржЖржкржирж╛рж░ ржЬржирзНржп ржорж╛рж░рж┐рзЯрж╛ ржбрж┐ржмрж┐ (MariaDB) ржмрж╕рж┐рзЯрзЗржЫрзЗ ржПржмржВ ржкрзНрж░рж╕рзНрждрзБржд ржХрж░рзЗржЫрзЗредUptime Kuma ржЗржЙржирж┐ржХрзНрж╕ рж╕ржХрзЗржЯрзЗрж░ (Unix Socket) ржорж╛ржзрзНржпржорзЗ ржПржЗ ржбрж╛ржЯрж╛ржмрзЗрж╕рзЗрж░ рж╕рж╛ржерзЗ рж╕ржВржпрзБржХрзНржд рж╣ржмрзЗред",
"setupDatabaseMariaDB": "ржмрж╣рж┐рж░рж╛ржЧржд MariaDB ржбрж╛ржЯрж╛ржмрзЗржЬрзЗрж░ рж╕рж╛ржерзЗ рж╕ржВржпрзЛржЧ ржХрж░рждрзЗ рж╣ржмрзЗред ржЖржкржирж╛ржХрзЗ ржбрж╛ржЯрж╛ржмрзЗржЬрзЗрж░ рж╕ржВржпрзЛржЧ рждржерзНржп рж╕рзЗржЯ ржХрж░рждрзЗ рж╣ржмрзЗред", "setupDatabaseMariaDB": "ржПржХржЯрж┐ ржмрж╣рж┐рж░рж╛ржЧржд ржорж╛рж░рж┐рзЯрж╛ ржбрж┐ржмрж┐ (MariaDB) ржбрж╛ржЯрж╛ржмрзЗрж╕рзЗрж░ рж╕рж╛ржерзЗ рж╕ржВржпрзЛржЧ ржХрж░рзБржиред ржЖржкржирж╛ржХрзЗ ржбрж╛ржЯрж╛ржмрзЗрж╕ рж╕ржВржпрзЛржЧ рждржерзНржп ржирж┐ржпрзБржХрзНржд ржХрж░рждрзЗ рж╣ржмрзЗред",
"Add": "рж╕ржВржпрзЛржЧ ржХрж░рзБржи", "Add": "рж╕ржВржпрзЛржЧ ржХрж░рзБржи",
"dbName": "ржбрж╛ржЯрж╛ржмрзЗржЬрзЗрж░ ржирж╛ржо", "dbName": "ржбрж╛ржЯрж╛ржмрзЗржЬрзЗрж░ ржирж╛ржо",
"languageName": "ржмрж╛ржВрж▓рж╛", "languageName": "ржЗржВрж░рзЗржЬрж┐",
"Settings": "рж╕рзЗржЯрж┐ржВрж╕", "Settings": "рж╕рзЗржЯрж┐ржВрж╕",
"Dashboard": "ржбрзНржпрж╛рж╢ржмрзЛрж░рзНржб", "Dashboard": "ржбрзНржпрж╛рж╢ржмрзЛрж░рзНржб",
"Help": "рж╕рж╛рж╣рж╛ржпрзНржп", "Help": "рж╕рж╛рж╣рж╛ржпрзНржп",
@@ -14,216 +14,5 @@
"Check Update On GitHub": "GitHub-ржП ржЖржкржбрзЗржЯ ржЪрзЗржХ ржХрж░рзБржи", "Check Update On GitHub": "GitHub-ржП ржЖржкржбрзЗржЯ ржЪрзЗржХ ржХрж░рзБржи",
"List": "рждрж╛рж▓рж┐ржХрж╛", "List": "рждрж╛рж▓рж┐ржХрж╛",
"General": "рж╕рж╛ржзрж╛рж░ржг", "General": "рж╕рж╛ржзрж╛рж░ржг",
"Game": "ржЦрзЗрж▓рж╛", "Game": "ржЦрзЗрж▓рж╛"
"disable authentication": "ржкрзНрж░ржорж╛ржгрзАржХрж░ржг ржмржирзНржз ржХрж░рзБржи",
"pauseDashboardHome": "ржерж╛ржорзБржи",
"disableauth.message2": "ржПржЯрж┐ Uptime Kuma ржПрж░ рж╕рж╛ржоржирзЗ {intendThirdPartyAuth} ржПрж░ ржорждрзЛ ржкрж░рж┐рж╕рзНржерж┐рждрж┐рж░ ржЬржирзНржп ржбрж┐ржЬрж╛ржЗржи ржХрж░рж╛ рж╣ржпрж╝рзЗржЫрзЗ, ржпрзЗржоржи Cloudflare Access, Authelia ржЕржержмрж╛ ржЕржирзНржпрж╛ржирзНржп ржкрзНрж░ржорж╛ржгрзАржХрж░ржг ржмрзНржпржмрж╕рзНржерж╛ред",
"I understand, please disable": "ржЖржорж┐ ржмрзБржЭрждрзЗ ржкрж╛рж░ржЫрж┐, ржжржпрж╝рж╛ ржХрж░рзЗ ржЕржХрзНрж╖ржо ржХрж░рзБржи",
"Certificate Info": "рж╕рж╛рж░рзНржЯрж┐ржлрж┐ржХрзЗржЯ рждржерзНржп",
"Create your admin account": "ржЖржкржирж╛рж░ ржЕрзНржпрж╛ржбржорж┐ржи ржЕрзНржпрж╛ржХрж╛ржЙржирзНржЯ рждрзИрж░рж┐ ржХрж░рзБржи",
"Import": "ржЗржоржкрзЛрж░рзНржЯ",
"Default enabled": "ржбрж┐ржлрж▓рзНржЯ рж╕ржХрзНрж░рж┐ржпрж╝",
"Heartbeats": "рж╣рж╛рж░рзНржЯржмрж┐ржЯ",
"Affected Monitors": "ржкрзНрж░ржнрж╛ржмрж┐ржд ржоржирж┐ржЯрж░ржЧрзБрж▓рзЛ",
"All Status Pages": "рж╕ржорж╕рзНржд рж╕рзНржЯрзНржпрж╛ржЯрж╛рж╕ ржкрзЗржЬ",
"alertNoFile": "ржЕржирзБржЧрзНрж░рж╣ ржХрж░рзЗ ржЖржоржжрж╛ржирж┐рж░ ржЬржирзНржп ржПржХржЯрж┐ ржлрж╛ржЗрж▓ ржирж┐рж░рзНржмрж╛ржЪржи ржХрж░рзБржиред",
"alertWrongFileType": "ржЕржирзБржЧрзНрж░рж╣ ржХрж░рзЗ ржПржХржЯрж┐ JSON ржлрж╛ржЗрж▓ ржирж┐рж░рзНржмрж╛ржЪржи ржХрж░рзБржиред",
"Clear all statistics": "рж╕ржм ржкрж░рж┐рж╕ржВржЦрзНржпрж╛ржи ржорзБржЫрзЗ ржлрзЗрж▓рзБржи",
"Setup 2FA": "2FA рж╕рзЗржЯ ржЖржк ржХрж░рзБржи",
"Two Factor Authentication": "ржжрзБржЗ ржлрзНржпрж╛ржХрзНржЯрж░ ржкрзНрж░ржорж╛ржгрзАржХрж░ржг",
"Add New Tag": "ржирждрзБржи ржЯрзНржпрж╛ржЧ ржпрзЛржЧ ржХрж░рзБржи",
"Tag with this name already exist.": "ржПржЗ ржирж╛ржорзЗрж░ ржЯрзНржпрж╛ржЧ ржЖржЧрзЗ ржерзЗржХрзЗржЗ ржЖржЫрзЗред",
"Pink": "ржЧрзЛрж▓рж╛ржкрзА",
"Search monitored sites": "ржкрж░рзНржпржмрзЗржХрзНрж╖ржг ржХрж░рж╛ рж╕рж╛ржЗржЯ ржЕржирзБрж╕ржирзНржзрж╛ржи",
"statusPageNothing": "ржПржЦрж╛ржирзЗ ржХрж┐ржЫрзБржЗ ржирзЗржЗ, ржЕржирзБржЧрзНрж░рж╣ ржХрж░рзЗ ржПржХржЯрж┐ ржЧрзНрж░рзБржк ржмрж╛ ржоржирж┐ржЯрж░ ржпрзЛржЧ ржХрж░рзБржиред",
"Degraded Service": "ржЕржзржГржкрждржи рж╕рзЗржмрж╛",
"Go to Dashboard": "ржбрзНржпрж╛рж╢ржмрзЛрж░рзНржбрзЗ ржпрж╛ржи",
"defaultNotificationName": "ржЖржорж╛рж░ {ржмрж┐ржЬрзНржЮржкрзНрждрж┐} рж╕рждрж░рзНржХрждрж╛ ({number})",
"webhookJsonDesc": "{0} ржпрзЗржХрзЛржирзЛ ржЖржзрзБржирж┐ржХ HTTP рж╕рж╛рж░рзНржнрж╛рж░ ржпрзЗржоржи Express.js-ржПрж░ ржЬржирзНржп ржнрж╛рж▓рзЛ",
"liquidIntroduction": "ржЯрзЗржорзНржкрж▓рзЗржЯржмрж┐рж▓рж┐ржЯрж┐ рж▓рж┐ржХрзБржЗржб ржЯрзЗржоржкрзНрж▓рзЗржЯрж┐ржВ ржнрж╛рж╖рж╛рж░ ржорж╛ржзрзНржпржорзЗ ржЕрж░рзНржЬржи ржХрж░рж╛ рж╣ржпрж╝ред ржмрзНржпржмрж╣рж╛рж░рзЗрж░ ржирж┐рж░рзНржжрзЗрж╢рж╛ржмрж▓рзАрж░ ржЬржирзНржп ржЕржирзБржЧрзНрж░рж╣ ржХрж░рзЗ {0} ржжрзЗржЦрзБржиред ржПржЗ ржЙржкрж▓ржмрзНржз ржнрзЗрж░рж┐ржпрж╝рзЗржмрж▓ рж╣рж▓:",
"Notifications": "ржирзЛржЯрж┐ржлрж┐ржХрзЗрж╢ржи",
"Setup Notification": "ржирзЛржЯрж┐ржлрж┐ржХрзЗрж╢ржи рж╕рзЗржЯржЖржк ржХрж░рзБржи",
"Light": "ржЖрж▓рзЛ",
"Auto": "рж╕рзНржмржпрж╝ржВржХрзНрж░рж┐ржпрж╝",
"Theme - Heartbeat Bar": "ржерж┐ржо - рж╣рж╛рж░рзНржЯржмрж┐ржЯ ржмрж╛рж░",
"styleElapsedTime": "рж╣рж╛рж░рзНржЯржмрж┐ржЯ ржмрж╛рж░рзЗрж░ ржирж┐ржЪрзЗ ржмрзНржпржмрж╣рзГржд рж╕ржоржпрж╝",
"styleElapsedTimeShowNoLine": "рж╢рзЛрж░ ржХрж░рзБржи (ржХрзЛржирзЛ рж▓рж╛ржЗржи ржирзЗржЗ)",
"styleElapsedTimeShowWithLine": "рж╢рзЛ ржХрж░рзБржи (рж▓рж╛ржЗржи рж╕рж╣)",
"Normal": "рж╕рзНржмрж╛ржнрж╛ржмрж┐ржХ",
"Bottom": "ржирзАржЪрзЗ",
"Timezone": "ржЯрж╛ржЗржоржЬрзЛржи",
"Search Engine Visibility": "рж╕рж╛рж░рзНржЪ ржЗржЮрзНржЬрж┐ржи ржжрзГрж╢рзНржпржорж╛ржирждрж╛",
"Allow indexing": "ржЗржирзНржбрзЗржХрзНрж╕рж┐ржВ ржЕржирзБржорзЛржжржи ржХрж░рзБржи",
"Discourage search engines from indexing site": "рж╕рж╛рж░рзНржЪ ржЗржЮрзНржЬрж┐ржиржЧрзБрж▓рзЛржХрзЗ рж╕рж╛ржЗржЯрзЗрж░ ржЗржирзНржбрзЗржХрзНрж╕рж┐ржВ ржерзЗржХрзЗ ржмрж┐рж░ржд рж░рж╛ржЦрзБржи",
"Change Password": "ржкрж╛рж╕ржУржпрж╝рж╛рж░рзНржб ржкрж░рж┐ржмрж░рзНрждржи ржХрж░рзБржи",
"Current Password": "ржмрж░рзНрждржорж╛ржи ржкрж╛рж╕ржУржпрж╝рж╛рж░рзНржб",
"New Password": "ржирждрзБржи ржкрж╛рж╕ржУржпрж╝рж╛рж░рзНржб",
"Repeat New Password": "ржирждрзБржи ржкрж╛рж╕ржУржпрж╝рж╛рж░рзНржбржЯрж┐ ржЖржмрж╛рж░ ржжрж┐ржи",
"Update Password": "ржкрж╛рж╕ржУржпрж╝рж╛рж░рзНржб ржЖржкржбрзЗржЯ ржХрж░рзБржи",
"Enable Auth": "ржкрзНрж░ржорж╛ржгрзАржХрж░ржг ржЪрж╛рж▓рзБ ржХрж░рзБржи",
"disableauth.message1": "ржЖржкржирж┐ ржХрж┐ рж╕рждрзНржпрж┐ржЗ {disableAuth} ржХрж░рждрзЗ ржЪрж╛ржи?",
"where you intend to implement third-party authentication": "ржпрзЗржЦрж╛ржирзЗ ржЖржкржирж┐ рждрзГрждрзАржпрж╝ ржкржХрзНрж╖рзЗрж░ ржкрзНрж░ржорж╛ржгрзАржХрж░ржг ржмрж╛рж╕рзНрждржмрж╛ржпрж╝ржи ржХрж░рждрзЗ ржЪрж╛ржи",
"Please use this option carefully!": "ржжржпрж╝рж╛ ржХрж░рзЗ ржПржЗ ржЕржкрж╢ржиржЯрж┐ рж╕рж╛ржмржзрж╛ржирзЗ ржмрзНржпржмрж╣рж╛рж░ ржХрж░рзБржи!",
"Logout": "рж▓ржЧ ржЖржЙржЯ",
"Leave": "рж▓рж┐ржн",
"Confirm": "ржирж┐рж╢рзНржЪрж┐ржд",
"Yes": "рж╣рзНржпрж╛ржБ",
"No": "ржирж╛",
"Username": "ржЗржЙржЬрж╛рж░ ржирзЗржо",
"Password": "ржкрж╛рж╕ржУржпрж╝рж╛рж░рзНржб",
"Remember me": "ржЖржорж╛ржХрзЗ ржоржирзЗ рж░рж╛ржЦрзБржи",
"Login": "рж▓ржЧ ржЗржи",
"add one": "ржПржХржЯрж┐ ржпрзЛржЧ ржХрж░рзБржи",
"Notification Type": "ржирзЛржЯрж┐ржлрж┐ржХрзЗрж╢ржирзЗрж░ ржзрж░ржи",
"Email": "ржЗржорзЗржЗрж▓",
"Test": "ржкрж░рзАржХрзНрж╖рж╛",
"Resolver Server": "рж╕ржорж╛ржзрж╛ржиржХрж╛рж░рзА рж╕рж╛рж░рзНржнрж╛рж░",
"Resource Record Type": "рж░рж┐рж╕рзЛрж░рзНрж╕ рж░рзЗржХрж░рзНржб ржЯрж╛ржЗржк",
"Last Result": "рж╢рзЗрж╖ ржлрж▓рж╛ржлрж▓",
"Repeat Password": "ржкрж╛рж╕ржУржпрж╝рж╛рж░рзНржб ржкрзБржирж░рж╛ржпрж╝ ржжрж┐ржи",
"Import Backup": "ржЗржоржкрзЛрж░рзНржЯ ржмрзНржпрж╛ржХржЖржк",
"Export Backup": "ржПржХрзНрж╕ржкрзЛрж░рзНржЯ ржмрзНржпрж╛ржХржЖржк",
"Export": "ржПржХрзНрж╕ржкрзЛрж░рзНржЯ",
"respTime": "ржкрзНрж░рждрж┐ржХрзНрж░рж┐ржпрж╝рж╛ рж╕ржоржпрж╝ (ms)",
"notAvailableShort": "ржкрзНрж░ржпрзЛржЬрзНржп ржиржпрж╝",
"Apply on all existing monitors": "рж╕ржорж╕рзНржд ржмрж┐ржжрзНржпржорж╛ржи ржоржирж┐ржЯрж░рзЗ ржкрзНрж░ржпрж╝рзЛржЧ ржХрж░рзБржи",
"Create": "рждрзИрж░рж┐",
"Clear Data": "ржбрзЗржЯрж╛ рж╕рж╛ржл",
"Events": "ржЗржнрзЗржирзНржЯ рж╕ржорзВрж╣",
"Auto Get": "ржЕржЯрзЛ ржЧрзНрж░рж╣ржг",
"Schedule maintenance": "рж░ржХрзНрж╖ржгрж╛ржмрзЗржХрзНрж╖ржг рж╕рзВржЪрзА ржХрж░рзБржи",
"Pick Affected Monitors...": "ржкрзНрж░ржнрж╛ржмрж┐ржд ржоржирж┐ржЯрж░ ржирж┐рж░рзНржмрж╛ржЪржи ржХрж░рзБржитАж",
"Start of maintenance": "рж░ржХрзНрж╖ржгрж╛ржмрзЗржХрзНрж╖ржгрзЗрж░ рж╢рзБрж░рзБ",
"Select status pages...": "рж╕рзНржЯрзНржпрж╛ржЯрж╛рж╕ ржкрзЗржЬржЧрзБрж▓рзЛ ржирж┐рж░рзНржмрж╛ржЪржи ржХрж░рзБржитАж",
"Skip existing": "ржмрж┐ржжрзНржпржорж╛ржи ржПржбрж╝рж┐ржпрж╝рзЗ ржпрж╛ржи",
"Overwrite": "ржУржнрж╛рж░рж░рж╛ржЗржЯ",
"Options": "ржЕржкрж╢ржи",
"Keep both": "ржжрзБржЯрзЛржЗ рж░рж╛ржЦрзБржи",
"Verify Token": "ржЯрзЛржХрзЗржи ржпрж╛ржЪрж╛ржЗ ржХрж░рзБржи",
"Enable 2FA": "2FA рж╕ржХрзНрж╖ржо ржХрж░рзБржи",
"Disable 2FA": "2FA ржирж┐рж╖рзНржХрзНрж░рж┐ржпрж╝ ржХрж░рзБржи",
"2FA Settings": "2FA рж╕рзЗржЯрж┐ржВрж╕",
"filterActive": "рж╕ржХрзНрж░рж┐ржпрж╝",
"filterActivePaused": "ржмрж┐рж░рждрж┐",
"Active": "рж╕ржХрзНрж░рж┐ржпрж╝",
"Inactive": "ржирж┐рж╖рзНржХрзНрж░рж┐ржпрж╝",
"Token": "ржЯрзЛржХрзЗржи",
"Show URI": "URI ржжрзЗржЦрж╛ржи",
"Tags": "ржЯрзНржпрж╛ржЧ",
"Add New below or Select...": "ржирзАржЪрзЗ ржирждрзБржи ржпрзЛржЧ ржХрж░рзБржи ржмрж╛ ржирж┐рж░рзНржмрж╛ржЪржи ржХрж░рзБржитАж",
"Tag with this value already exist.": "ржПржЗ ржорж╛ржи рж╕рж╣ ржЯрзНржпрж╛ржЧ ржЗрждрж┐ржоржзрзНржпрзЗржЗ ржмрж┐ржжрзНржпржорж╛ржиред",
"color": "рж░ржВ",
"value (optional)": "ржорж╛ржи (ржРржЪрзНржЫрж┐ржХ)",
"Red": "рж▓рж╛рж▓",
"Orange": "ржХржорж▓рж╛",
"Green": "рж╕ржмрзБржЬ",
"Blue": "ржирзАрж▓",
"Indigo": "ржирзАрж▓",
"Purple": "ржмрзЗржЧрзБржирж┐",
"Custom": "ржХрж╛рж╕рзНржЯржо",
"Search...": "ржЕржирзБрж╕ржирзНржзрж╛ржитАж",
"Avg. Ping": "ржЧржбрж╝ ржкрж┐ржВ",
"Avg. Response": "ржЧржбрж╝ ржкрзНрж░рждрж┐ржХрзНрж░рж┐ржпрж╝рж╛",
"Entry Page": "ржкрзНрж░ржмрзЗрж╢ ржкрзГрж╖рзНржарж╛",
"statusPageRefreshIn": "рж░рж┐ржлрзНрж░рзЗрж╢ рж╣ржмрзЗ: {0}",
"No Services": "ржХрзЛржирзЛ ржкрж░рж┐рж╖рзЗржмрж╛ ржирзЗржЗ",
"All Systems Operational": "рж╕ржорж╕рзНржд рж╕рж┐рж╕рзНржЯрзЗржо ржЕржкрж╛рж░рзЗрж╢ржирж╛рж▓",
"Partially Degraded Service": "ржЖржВрж╢рж┐ржХржнрж╛ржмрзЗ ржЕржмржиржорж┐ржд ржкрж░рж┐рж╖рзЗржмрж╛",
"Add Group": "ржЧрзНрж░рзБржк ржпрзЛржЧ ржХрж░рзБржи",
"Add a monitor": "ржПржХржЯрж┐ ржоржирж┐ржЯрж░ ржпрзЛржЧ ржХрж░рзБржи",
"Edit Status Page": "ржПржбрж┐ржЯ рж╕рзНржЯрзЗржЯрж╛рж╕ ржкрзЗржЬ",
"Status Page": "рж╕рзНржЯрзНржпрж╛ржЯрж╛рж╕ ржкрзЗржЬ",
"Status Pages": "рж╕рзНржЯрзНржпрж╛ржЯрж╛рж╕ ржкрзЗржЬ рж╕ржорзВрж╣",
"here": "ржПржЦрж╛ржирзЗ",
"Required": "ржкрзНрж░ржпрж╝рзЛржЬржи",
"Post URL": "ржкрзЛрж╕рзНржЯ URL",
"Content Type": "ржмрж┐рж╖ржпрж╝ржмрж╕рзНрждрзБрж░ ржкрзНрж░ржХрж╛рж░",
"webhookFormDataDesc": "{multipart} PHP ржПрж░ ржЬржирзНржп ржнрж╛рж▓рзЛред JSON-ржХрзЗ {decodeFunction} ржжрж┐ржпрж╝рзЗ ржкрж╛рж░рзНрж╕ ржХрж░рждрзЗ рж╣ржмрзЗ",
"templateMsg": "ржмрж┐ржЬрзНржЮржкрзНрждрж┐рж░ ржмрж╛рж░рзНрждрж╛",
"templateHeartbeatJSON": "рж╣рзГржжрж╕рзНржкржирзНржжржи ржмрж░рзНржгржирж╛ржХрж╛рж░рзА ржмрж╕рзНрждрзБ",
"templateMonitorJSON": "ржоржирж┐ржЯрж░рзЗрж░ ржмрж░рзНржгржирж╛ржХрж╛рж░рзА ржмрж╕рзНрждрзБ",
"templateLimitedToUpDownNotifications": "рж╢рзБржзрзБржорж╛рждрзНрж░ UP/DOWN ржмрж┐ржЬрзНржЮржкрзНрждрж┐рж░ ржЬржирзНржп ржЙржкрж▓ржмрзНржз",
"Gray": "ржзрзВрж╕рж░",
"Add New Monitor": "ржирждрзБржи ржЖржкржЯрж╛ржЗржо ржоржирж┐ржЯрж░ ржпрзЛржЧ ржХрж░рзБржи",
"statusMaintenance": "рж░ржХрзНрж╖ржгрж╛ржмрзЗржХрзНрж╖ржг",
"Friendly Name": "ржмржирзНржзрзБрждрзНржмржкрзВрж░рзНржг ржирж╛ржо",
"URL": "ржЗржЙржЖрж░ржПрж▓",
"settingUpDatabaseMSG": "ржбрж╛ржЯрж╛ржмрзЗрж╕ рж╕рзЗржЯржЖржк ржХрж░рж╛ рж╣ржЪрзНржЫрзЗред ржПржЯрж┐ ржХрж┐ржЫрзБржЯрж╛ рж╕ржоржпрж╝ ржирж┐рждрзЗ ржкрж╛рж░рзЗ, ржЕржирзБржЧрзНрж░рж╣ ржХрж░рзЗ ржзрзИрж░рзНржп ржзрж░рзБржиред",
"Response": "рж░рзЗрж╕ржкржирзНрж╕",
"Ping": "ржкрж┐ржВ",
"Keyword": "ржХрзАржУржпрж╝рж╛рж░рзНржб",
"Invert Keyword": "ржЗржиржнрж╛рж░рзНржЯ ржХрзАржУржпрж╝рж╛рж░рзНржб",
"setupDatabaseSQLite": "ржПржХржЯрж┐ рж╕рж╛ржзрж╛рж░ржг ржбрж╛ржЯрж╛ржмрзЗрж╕ ржлрж╛ржЗрж▓, ржпрж╛ ржЫрзЛржЯ ржкрж░рж┐рж╕рж░рзЗрж░ ржбрж┐ржкрзНрж▓ржпрж╝ржорзЗржирзНржЯрзЗрж░ ржЬржирзНржп рж╕рзБржкрж╛рж░рж┐рж╢ ржХрж░рж╛ рж╣ржпрж╝ред v2.0.0 ржПрж░ ржкрзВрж░рзНржмрзЗ, Uptime Kuma ржбрж┐ржлрж▓рзНржЯ ржбрж╛ржЯрж╛ржмрзЗрж╕ рж╣рж┐рж╕рзЗржмрзЗ SQLite ржмрзНржпржмрж╣рж╛рж░ ржХрж░рждред",
"Unknown": "ржЕржЬрж╛ржирж╛",
"Cannot connect to the socket server": "рж╕ржХрзЗржЯ рж╕рж╛рж░рзНржнрж╛рж░рзЗрж░ рж╕рж╛ржерзЗ рж╕ржВржпрзЛржЧ рж╕рзНржерж╛ржкржи ржХрж░рж╛ ржпрж╛ржЪрзНржЫрзЗ ржирж╛",
"Reconnecting...": "ржкрзБржирж░рж╛ржпрж╝ рж╕ржВржпрзЛржЧ рж╕рзНржерж╛ржкржи ржХрж░рж╛ рж╣ржЪрзНржЫрзЗ...",
"Passive Monitor Type": "ржирж┐рж╖рзНржХрзНрж░рж┐ржпрж╝ ржоржирж┐ржЯрж░рзЗрж░ ржзрж░ржи",
"markdownSupported": "ржорж╛рж░рзНржХржбрж╛ржЙржи рж╕рж┐ржиржЯрзНржпрж╛ржХрзНрж╕ рж╕рж╛ржкрзЛрж░рзНржЯ",
"Pause": "ржерж╛ржорзБржи",
"-day": "-ржжрж┐ржи",
"hour": "ржШржирзНржЯрж╛",
"Host URL": "рж╣рзЛрж╕рзНржЯ ржЗржЙржЖрж░ржПрж▓",
"Either enter the hostname of the server you want to connect to or localhost if you intend to use a locally configured mail transfer agent": "ржЖржкржирж┐ ржпрзЗ рж╕рж╛рж░рзНржнрж╛рж░рзЗ рж╕ржВржпрзЛржЧ ржХрж░рждрзЗ ржЪрж╛ржи рждрж╛рж░ рж╣рзЛрж╕рзНржЯржирзЗржо ржкрзНрж░ржмрзЗрж╢ ржХрж░рзБржи ржЕржержмрж╛ ржпржжрж┐ ржЖржкржирж┐ ржПржХржЯрж┐ {local_mta} ржмрзНржпржмрж╣рж╛рж░ ржХрж░рж╛рж░ ржкрж░рж┐ржХрж▓рзНржкржирж╛ ржХрж░рзЗржи, рждрж╛рж╣рж▓рзЗ {localhost} рж▓рж┐ржЦрзБржи",
"ignoreTLSErrorGeneral": "рж╕ржВржпрзЛржЧрзЗрж░ ржЬржирзНржп TLS/SSL рждрзНрж░рзБржЯрж┐ ржЙржкрзЗржХрзНрж╖рж╛ ржХрж░рзБржи",
"Upside Down Mode": "ржЖржкрж╕рж╛ржЗржб ржбрж╛ржЙржи ржорзЛржб",
"Pending": "ржкрзНрж░ржХрзНрж░рж┐ржпрж╝рж╛ржзрзАржи",
"Push URL": "ржкрзБрж╢ URL",
"needPushEvery": "ржЖржкржирж╛ржХрзЗ ржПржЗ URL ржЯрж┐ ржкрзНрж░рждрж┐ {0} рж╕рзЗржХрзЗржирзНржбрзЗ ржХрж▓ ржХрж░рждрзЗ рж╣ржмрзЗред",
"Dark": "ржЕржирзНржзржХрж╛рж░",
"Up": "ржЖржк",
"webhookAdditionalHeadersTitle": "ржЕрждрж┐рж░рж┐ржХрзНржд рж╢рж┐рж░рзЛржирж╛ржо",
"pushOthers": "ржЕржирзНржпрж╛ржирзНржп",
"programmingLanguages": "ржкрзНрж░рзЛржЧрзНрж░рж╛ржорж┐ржВ ржнрж╛рж╖рж╛рж╕ржорзВрж╣",
"Not available, please setup.": "ржЙржкрж▓ржмрзНржз ржиржпрж╝, ржЕржирзБржЧрзНрж░рж╣ ржХрж░рзЗ рж╕рзЗржЯржЖржк ржХрж░рзБржиред",
"Down": "ржбрж╛ржЙржи",
"Monitor Type": "ржоржирж┐ржЯрж░рзЗрж░ ржзрж░ржи",
"Expected Value": "ржкрзНрж░рждрзНржпрж╛рж╢рж┐ржд ржорж╛ржи",
"Home": "рж╣рзЛржо",
"Maintenance": "рж░ржХрзНрж╖ржгрж╛ржмрзЗржХрзНрж╖ржг",
"General Monitor Type": "рж╕рж╛ржзрж╛рж░ржг ржоржирж┐ржЯрж░рзЗрж░ ржзрж░ржи",
"Specific Monitor Type": "ржирж┐рж░рзНржжрж┐рж╖рзНржЯ ржоржирж┐ржЯрж░рзЗрж░ ржзрж░ржи",
"Monitor": "ржоржирж┐ржЯрж░ | ржоржирж┐ржЯрж░ржЧрзБрж▓рзЛ",
"day": "ржжрж┐ржи | ржжрж┐ржиржЧрзБрж▓рзЛ",
"-hour": "-ржШржирзНржЯрж╛",
"Hostname": "рж╣рзЛрж╕рзНржЯржирзЗржо",
"locally configured mail transfer agent": "рж▓рзЛржХрж╛рж▓рж┐ ржХржиржлрж┐ржЧрж╛рж░ржб ржорзЗржЗрж▓ ржЯрзНрж░рж╛ржирзНрж╕ржлрж╛рж░ ржПржЬрзЗржирзНржЯ",
"Port": "ржкрзЛрж░рзНржЯ",
"Heartbeat Interval": "рж╣рж╛рж░рзНржЯржмрж┐ржЯ ржЗржирзНржЯрж╛рж░ржнрж╛рж▓",
"Max. Redirects": "рж╕рж░рзНржмрзЛржЪрзНржЪ рж░рж┐ржбрж╛ржЗрж░рзЗржХрзНржЯ",
"Primary Base URL": "ржкрзНрж░рж╛ржержорж┐ржХ ржмрзЗрж╕ URL",
"Message": "ржмрж╛рж░рзНрждрж╛",
"Resume": "ржкрзБржирж░рж╛ржпрж╝ рж╢рзБрж░рзБ",
"Delete": "ржорзБржЫрзЗ ржлрзЗрж▓рзБржи",
"now": "ржПржЦржи",
"time ago": "{рзж} ржмрзЯрж╕",
"-year": "-ржмржЫрж░",
"Json Query Expression": "JSON ржХрзЛржпрж╝рзЗрж░рж┐ ржПржХрзНрж╕ржкрзНрж░рзЗрж╢ржи",
"timeoutAfter": "{0} рж╕рзЗржХрзЗржирзНржб ржкрж░ ржЯрж╛ржЗржоржЖржЙржЯ",
"Retries": "ржкрзБржирж░рж╛ржпрж╝ ржЪрзЗрж╖рзНржЯрж╛ ржХрж░рзЗ",
"checkEverySecond": "ржкрзНрж░рждрж┐ржЯрж┐ {0} рж╕рзЗржХрзЗржирзНржбрзЗ ржЪрзЗржХ ржХрж░рзБржи",
"retryCheckEverySecond": "ржкрзНрж░рждрж┐ржЯрж┐ {0} рж╕рзЗржХрзЗржирзНржбрзЗ ржкрзБржирж░рж╛рзЯ ржЪрзЗрж╖рзНржЯрж╛ ржХрж░рзБржи",
"resendEveryXTimes": "ржкрзНрж░рждрж┐ржЯрж┐ {0} ржмрж╛рж░ ржкрзБржирж░рж╛рзЯ ржкрж╛ржарж╛ржи",
"pushOptionalParams": "ржРржЪрзНржЫрж┐ржХ ржкрзНржпрж╛рж░рж╛ржорж┐ржЯрж╛рж░рж╕ржорзВрж╣: {0}",
"Save": "рж╕ржВрж░ржХрзНрж╖ржг",
"ignoredTLSError": "TLS/SSL рждрзНрж░рзБржЯрж┐ржЧрзБрж▓рж┐ ржЙржкрзЗржХрзНрж╖рж╛ ржХрж░рж╛ рж╣ржпрж╝рзЗржЫрзЗ",
"Accepted Status Codes": "ржЧрзНрж░рж╣ржгржпрзЛржЧрзНржп рж╕рзНржЯрзНржпрж╛ржЯрж╛рж╕ ржХрзЛржбрж╕ржорзВрж╣",
"Disable Auth": "ржкрзНрж░ржорж╛ржгрзАржХрж░ржг ржмржирзНржз ржХрж░рзБржи",
"Theme": "ржерж┐ржо",
"Name": "ржирж╛ржо",
"Status": "ржЕржмрж╕рзНржерж╛",
"DateTime": "рждрж╛рж░рж┐ржЦ ржУ рж╕ржоржпрж╝",
"No important events": "ржХрзЛржирзЛ ржЧрзБрж░рзБрждрзНржмржкрзВрж░рзНржг ржЗржнрзЗржирзНржЯ ржирзЗржЗ",
"Edit": "рж╕ржорзНржкрж╛ржжржирж╛",
"Current": "ржмрж░рзНрждржорж╛ржи",
"Uptime": "ржЖржкржЯрж╛ржЗржо",
"Request Timeout": "рж░рж┐ржХрзЛрзЯрзЗрж╕рзНржЯ ржЯрж╛ржЗржоржЖржЙржЯ",
"Heartbeat Retry Interval": "рж╣рж╛рж░рзНржЯржмрж┐ржЯ рж░рж┐ржЯрзНрж░рж╛ржЗ ржЗржирзНржЯрж╛рж░ржнрж╛рж▓",
"Advanced": "ржЕрзНржпрж╛ржбржнрж╛ржирзНрж╕",
"retriesDescription": "рж╕рж╛рж░рзНржнрж┐рж╕ржЯрж┐ ржбрж╛ржЙржи рж╣рж┐рж╕рзЗржмрзЗ ржЪрж┐рж╣рзНржирж┐ржд рж╣ржУржпрж╝рж╛рж░ ржЖржЧрзЗ ржПржмржВ ржПржХржЯрж┐ ржирзЛржЯрж┐ржлрж┐ржХрзЗрж╢ржи ржкрж╛ржарж╛ржирзЛрж░ ржЬржирзНржп рж╕рж░рзНржмрзЛржЪрзНржЪ ржкрзБржирж░рж╛ржпрж╝ ржЪрзЗрж╖рзНржЯрж╛ ржХрж░рж╛рж░ рж╕ржВржЦрзНржпрж╛",
"upsideDownModeDescription": "рж╕рзНржЯрзНржпрж╛ржЯрж╛рж╕ржЯрж┐ ржЙрж▓рзНржЯрзЛ ржХрж░рзЗ ржжрж┐ржиред ржпржжрж┐ рж╕рж╛рж░рзНржнрж┐рж╕ржЯрж┐ ржкрзМржБржЫрж╛ржирзЛ ржпрж╛ржпрж╝, рждржмрзЗ ржПржЯрж┐ DOWN рж╣ржмрзЗред",
"maxRedirectDescription": "ржЕржирзБрж╕рж░ржг ржХрж░рж╛рж░ ржЬржирзНржп рж╕рж░рзНржмрзЛржЪрзНржЪ рж░рж┐ржбрж╛ржЗрж░рзЗржХрзНржЯ рж╕ржВржЦрзНржпрж╛ред рж░рж┐ржбрж╛ржЗрж░рзЗржХрзНржЯ ржирж┐рж╖рзНржХрзНрж░рж┐ржпрж╝ ржХрж░рждрзЗ 0 рж╕рзЗржЯ ржХрж░рзБржиред",
"ignoreTLSError": "HTTPS ржУржпрж╝рзЗржмрж╕рж╛ржЗржЯржЧрзБрж▓рж┐рж░ ржЬржирзНржп TLS/SSL рждрзНрж░рзБржЯрж┐ржЧрзБрж▓рж┐ ржЙржкрзЗржХрзНрж╖рж╛ ржХрж░рзБржи",
"pushViewCode": "ржкрзБрж╢ ржоржирж┐ржЯрж░ ржХрзАржнрж╛ржмрзЗ ржмрзНржпржмрж╣рж╛рж░ ржХрж░ржмрзЗржи? (ржХрзЛржб ржжрзЗржЦрзБржи)",
"Appearance": "ржжрзЗржЦрж╛ржирзЛрж░ ржзрж░ржи",
"Quick Stats": "рждрж╛рзОржХрзНрж╖ржгрж┐ржХ ржкрж░рж┐рж╕ржВржЦрзНржпрж╛ржи"
} }

View File

@@ -49,7 +49,7 @@
"Delete": "Eliminar", "Delete": "Eliminar",
"Current": "Actual", "Current": "Actual",
"Uptime": "Temps actiu", "Uptime": "Temps actiu",
"Cert Exp.": "Caducitat del certificat.", "Cert Exp.": "Caducitat del certificat",
"Monitor": "Monitor | Monitors", "Monitor": "Monitor | Monitors",
"day": "dia | dies", "day": "dia | dies",
"-day": "-dia", "-day": "-dia",
@@ -65,7 +65,7 @@
"URL": "URL", "URL": "URL",
"Hostname": "Nom del servidor", "Hostname": "Nom del servidor",
"Port": "Port", "Port": "Port",
"timeoutAfter": "┬бTimeout' despr├йs de {0} segons", "timeoutAfter": "┬бTimeout' despr├йs de {0",
"locally configured mail transfer agent": "Agent de transfer├иncia de correu configurat localment", "locally configured mail transfer agent": "Agent de transfer├иncia de correu configurat localment",
"Either enter the hostname of the server you want to connect to or localhost if you intend to use a locally configured mail transfer agent": "Introdu├пu el nom del servidor al qual voleu connectar-vos o {localhost} si voleu utilitzar un {local_mta}", "Either enter the hostname of the server you want to connect to or localhost if you intend to use a locally configured mail transfer agent": "Introdu├пu el nom del servidor al qual voleu connectar-vos o {localhost} si voleu utilitzar un {local_mta}",
"Host URL": "URL del servidor", "Host URL": "URL del servidor",
@@ -213,352 +213,5 @@
"Email": "Correu", "Email": "Correu",
"Last Result": "Darrer Resultat", "Last Result": "Darrer Resultat",
"Add New Tag": "Afegir nova etiqueta", "Add New Tag": "Afegir nova etiqueta",
"Tag with this value already exist.": "Ja existeix una etiqueta amb aquest valor.", "Tag with this value already exist.": "Ja existeix una etiqueta amb aquest valor."
"defaultNotificationName": "La meva {notification} Alerta ({number})",
"Required": "Obligatori",
"Post URL": "Posar URL",
"Content Type": "Content Type",
"Json Query Expression": "Expressi├│ de consulta Json",
"now": "ara",
"-year": "-any",
"Status Pages": "P├аgines d'estat",
"here": "aqu├н",
"time ago": "fa {0}",
"ignoredTLSError": "Errors TLS/SSL ignorats",
"webhookFormDataDesc": "{multipart} es bo per PHP. El JSON haur├а d'analitzar-se amb {decodeFunction}",
"webhookJsonDesc": "{0} es bo per qualsevol servidor HTTP modern com Express.js",
"templateMsg": "missatge de la notificaci├│",
"webhookAdditionalHeadersTitle": "Cap├зaleres addicionals",
"Application Token": "Testimoni d'aplicaci├│",
"Server URL": "URL del servidor",
"Priority": "Prioritat",
"Webhook URL": "URL del Webhook",
"emojiCheatSheet": "Full de trampa d'emoji: {0}",
"Read more": "Llegeix m├йs",
"appriseInstalled": "S'ha instal┬╖lat l'ap├иndix.",
"templateHeartbeatJSON": "objecte que descriu el batec del cor",
"templateMonitorJSON": "objecte que descriu el monitor",
"templateLimitedToUpDownCertNotifications": "nom├йs disponible per a notificacions de venciment UP/DOWN/Certificate",
"templateLimitedToUpDownNotifications": "nom├йs disponible per a notificacions UP/DOWN",
"webhookAdditionalHeadersDesc": "Estableix les cap├зaleres addicionals enviades amb el webhook. Cada cap├зalera s'ha de definir com una clau/valor JSON.",
"webhookBodyPresetOption": "Predefinit - {0}",
"webhookBodyCustomOption": "Cos personalitzat",
"Headers": "Cap├зaleres",
"Monitor History": "Historial del monitor",
"PasswordsDoNotMatch": "Les contrasenyes no coincideixen.",
"records": "registres",
"One record": "Un registre",
"Current User": "Usuari actual",
"topic": "Tema",
"topicExplanation": "tema MQTT a monitorar",
"successKeyword": "Paraula clau d'├иxit",
"successKeywordExplanation": "Paraula clau MQTT que es considerar├а un ├иxit",
"recent": "Recent",
"Reset Token": "Restableix el testimoni",
"Done": "Fet",
"Info": "Info",
"Steam API Key": "Clau API de Steam",
"Shrink Database": "Redueix la base de dades",
"Pick a RR-Type...": "Trieu un tipus RRтАж",
"Default": "Per defecte",
"HTTP Options": "Opcions HTTP",
"Create Incident": "Crear Incident",
"Title": "T├нtol",
"Content": "Contingut",
"Style": "Estil",
"info": "info",
"warning": "av├нs",
"danger": "perill",
"primary": "prim├аria",
"light": "lleuger",
"dark": "fosc",
"Post": "Post",
"Created": "Creat",
"Last Updated": "Darrera actualitzaci├│",
"Switch to Light Theme": "Canvia a tema clar",
"Switch to Dark Theme": "Canviar a tema fosc",
"Show Tags": "Mostra les etiquetes",
"Hide Tags": "Amaga les etiquetes",
"Description": "Descripci├│",
"No monitors available.": "No hi ha monitors disponibles.",
"Add one": "Afegeix-ne un",
"No Monitors": "Sense monitors",
"Untitled Group": "Grup sense t├нtol",
"Services": "Serveis",
"Discard": "Descarta",
"Cancel": "Canel┬╖la",
"Select": "Selecciona",
"Check/Uncheck": "Comprova/desmarca",
"Powered by": "Funciona amb",
"Customize": "Personalitza",
"Custom Footer": "Peu de p├аgina personalitzat",
"Custom CSS": "CSS personalitzat",
"default": "Per defecte",
"enabled": "Habilitat",
"setAsDefault": "Estableix com a predeterminat",
"deleteProxyMsg": "Esteu segur que voleu suprimir aquest servidor intermediari per a tots els monitors?",
"setAsDefaultProxyDescription": "Aquest servidor intermediari s'habilitar├а de manera predeterminada per als monitors nous. Encara podeu desactivar el servidor intermediari per separat per a cada monitor.",
"Certificate Chain": "Cadena de certificats",
"Valid": "V├аlid",
"Invalid": "Inv├аlid",
"User": "Usuari",
"Installed": "Instal┬╖lat",
"Not installed": "No instal┬╖lat",
"Running": "En execuci├│",
"Not running": "No en execuci├│",
"Remove Token": "Elimina el testimoni",
"Start": "Inicia",
"Stop": "Aturar",
"Add New Status Page": "Afegeix una p├аgina d'estat nova",
"Slug": "├Аlies",
"Accept characters:": "Accepta car├аcters:",
"startOrEndWithOnly": "Inicia o acaba nom├йs amb {0}",
"No consecutive dashes": "Sense guions consecutius",
"Next": "Seg├╝ent",
"The slug is already taken. Please choose another slug.": "L'├аlias ja est├а agafat. Si us plau, escolliu un altre ├аlies.",
"No Proxy": "Sense servidor intermediari",
"Proxies": "Servidors intermediaris",
"HTTP Basic Auth": "Autenticaci├│ b├аsica HTTP",
"New Status Page": "P├аgina d'estat nova",
"Reverse Proxy": "Servidor intermediari invertit",
"Backup": "C├▓pia de seguretat",
"About": "Quant a",
"wayToGetCloudflaredURL": "(Descarrega de cloudfared des de {0})",
"cloudflareWebsite": "Lloc web de Cloudflare",
"Message:": "Missatge:",
"HTTP Headers": "Cap├зaleres HTTP",
"Trust Proxy": "Confia en el servidor intermediari",
"Other Software": "Un altre programari",
"For example: nginx, Apache and Traefik.": "Per exemple: nginx, Apache i Traefik.",
"Please read": "Llegiu",
"Subject:": "Assumpte:",
"Valid To:": "V├аlid per a:",
"Days Remaining:": "Dies restants:",
"Issuer:": "Emissor:",
"Fingerprint:": "Empremta digital:",
"No status pages": "Sense p├аgines d'estat",
"Domain Name Expiry Notification": "Notificaci├│ de venciment del nom de domini",
"Add a new expiry notification day": "Notificaci├│ de venciment del nom de domini",
"Remove the expiry notification": "Elimina el dia de notificaci├│ de venciment",
"Proxy": "Servidor intermediari",
"Date Created": "Data de creaci├│",
"Footer Text": "Text del peu de p├аgina",
"Refresh Interval Description": "La p├аgina d'estat far├а una actualitzaci├│ completa del lloc cada {0} segons",
"Show Powered By": "Mostra Impulsat per",
"Domain Names": "Noms de domini",
"signedInDisp": "Sessi├│ iniciada com a {0}",
"RadiusSecret": "Secret de Radius",
"RadiusSecretDescription": "Secret compartit entre client i servidor",
"RadiusCalledStationId": "Id de l'estaci├│ cridada",
"RadiusCallingStationId": "Id de l'estaci├│ de trucada",
"RadiusCallingStationIdDescription": "Identificador del dispositiu de crida",
"Certificate Expiry Notification": "Notificaci├│ de venciment del certificat",
"API Username": "Nom d'usuari API",
"API Key": "Clau API",
"Show update if available": "Mostra l'actualitzaci├│ si est├а disponible",
"Using a Reverse Proxy?": "Usar un servidor intermediari invers?",
"Check how to config it for WebSocket": "Comprova com configurar-lo per a WebSocket",
"Steam Game Server": "Servidor de jocs Steam",
"Most likely causes:": "Causes m├йs probables:",
"There might be a typing error in the address.": "Pot haver-hi un error d'escriptura a l'adre├зa.",
"What you can try:": "Qu├и podeu provar:",
"Retype the address.": "Torneu a teclejar l'adre├зa.",
"Go back to the previous page.": "Torna a la p├аgina anterior.",
"Coming Soon": "Properament",
"Connection String": "Cadena de connexi├│",
"Query": "Consulta",
"settingsCertificateExpiry": "Caducitat del certificat TLS",
"Setup Docker Host": "Configura l'amfitri├│ Docker",
"Connection Type": "Tipus de connexi├│",
"Docker Daemon": "Dimoni Docker",
"noDockerHostMsg": "No disponible. Primer configureu un amfitri├│ Docker.",
"DockerHostRequired": "Establiu l'amfitri├│ Docker per a aquest monitor.",
"socket": "S├▓col",
"tcp": "TCP / HTTP",
"Docker Container": "Contenidor Docker",
"Container Name / ID": "Nom del contenidor / ID",
"Docker Host": "Amfitri├│ Docker",
"Docker Hosts": "Amfitrions Docker",
"Domain": "Domini",
"Workstation": "Estaci├│ de treball",
"Packet Size": "Mida del paquet",
"Bot Token": "Testimoni de bot",
"wayToGetTelegramToken": "Podeu obtenir un testimoni de {0}.",
"Chat ID": "ID de xat",
"telegramMessageThreadID": "(Opcional) ID del fil del missatge",
"telegramMessageThreadIDDescription": "Identificador ├║nic opcional per al fil del missatge de destinaci├│ (tema) del f├▓rum; nom├йs per als supergrups del f├▓rum",
"telegramSendSilently": "Envia silenciosament",
"telegramProtectContent": "Protegeix la reenviament/desament",
"supportTelegramChatID": "Admet xat directe / grup / ID de xat del canal",
"YOUR BOT TOKEN HERE": "EL VOSTRE TESTIMONI DE BOT AQU├Н",
"chatIDNotFound": "No s'ha trobat l'ID del xat; primer envieu un missatge a aquest bot",
"disableCloudflaredNoAuthMsg": "Esteu en mode No Auth, no cal una contrasenya.",
"wayToGetLineNotifyToken": "Podeu obtenir un testimoni d'acc├йs des de {0}",
"Examples": "Exemples",
"Home Assistant URL": "URL de l'assistent d'inici",
"Long-Lived Access Token": "Testimoni d'acc├йs viu",
"Notification Service": "Servei de notificacions",
"Automations can optionally be triggered in Home Assistant:": "Les automatitzacions es poden activar opcionalment a l'assistent d'inici:",
"Trigger type:": "Tipus d'activador:",
"Event type:": "Tipus d'esdeveniment:",
"Event data:": "Dades de l'esdeveniment:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "A continuaci├│, trieu una acci├│, per exemple, canvieu l'escena a on una llum RGB ├йs vermella.",
"Frontend Version": "Versi├│ del frontal",
"Frontend Version do not match backend version!": "La versi├│ frontal no coincideix amb la versi├│ del dorsal!",
"backupRecommend": "Si us plau, feu una c├▓pia de seguretat del volum o de la carpeta de dades (./data/) directament.",
"Optional": "Opcional",
"and": "i",
"startDateTime": "Data/hora d'inici",
"endDateTime": "Data/hora final",
"cronExpression": "Expressi├│ Cron",
"cronSchedule": "Planificaci├│: ",
"invalidCronExpression": "Expressi├│ Cron no v├аlida: {0}",
"recurringInterval": "Interval",
"Recurring": "Recurr├иncia",
"strategyManual": "Activa/Inactiva manualment",
"warningTimezone": "Est├а utilitzant la zona hor├аria del servidor",
"weekdayShortMon": "Dill",
"weekdayShortTue": "Dim",
"weekdayShortWed": "Dim",
"weekdayShortThu": "Dij",
"weekdayShortFri": "Div",
"weekdayShortSat": "Diss",
"weekdayShortSun": "Dg",
"dayOfWeek": "Dia de la setmana",
"dayOfMonth": "Dia del mes",
"lastDay": "├Ъltim dia",
"lastDay2": "2n ├║ltim dia del mes",
"lastDay3": "3r Darrer Dia del Mes",
"lastDay4": "4t Darrer Dia del Mes",
"No Maintenance": "Sense manteniment",
"maintenanceStatus-under-maintenance": "Sota manteniment",
"maintenanceStatus-inactive": "Inactiu",
"maintenanceStatus-scheduled": "Programat",
"maintenanceStatus-unknown": "Desconegut",
"Server Timezone": "Zona hor├аria del servidor",
"statusPageMaintenanceEndDate": "Final",
"IconUrl": "URL de la icona",
"Enable DNS Cache": "(Obsolet) Habilita la mem├▓ria cau DNS per als monitors HTTP(s)",
"Enable": "Habilita",
"Disable": "Desactiva",
"chromeExecutable": "Executable Chrome/Chromium",
"chromeExecutableAutoDetect": "Detecci├│ autom├аtica",
"dnsCacheDescription": "Pot ser que no funcioni treballant amb entorns IPv6, desactiva'l si detectes qualsevol problema.",
"Single Maintenance Window": "Finestra de Manteniment ├║nic",
"Maintenance Time Window of a Day": "Finestra de Temps del manteniment d'un Dia",
"Effective Date Range": "Rang de data efica├з (Opcional)",
"Schedule Maintenance": "Programa de manteniment",
"Edit Maintenance": "Edita el manteniment",
"Date and Time": "Data i hora",
"DateTime Range": "Rang de data i temps",
"loadingError": "Impossible obtenir la data, si us plau prova-ho m├йs endavant.",
"plugin": "Connector | Connectors",
"install": "Instal┬╖la",
"installing": "Instal┬╖lant",
"uninstall": "Desinstal┬╖la",
"confirmUninstallPlugin": "Est├аs segur de desinstal┬╖lar aquest connector?",
"notificationRegional": "Regional",
"Clone Monitor": "Clona el monitor",
"Clone": "Clona",
"cloneOf": "Clon de {0}",
"secureOptionNone": "Cap / STARTTLS (25, 587)",
"secureOptionTLS": "TLS (465)",
"Ignore TLS Error": "Ignora error TLS",
"From Email": "Des de Correu",
"emailCustomisableContent": "Contingut personalitzable",
"emailCustomSubject": "Tema personalitzable",
"leave blank for default subject": "deixar en blanc per tema per defecte",
"emailCustomBody": "Cos personalitzat",
"leave blank for default body": "deixa en blanc per un cos per defecte",
"emailTemplateServiceName": "Nom de servei",
"emailTemplateHostnameOrURL": "Nom de host o URL",
"emailTemplateStatus": "Estat",
"emailTemplateMonitorJSON": "objecte que descriu el monitor",
"emailTemplateHeartbeatJSON": "objecte que descriu el batec del cor",
"To Email": "Dest├н email",
"smtpCC": "CC",
"smtpBCC": "BCC",
"Discord Webhook URL": "Discord Webhook URL",
"wayToGetDiscordURL": "Pots rebre aquest per anar a Par├аmetres de Servidor -> Integracions -> Vista *Webhooks -> Nou *Webhook",
"Bot Display Name": "Nom de pantalla de bot",
"Prefix Custom Message": "Prefix de missatge personalitzat",
"Hello @everyone is...": "Hola {'@'} a tothom тАж",
"Send to channel": "Envia al canal",
"Create new forum post": "Crea una nova publicaci├│",
"postToExistingThread": "Publica a un fil existent",
"forumPostName": "Nom de publicaci├│ de f├▓rum",
"threadForumPostID": "Fil / identificador de f├▓rum",
"e.g. {discordThreadID}": "exemple {discordThreadID}",
"wayToGetTeamsURL": "Pot aprendre com crear una URL de webhook {0}.",
"wayToGetZohoCliqURL": "Pot aprendre com crear una URL de webhook {0}.",
"needSignalAPI": "Necessites tenir una senyal de client amb REST API.",
"wayToCheckSignalURL": "Pot comprovar aquesta URL per veure com configurar:",
"Number": "N├║mero",
"Recipients": "Receptors",
"Access Token": "Fitxa d'acc├йs",
"Channel access token (Long-lived)": "Fitxa d'acc├йs del canal (de llarga vida)",
"Line Developers Console": "Consola de Desenvolupadors de la l├нnia",
"appriseNotInstalled": "L'ap├иndix no est├а instal┬╖lat. {0}",
"Method": "M├иtode",
"clearDataOlderThan": "Conserva les dades de l'historial del monitor durant {0} dies.",
"steamApiKeyDescription": "Per a monitoritzar un servidor de jocs de vapor, necessiteu una clau Steam Web-API. Podeu registrar la vostra clau API aqu├н: ",
"shrinkDatabaseDescriptionSqlite": "Activa la base de dades {vacuum} per a SQLite. {auto.vacuum} ja est├а activat, per├▓ aix├▓ no desfragmenta la base de dades ni reempaqueta les p├аgines individuals de la base de dades de la manera com ho fa l'ordre {vacuum}.",
"liquidIntroduction": "S'aconsegueix la flexibilitat mitjan├зant el llenguatge de templataci├│ l├нquid. Consulteu el {0} per a les instruccions d'├║s. Aquestes s├│n les variables disponibles:",
"selectedMonitorCount": "Seleccionat: {0}",
"deleteStatusPageMsg": "Esteu segur que voleu suprimir aquesta p├аgina d'estat?",
"proxyDescription": "Els intermediaris s'han d'assignar a un monitor perqu├и funcioni.",
"enableProxyDescription": "Aquest servidor intermediari no afectar├а les sol┬╖licituds del monitor fins que estigui activat. Podeu controlar temporalment desactivar el servidor intermediari de tots els monitors per l'estat d'activaci├│.",
"statusPageSpecialSlugDesc": "├Аlies especial {0}: aquesta p├аgina es mostrar├а quan no es proporcioni l'├аlies",
"Authentication": "Autenticaci├│",
"Page Not Found": "P├аgina no trobada",
"Don't know how to get the token? Please read the guide:": "No saps com aconseguir el testimoni? Si us plau, llegiu la guia:",
"The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.": "La connexi├│ actual es pot perdre si esteu connectant a trav├йs del t├║nel Cloudflare. Segur que voleu aturar-ho? Escriviu la contrasenya actual per confirmar-la.",
"Refresh Interval": "Interval de refresc",
"signedInDispDisabled": "Autenticaci├│ desactivada.",
"RadiusCalledStationIdDescription": "Identificador del dispositiu anomenat",
"Also check beta release": "Comprova tamb├й la versi├│ beta",
"The resource is no longer available.": "El recurs ja no est├а disponible.",
"certificationExpiryDescription": "Els monitors HTTPS activen la notificaci├│ quan el certificat TLS caduca a:",
"deleteDockerHostMsg": "Esteu segur que voleu suprimir aquest amfitri├│ de l'acoblador per a tots els monitors?",
"tailscalePingWarning": "Per utilitzar el monitor de Ping Tailscale, heu d'instal┬╖lar el Kuma Uptime sense Docker i tamb├й instal┬╖lar el client Tailscale al vostre servidor.",
"telegramSendSilentlyDescription": "Envia el missatge en silenci. Els usuaris rebran una notificaci├│ sense so.",
"telegramProtectContentDescription": "Si est├а activat, els missatges del bot del Telegram estaran protegits contra reenviaments i desaments.",
"wayToGetTelegramChatID": "Podeu obtenir el vostre ID de xat enviant un missatge al bot i anant a aquest URL per veure el xat id:",
"trustProxyDescription": "Confia en les cap├зaleres ┬лX-Forwarded-*┬╗. Si voleu obtenir la IP del client correcta i el vostre Kuma Uptime est├а darrere d'un servidor intermediari com Nginx o Apache, haur├нeu d'activar-ho.",
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Es pot crear un testimoni d'acc├йs de llarga durada fent clic al nom del vostre perfil (a baix a l'esquerra) i despla├зant-vos a la part inferior i despr├йs feu clic a Crea un testimoni. ",
"default: notify all devices": "per defecte: notifica tots els dispositius",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Podeu trobar una llista dels Serveis de Notificaci├│ a l'assistent d'inici a ┬лEines de revelador . Serveis┬╗ cerca ┬лnotificaci├│┬╗ per trobar el nom del vostre dispositiu/tel├иfon.",
"backupOutdatedWarning": "Obsolet: At├иs que s'han afegit moltes caracter├нstiques i aquesta funci├│ de c├▓pia de seguretat ├йs una mica inexistent, no pot generar o restaurar una c├▓pia de seguretat completa.",
"lastDay1": "L'├║ltim dia del mes",
"pauseMaintenanceMsg": "Segur que voleu fer una pausa?",
"maintenanceStatus-ended": "Finalitzat",
"Display Timezone": "Mostra la zona hor├аria",
"enableNSCD": "Habilita NSCD (Dimoni de mem├▓ria cau de Servei del Nom ) per accelerar les sol┬╖licituds de DNS",
"chromeExecutableDescription": "Per a usuaris de Docker, si el Chrome no est├а encara instal┬╖lat, pot dur uns quants minuts per instal┬╖lar i mostrar el resultat de prova. Duu 1*GB d'espai de disc.",
"uninstalling": "Desinstal┬╖lant",
"smtp": "Correu electr├▓nic (SMTP)",
"smtpLiquidIntroduction": "Els seg├╝ents dos camps s├│n personalitzables via \"Liquid templating Language\". Per favor refereix al {0} per a instruccions d'├║s. Aquests s├│n les variables disponibles:",
"emailTemplateMsg": "missatge de la notificaci├│",
"emailTemplateLimitedToUpDownNotification": "nom├йs disponible per estats UP/Down, altrament null",
"Select message type": "Selecciona el tipus de missatge",
"whatHappensAtForumPost": "Crea una nova publicaci├│ de f├▓rum. Aix├▓ no publica un missatge a un f├▓rum existent. Per publicar un fil existent utilitza \"{option}\"",
"Channel access token": "Fitxa d'acc├йs del canal",
"Body": "Cos",
"or": "o",
"PushUrl": "URL de captura",
"HeadersInvalidFormat": "Les cap├зaleres de sol┬╖licitud no s├│n JSON v├аlides: ",
"BodyInvalidFormat": "El cos de petici├│ no ├йs JSON v├аlid: ",
"Security": "Seguretat",
"Pick Accepted Status Codes...": "Trieu els codis d'estat acceptatsтАж",
"error": "error",
"critical": "cr├нtica",
"Please input title and content": "Introdu├пu el t├нtol i el contingut",
"telegramServerUrl": "(Opcional) Url del servidor",
"telegramServerUrlDescription": "Per saltar-se les limitacions del bot de Telegram o tenir acc├йs a regions bloquejades (China, Iran, etc). Per a m├йs informaci├│ fes click {0}. Per defecte {1}",
"templateServiceName": "Nom del servei",
"templateHostnameOrURL": "Adre├зa URL o nom del host",
"templateStatus": "Estat",
"telegramUseTemplate": "Fes servir una plantilla de missatge personalitzada",
"telegramUseTemplateDescription": "Si s'activa, el missatge s'enviar├а fent servir una plantilla personalitzada.",
"telegramTemplateFormatDescription": "Telegram permet l'├║s de diferents tipus de llenguatges de marcat, llegeix Telegram {0} per m├йs detalls."
} }

View File

@@ -802,8 +802,8 @@
"Json Query": "Json dotaz", "Json Query": "Json dotaz",
"Badge Duration (in hours)": "Zobrazen├н odznaku (v hodin├бch)", "Badge Duration (in hours)": "Zobrazen├н odznaku (v hodin├бch)",
"Badge Preview": "N├бhled odznaku", "Badge Preview": "N├бhled odznaku",
"Notify Channel": "Upozornit kan├бl", "Notify Channel": "Kan├бl nofitikac├н",
"aboutNotifyChannel": "Upozorn─Ыn├н na kan├бl spust├н upozorn─Ыn├н na po─Н├нta─Нi nebo v mobiln├нm telefonu pro v┼бechny ─Нleny kan├бlu, a┼е u┼╛ je jejich dostupnost nastavena na aktivn├н nebo na nep┼Щ├нtomnost.", "aboutNotifyChannel": "Upozorn─Ыn├н kan├бlu spust├н upozorn─Ыn├н na po─Н├нta─Нi nebo v mobilu pro v┼бechny ─Нleny kan├бlu, a┼е u┼╛ jsou dostupn├н nebo ne.",
"filterActive": "Aktivn├н", "filterActive": "Aktivn├н",
"filterActivePaused": "Pozastaveno", "filterActivePaused": "Pozastaveno",
"Enter the list of brokers": "Vytvo┼Щte seznam zprost┼Щedkovatel┼п", "Enter the list of brokers": "Vytvo┼Щte seznam zprost┼Щedkovatel┼п",
@@ -1051,45 +1051,5 @@
"Client ID": "ID klienta", "Client ID": "ID klienta",
"Client Secret": "Tajemstv├н klienta", "Client Secret": "Tajemstv├н klienta",
"OAuth Scope": "OAuth rozsah", "OAuth Scope": "OAuth rozsah",
"Optional: Space separated list of scopes": "Voliteln├й: seznam rozsah┼п odd─Ыlte mezerami", "Optional: Space separated list of scopes": "Voliteln├й: seznam rozsah┼п odd─Ыlte mezerami"
"Debug": "Lad─Ыn├н",
"CopyToClipboardError": "Nelze zkop├нrovat do schr├бnky: {error}",
"ignoredTLSError": "Chyby TLS/SSL byly ignorov├бny",
"Copy": "Kop├нrovat",
"aboutSlackUsername": "M─Ыn├н zobrazovan├й jm├йno odes├нlatele zpr├бvy. Pokud n─Ыkoho chcete zm├нnit, pou┼╛ijte rad─Ыji pole obecn├╜ n├бzev.",
"Message format": "Form├бt zpr├бvy",
"Notification Channel": "Kan├бl notifikac├н",
"Alphanumerical string and hyphens only": "Pouze alfanumerick├й ┼Щet─Ыzce a poml─Нky",
"Sound": "Zvuk",
"Custom sound to override default notification sound": "Pou┼╛├нt vlastn├н zvuk m├нsto v├╜choz├нho zvuku upozorn─Ыn├н",
"Correct": "Spr├бvn─Ы",
"Fail": "Chyba",
"Reveal": "Odhalen├н",
"Doorbell": "Zvonek",
"Flute": "Fl├йtna",
"Money": "Pen├нze",
"Elevator": "V├╜tah",
"Guitar": "Kytara",
"Time Sensitive (iOS Only)": "─Мasov─Ы kritick├й (pouze pro iOS)",
"Time sensitive notifications will be delivered immediately, even if the device is in do not disturb mode.": "─Мasov─Ы kritick├б upozorn─Ыn├н budou doru─Нena okam┼╛it─Ы, i kdy┼╛ je za┼Щ├нzen├н v re┼╛imu neru┼бit.",
"From": "Od",
"Can be found on:": "Lze nal├йzt na: {0}",
"The phone number of the recipient in E.164 format.": "Telefonn├н ─Н├нslo p┼Щ├нjemce ve form├бtu E.164 (+420...).",
"RabbitMQ Nodes": "RabbitMQ uzly pro spr├бvu",
"rabbitmqNodesDescription": "URL RabbitMQ uzl┼п pro spr├бvu zad├бvejte v─Нetn─Ы protokolu a portu. P┼Щ├нklad: {0}",
"rabbitmqNodesRequired": "Pros├нm, definujte uzly pro tento dohled.",
"rabbitmqNodesInvalid": "Pros├нm, pou┼╛ijte pln─Ы kvalifikovan├й URL (za─Н├нnaj├нc├н na 'http)' RabbitMQ uzl┼п.",
"RabbitMQ Username": "RabbitMQ u┼╛ivatelsk├й jm├йno",
"Send rich messages": "Poslat rozs├бhl├й zpr├бvy",
"Arcade": "Ark├бda",
"Harp": "Harfa",
"Bubble": "Bublinky",
"Scifi": "Scifi",
"Pop": "Prasknut├н",
"Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "Pro zaji┼бt─Ыn├н p┼Щ├нjmu odpov─Ыd├н zadejte ID odes├нlatele textu nebo telefonn├н ─Н├нslo ve form├бtu E.164.",
"RabbitMQ Password": "RabbitMQ heslo",
"rabbitmqHelpText": "Abyste mohli pou┼╛├нvat tento monitor, mus├нte v nastaven├н RabbitMQ povolit modul pro spr├бvu. Dal┼б├н informace naleznete na adrese {rabitmq_documentation}.",
"SendGrid API Key": "SendGrid API kl├н─Н",
"Separate multiple email addresses with commas": "V├нce e-mailov├╜ch adres odd─Ыlte ─Н├бrkami",
"Clear": "Odstran─Ыn├н"
} }

View File

@@ -45,7 +45,7 @@
"Port": "Port", "Port": "Port",
"Heartbeat Interval": "Hjerteslag interval", "Heartbeat Interval": "Hjerteslag interval",
"Retries": "Gentagelser", "Retries": "Gentagelser",
"retriesDescription": "Maksimalt antal gentagelser, f├╕r tjenesten markeres som inaktiv og sender en meddelelse", "retriesDescription": "Maksimalt antal gentagelser, f├╕r tjenesten markeres som inaktiv og sender en meddelelse.",
"Advanced": "Avanceret", "Advanced": "Avanceret",
"ignoreTLSError": "Ignor├йr TLS/SSL fejl for HTTPS websteder", "ignoreTLSError": "Ignor├йr TLS/SSL fejl for HTTPS websteder",
"Upside Down Mode": "Omvendt tilstand", "Upside Down Mode": "Omvendt tilstand",
@@ -99,7 +99,7 @@
"deleteNotificationMsg": "Er du sikker p├е, at du vil slette denne underretning for alle overv├еgere?", "deleteNotificationMsg": "Er du sikker p├е, at du vil slette denne underretning for alle overv├еgere?",
"resolverserverDescription": "Cloudflare er standardserveren, den kan til enhver tid ├жndres.", "resolverserverDescription": "Cloudflare er standardserveren, den kan til enhver tid ├жndres.",
"Resolver Server": "Navne-server", "Resolver Server": "Navne-server",
"rrtypeDescription": "V├жlg den type RR, du vil overv├еge", "rrtypeDescription": "V├жlg den type RR, du vil overv├еge.",
"Last Result": "Seneste resultat", "Last Result": "Seneste resultat",
"pauseMonitorMsg": "Er du sikker p├е at du vil standse overv├еgningen?", "pauseMonitorMsg": "Er du sikker p├е at du vil standse overv├еgningen?",
"Create your admin account": "Opret din administratorkonto", "Create your admin account": "Opret din administratorkonto",
@@ -125,7 +125,7 @@
"backupDescription3": "F├╕lsom data, f.eks. underretnings-tokener, er inkluderet i eksportfilen. Gem den sikkert.", "backupDescription3": "F├╕lsom data, f.eks. underretnings-tokener, er inkluderet i eksportfilen. Gem den sikkert.",
"alertNoFile": "V├жlg en fil der skal importeres.", "alertNoFile": "V├жlg en fil der skal importeres.",
"alertWrongFileType": "V├жlg venligst en JSON-fil.", "alertWrongFileType": "V├жlg venligst en JSON-fil.",
"twoFAVerifyLabel": "Indtast venligst dit token for at bekr├жfte, at 2FA fungerer:", "twoFAVerifyLabel": "Indtast venligst dit token for at bekr├жfte, at 2FA fungerer",
"tokenValidSettingsMsg": "Token er gyldigt! Du kan nu gemme 2FA -indstillingerne.", "tokenValidSettingsMsg": "Token er gyldigt! Du kan nu gemme 2FA -indstillingerne.",
"confirmEnableTwoFAMsg": "Er du sikker p├е at du vil aktivere 2FA?", "confirmEnableTwoFAMsg": "Er du sikker p├е at du vil aktivere 2FA?",
"confirmDisableTwoFAMsg": "Er du sikker p├е at du vil deaktivere 2FA?", "confirmDisableTwoFAMsg": "Er du sikker p├е at du vil deaktivere 2FA?",
@@ -141,7 +141,7 @@
"Token": "Token", "Token": "Token",
"Show URI": "Vis URI", "Show URI": "Vis URI",
"Clear all statistics": "Ryd alle Statistikker", "Clear all statistics": "Ryd alle Statistikker",
"retryCheckEverySecond": "Pr├╕v igen hvert {0} sekund", "retryCheckEverySecond": "Pr├╕v igen hvert {0} sekund.",
"importHandleDescription": "V├жlg 'Spring over eksisterende', hvis du vil springe over hver overv├еger eller underretning med samme navn. 'Overskriv' sletter alle eksisterende overv├еgere og underretninger.", "importHandleDescription": "V├жlg 'Spring over eksisterende', hvis du vil springe over hver overv├еger eller underretning med samme navn. 'Overskriv' sletter alle eksisterende overv├еgere og underretninger.",
"confirmImportMsg": "Er du sikker p├е at importere sikkerhedskopien? S├╕rg for, at du har valgt den rigtige importindstilling.", "confirmImportMsg": "Er du sikker p├е at importere sikkerhedskopien? S├╕rg for, at du har valgt den rigtige importindstilling.",
"Heartbeat Retry Interval": "Hjerteslag gentagelsesinterval", "Heartbeat Retry Interval": "Hjerteslag gentagelsesinterval",
@@ -277,7 +277,7 @@
"lineDevConsoleTo": "Line Udviklerkonsol - {0}", "lineDevConsoleTo": "Line Udviklerkonsol - {0}",
"Basic Settings": "Basisindstillinger", "Basic Settings": "Basisindstillinger",
"User ID": "Bruger-ID", "User ID": "Bruger-ID",
"Messaging API": "Besked API", "Messaging API": "Messaging API",
"wayToGetLineChannelToken": "Tilg├е f├╕rst {0}, opret en udbyder og kanal (Messaging API), s├е kan du f├е kanaladgangstoken'et og bruger-ID'et fra de ovenn├жvnte menupunkter.", "wayToGetLineChannelToken": "Tilg├е f├╕rst {0}, opret en udbyder og kanal (Messaging API), s├е kan du f├е kanaladgangstoken'et og bruger-ID'et fra de ovenn├жvnte menupunkter.",
"Icon URL": "Ikon URL", "Icon URL": "Ikon URL",
"aboutIconURL": "Du kan angive et link til et billede i \"Ikon URL\" for at tilsides├жtte standardprofilbilledet. Vil ikke blive brugt, hvis Ikon Emoji er angivet.", "aboutIconURL": "Du kan angive et link til et billede i \"Ikon URL\" for at tilsides├жtte standardprofilbilledet. Vil ikke blive brugt, hvis Ikon Emoji er angivet.",
@@ -415,7 +415,7 @@
"signedInDisp": "Logget ind som {0}", "signedInDisp": "Logget ind som {0}",
"Certificate Expiry Notification": "Meddelelse om udl├╕bsdato for certifikatet", "Certificate Expiry Notification": "Meddelelse om udl├╕bsdato for certifikatet",
"API Username": "API Brugernavn", "API Username": "API Brugernavn",
"API Key": "API N├╕gle", "API Key": "API Key",
"Steam Game Server": "Steam Game Server", "Steam Game Server": "Steam Game Server",
"What you can try:": "Hvad du kan pr├╕ve:", "What you can try:": "Hvad du kan pr├╕ve:",
"Go back to the previous page.": "G├е tilbage til forrige side.", "Go back to the previous page.": "G├е tilbage til forrige side.",
@@ -621,11 +621,11 @@
"confirmDeleteTagMsg": "Er du sikker p├е at du vil slette denne etiket? Overv├еgninger med denne etiket vil ikke blive slettet.", "confirmDeleteTagMsg": "Er du sikker p├е at du vil slette denne etiket? Overv├еgninger med denne etiket vil ikke blive slettet.",
"resendEveryXTimes": "Gensend hver {0} gang", "resendEveryXTimes": "Gensend hver {0} gang",
"resendDisabled": "Gensendelse deaktiveret", "resendDisabled": "Gensendelse deaktiveret",
"Reconnecting...": "Genopretter forbindelse...", "Reconnecting...": "Genforbinder...",
"successPaused": "Standset med succes.", "successPaused": "Standset med succes.",
"Reset Token": "Nulstil n├╕gle", "Reset Token": "Nulstil n├╕gle",
"Show Clickable Link": "Vis klikbart link", "Show Clickable Link": "Vis klikbart link",
"atLeastOneMonitor": "V├жlg mindst ├йn ber├╕rt overv├еgning", "atLeastOneMonitor": "V├жlg mindst ├йn ber├╕rt overv├еgning.",
"authInvalidToken": "Ugyldig n├╕gle.", "authInvalidToken": "Ugyldig n├╕gle.",
"authIncorrectCreds": "Brugernavn eller adgangskode er ikke korrekt.", "authIncorrectCreds": "Brugernavn eller adgangskode er ikke korrekt.",
"2faAlreadyEnabled": "2FA er allerede aktiveret.", "2faAlreadyEnabled": "2FA er allerede aktiveret.",
@@ -656,147 +656,5 @@
"telegramSendSilentlyDescription": "Send beskeden lydl├╕st. Brugerne vil modtage en notifikation uden lyd.", "telegramSendSilentlyDescription": "Send beskeden lydl├╕st. Brugerne vil modtage en notifikation uden lyd.",
"pushoverMessageTtl": "Message TTL (Sekunder)", "pushoverMessageTtl": "Message TTL (Sekunder)",
"setupDatabaseEmbeddedMariaDB": "Du skal ikke ops├жtte noget. Docker billedet har integreret og konfigureret MariaDB automatisk. Uptime Kuma vil forbinde til databasen vha. en Unix socket.", "setupDatabaseEmbeddedMariaDB": "Du skal ikke ops├жtte noget. Docker billedet har integreret og konfigureret MariaDB automatisk. Uptime Kuma vil forbinde til databasen vha. en Unix socket.",
"setupDatabaseMariaDB": "Oprette forbindelse til en ekstern MariaDB database. Du skal indstille databasens forbindelsesinformation.", "setupDatabaseMariaDB": "Oprette forbindelse til en ekstern MariaDB database. Du skal indstille databasens forbindelsesinformation."
"styleElapsedTimeShowWithLine": "Vis (med linjer)",
"styleElapsedTime": "Forl├╕bet tid under heartbeat-bj├жlken",
"templateMsg": "besked fra notifikationen",
"templateHeartbeatJSON": "objekt, der beskriver heartbeat",
"templateMonitorJSON": "objekt, der beskriver monitoren",
"templateLimitedToUpDownNotifications": "kun tilg├жngelig for UP/DOWN notifikationer",
"webhookAdditionalHeadersTitle": "Yderligere Headers",
"webhookAdditionalHeadersDesc": "Angiver yderligere headers, der sendes med webhooken. Hver header skal defineres som en JSON-n├╕gle/v├жrdi.",
"webhookBodyCustomOption": "Brugerdefineret Body",
"successKeyword": "Succesn├╕gleord",
"startOrEndWithOnly": "Kun start eller slut med {0}",
"setAsDefaultProxyDescription": "Denne proxy vil som standard v├жre aktiveret for nye monitorer. Du kan stadig deaktivere proxyen individuelt for hver monitor.",
"No consecutive dashes": "Ingen p├е hinanden f├╕lgende bindestreger",
"statusPageSpecialSlugDesc": "Speciel slug {0}: Denne side vises, n├еr der ikke angives en slug",
"Query": "K├╕",
"Add a new expiry notification day": "Tilf├╕j en ny udl├╕bsnotifikationsdag",
"Remove the expiry notification": "Fjern udl├╕bsnotifikationsdagen",
"Refresh Interval": "Opdateringsinterval",
"Refresh Interval Description": "Statussiden vil udf├╕re en fuld opdatering af sitet hvert {0} sekunder",
"RadiusSecret": "Radius-hemmelighed",
"RadiusCalledStationId": "Called Station ID",
"RadiusCalledStationIdDescription": "Identifikator for den kaldte enhed",
"RadiusCallingStationId": "Calling Station Id",
"RadiusCallingStationIdDescription": "Identifikator for den kaldende enhed",
"Check how to config it for WebSocket": "Tjek, hvordan det konfigureres til WebSocket",
"Connection String": "Forbindelsesstreng",
"Workstation": "Arbejdsstation",
"telegramMessageThreadID": "(Valgfrit) Beskedtr├еd-ID",
"telegramMessageThreadIDDescription": "Valgfri unik identifikator for m├еlbeskedtr├еden (emnet) i forummet; kun for forum-supergrupper",
"telegramProtectContent": "Beskyt videresendelse/gemning",
"telegramProtectContentDescription": "Hvis aktiveret, vil bot-beskeder i Telegram v├жre beskyttet mod videresendelse og gemning.",
"disableCloudflaredNoAuthMsg": "Du er i No Auth-tilstand, en adgangskode er ikke p├еkr├жvet.",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "En liste over notifikationstjenester kan findes i Home Assistant under тАЬDeveloper Tools > ServicesтАЭ. S├╕g efter тАЬnotificationтАЭ for at finde navnet p├е din enhed/telefon.",
"Then choose an action, for example switch the scene to where an RGB light is red.": "V├жlg derefter en handling, for eksempel at skifte scenen til en, hvor et RGB-lys er r├╕dt.",
"backupRecommend": "Sikkerhedskopier venligst volumen eller data-mappen (./data/) direkte i stedet.",
"and": "og",
"startDateTime": "Startdato/-tidspunkt",
"endDateTime": "Slutdato/-tidspunkt",
"cronExpression": "Cron-udtryk",
"cronSchedule": "Tidsplan: ",
"warningTimezone": "Den bruger serverens tidszone",
"enableNSCD": "Aktiv├йr NSCD (Name Service Cache Daemon) for at cache alle DNS-foresp├╕rgsler",
"chromeExecutable": "Chrome/Chromium-eksekverbar fil",
"Single Maintenance Window": "Enkelt vedligeholdelsesvindue",
"Edit Maintenance": "Rediger vedligeholdelse",
"emailCustomisableContent": "Brugerdefinerbart indhold",
"leave blank for default subject": "lad st├е tomt for standardemne",
"emailCustomBody": "Brugerdefineret body",
"leave blank for default body": "lad st├е tomt for standard-body",
"emailTemplateServiceName": "Servicenavn",
"emailTemplateHostnameOrURL": "V├жrtsnavn eller URL",
"emailTemplateStatus": "Status",
"emailTemplateMonitorJSON": "objekt, der beskriver monitoren",
"emailTemplateHeartbeatJSON": "objekt, der beskriver heartbeat",
"emailTemplateMsg": "besked fra notifikationen",
"emailTemplateLimitedToUpDownNotification": "kun tilg├жngelig for UP/DOWN heartbeats, ellers null",
"Select message type": "V├жlg beskedtype",
"Send to channel": "Send til kanal",
"Create new forum post": "Opret nyt forumpost",
"postToExistingThread": "Send til eksisterende tr├еd / forumpost",
"forumPostName": "Forumpost-navn",
"threadForumPostID": "Tr├еd- / Forumpost-ID",
"e.g. {discordThreadID}": "f.eks. {discordThreadID}",
"wayToGetDiscordThreadId": "At hente en tr├еd- / forumpost-ID ligner processen for at hente en kanal-ID. L├жs mere om, hvordan du f├еr IDs {0}",
"Channel access token (Long-lived)": "Kanaladgangstoken (langvarig)",
"Your User ID": "Din bruger-ID",
"dataRetentionTimeError": "Opbevaringsperioden skal v├жre 0 eller h├╕jere",
"infiniteRetention": "S├жt til 0 for uendelig opbevaring.",
"enableGRPCTls": "Tillad afsendelse af gRPC-foresp├╕rgsel med TLS-forbindelse",
"affectedStatusPages": "Vis denne vedligeholdelsesbesked p├е udvalgte statussider",
"invertKeywordDescription": "Se efter, at n├╕gleordet mangler i stedet for at v├жre til stede.",
"octopushAPIKey": "тАЬAPI-n├╕gleтАЭ fra HTTP API-legitimationsoplysninger i kontrolpanelet",
"octopushLogin": "тАЬLoginтАЭ fra HTTP API-legitimationsoplysninger i kontrolpanelet",
"pushoversounds pushover": "Pushover (standard)",
"pushoversounds bike": "Cykel",
"pushoversounds bugle": "Signalhorn",
"pushoversounds cashregister": "Kasseapparat",
"pushoversounds cosmic": "Kosmisk",
"pushoversounds falling": "Faldende",
"pushoversounds gamelan": "Gamelan",
"pushoversounds incoming": "Indkommende",
"pushoversounds intermission": "Pause",
"pushoversounds spacealarm": "Rumalarm",
"pushoversounds tugboat": "Sl├жbeb├еd",
"pushoversounds climb": "Klatring (lang)",
"pushoversounds persistent": "Vedvarende (lang)",
"pushoversounds echo": "Pushover Echo (lang)",
"pushoversounds updown": "Op Ned (lang)",
"GoogleChat": "Google Chat (kun Google Workspace)",
"styleElapsedTimeShowNoLine": "Vis (ingen linjer)",
"Slug": "Slug",
"The slug is already taken. Please choose another slug.": "Denne slug er allerede i brug. V├жlg venligst en anden.",
"There might be a typing error in the address.": "Der er muligvis en stavfejl i adressen.",
"Long-Lived Access Token": "Long-Lived Access Token",
"Search monitored sites": "S├╕g overv├еgede sites",
"liquidIntroduction": "Templatability opn├еs via Liquid-templeringssproget. Se venligst {0} for brugsanvisninger. Her er de tilg├жngelige variabler:",
"templateLimitedToUpDownCertNotifications": "kun tilg├жngelig for UP/DOWN/Certifikatudl├╕b notifikationer",
"shrinkDatabaseDescriptionSqlite": "Udl├╕s database-{vacuum} for SQLite. {auto_vacuum} er allerede aktiveret, men dette defragmenterer ikke databasen eller ompakker de enkelte database-sider p├е samme m├еde som {vacuum}-kommandoen g├╕r.",
"Check/Uncheck": "Mark├йr/Afjern markering",
"enableProxyDescription": "Denne proxy vil ikke p├еvirke monitor-foresp├╕rgsler, f├╕r den er aktiveret. Du kan midlertidigt deaktivere proxyen for alle monitorer via aktiveringsstatus.",
"RadiusSecretDescription": "Delt hemmelighed mellem klient og server",
"noDockerHostMsg": "Ikke tilg├жngelig. Ops├жt en Docker-host f├╕rst.",
"DockerHostRequired": "Angiv venligst Docker-hosten for denne monitor.",
"tailscalePingWarning": "For at bruge Tailscale Ping-monitoren skal du installere Uptime Kuma uden Docker og ogs├е installere Tailscale-klienten p├е din server.",
"trustProxyDescription": "Tillid til тАШX-Forwarded-*тАЩ headers. Hvis du vil hente den korrekte klient-IP, og din Uptime Kuma er bag en proxy s├еsom Nginx eller Apache, b├╕r du aktivere dette.",
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "En langvarig adgangstoken kan oprettes ved at klikke p├е dit profilnavn (nederst til venstre), rulle ned til bunden og derefter klikke p├е тАЬOpret tokenтАЭ. ",
"backupOutdatedWarning": "For├жldet: Da mange funktioner er blevet tilf├╕jet, og denne backup-funktion er lidt vedligeholdelsesfri, kan den ikke generere eller gendanne en komplet backup.",
"invalidCronExpression": "Ugyldigt Cron-udtryk: {0}",
"chromeExecutableDescription": "For Docker-brugere: Hvis Chromium endnu ikke er installeret, kan det tage et par minutter at installere og vise testresultatet. Det kr├жver 1 GB diskplads.",
"Effective Date Range": "Gyldig datointerval (Valgfrit)",
"DateTime Range": "Dato-/tidsinterval",
"notificationRegional": "Regional",
"smtpLiquidIntroduction": "De f├╕lgende to felter kan tilpasses via Liquid-templateringssproget. Se venligst {0} for brugsanvisninger. Her er de tilg├жngelige variabler:",
"whatHappensAtForumPost": "Opret en ny forumpost. Dette sender IKKE beskeder i en eksisterende post. For at sende i en eksisterende post, brug тАЭ{option}тАЭ",
"grpcMethodDescription": "Metodenavnet konverteres til camelCase-format, s├еsom sayHello, check osv.",
"affectedMonitorsDescription": "V├жlg de monitorer, der er p├еvirket af den aktuelle vedligeholdelse",
"jsonQueryDescription": "Parse og udtr├жk specifikke data fra serverens JSON-svar ved hj├жlp af en JSON-foresp├╕rgsel, eller brug тАЭ$тАЭ for det r├е svar, hvis JSON ikke forventes. Resultatet sammenlignes derefter med den forventede v├жrdi som strenge. Se {0} for dokumentation, og brug {1} til at eksperimentere med foresp├╕rgsler.",
"pushoversounds classical": "Klassisk",
"pushoversounds pianobar": "Piano Bar",
"wayToGetKookBotToken": "Opret en applikation og f├е din bot-token p├е {0}",
"wayToGetKookGuildID": "T├жnd for тАШDeveloper ModeтАЩ i Kook-indstillingerne, og h├╕jreklik p├е guilden for at f├е dens ID",
"successKeywordExplanation": "MQTT-n├╕gleord, der vil blive betragtet som succes",
"endpoint": "endpoint",
"topicExplanation": "MQTT-emne til overv├еgning",
"settingUpDatabaseMSG": "Ops├жtter databasen. Det kan tage et stykke tid, s├е v├жr t├еlmodig.",
"now": "nu",
"Json Query Expression": "Json Query Expression",
"locally configured mail transfer agent": "lokalt konfigureret mail overf├╕rsels agent",
"Either enter the hostname of the server you want to connect to or localhost if you intend to use a locally configured mail transfer agent": "Indtast enten v├жrtsnavnet p├е serveren du vil forbinde til eller {localhost} hvis du planl├жgger at bruge en {local_mta}",
"timeoutAfter": "Timeout efter {0} sekunder",
"ignoredTLSError": "TLS/SSL-fejl er blevet ignoreret",
"Invert Keyword": "Inverter N├╕gleord",
"Resend Notification if Down X times consecutively": "Send meddelelse igen, hvis Ned X gange i tr├жk",
"Expected Value": "Forventede V├жrdi",
"setupDatabaseSQLite": "En simpel database-fil, anbefalet til mindre implementeringer. F├╕r v2.0.0, brugte Uptime Kuma SQLite som standard database.",
"ignoreTLSErrorGeneral": "Ignor├йr TLS/SSL-fejl for forbindelsen",
"time ago": "{0} siden",
"-year": "-├еr",
"Host URL": "Host URL",
"Request Timeout": "Anmod Timeout",
"Cannot connect to the socket server": "Kan ikke oprette forbindelse til socket serveren",
"pushViewCode": "Hvordan bruger man Push Monitor? (Se kode)"
} }

View File

@@ -1085,34 +1085,5 @@
"Can be found on:": "Ist zu finden auf: {0}", "Can be found on:": "Ist zu finden auf: {0}",
"From": "Von", "From": "Von",
"Arcade": "Spielhalle", "Arcade": "Spielhalle",
"Time sensitive notifications will be delivered immediately, even if the device is in do not disturb mode.": "Zeitkritische Benachrichtigungen werden sofort zugestellt, auch wenn sich das Ger├дt im Nicht st├╢ren-Modus befindet.", "Time sensitive notifications will be delivered immediately, even if the device is in do not disturb mode.": "Zeitkritische Benachrichtigungen werden sofort zugestellt, auch wenn sich das Ger├дt im Nicht st├╢ren-Modus befindet."
"RabbitMQ Nodes": "RabbitMQ-Verwaltungsknoten",
"rabbitmqNodesDescription": "Gib die URL f├╝r die RabbitMQ-Verwaltungsknoten einschliesslich Protokoll und Port ein. Beispiel: {0}",
"rabbitmqNodesRequired": "Setze die Knoten f├╝r diesen Monitor.",
"RabbitMQ Username": "RabbitMQ Benutzername",
"RabbitMQ Password": "RabbitMQ Passwort",
"SendGrid API Key": "SendGrid-API-Schl├╝ssel",
"Separate multiple email addresses with commas": "Mehrere E-Mail-Adressen mit Kommas trennen",
"rabbitmqNodesInvalid": "Benutze eine vollst├дndig qualifizierte URL (beginnend mit 'http') f├╝r RabbitMQ-Knoten.",
"rabbitmqHelpText": "Um den Monitor zu benutzen, musst du das Management Plugin in deinem RabbitMQ-Setup aktivieren. Weitere Informationen siehe {rabitmq_documentation}.",
"aboutSlackUsername": "├Дndert den Anzeigenamen des Absenders. Wenn du jemanden erw├дhnen m├╢chtest, f├╝ge ihn stattdessen in den Namen ein.",
"templateHostnameOrURL": "Hostname oder URL",
"telegramUseTemplate": "Benutzerdefinierte Nachrichtenvorlage verwenden",
"telegramUseTemplateDescription": "Wenn diese Option aktiviert ist, wird die Nachricht unter Verwendung einer benutzerdefinierten Vorlage gesendet.",
"templateServiceName": "Service-Name",
"YZJ Webhook URL": "YZJ Webhook URL",
"YZJ Robot Token": "YZJ Robot Token",
"templateStatus": "Status",
"telegramTemplateFormatDescription": "Telegram erm├╢glicht die Verwendung verschiedener Markup-Sprachen f├╝r Nachrichten, siehe Telegram {0} f├╝r spezifische Details.",
"Plain Text": "Nur Text",
"Message Template": "Nachrichtenvorlage",
"Template Format": "Vorlagenformat",
"wayToGetWahaApiUrl": "Die URL deiner WAHA-Instanz.",
"wayToGetWahaSession": "Von dieser Sitzung aus sendet WAHA Benachrichtigungen an die Chat-ID. Du kannst sie im WAHA Dashboard finden.",
"wahaSession": "Sitzung",
"wahaChatId": "Chat-ID (Telefonnummer / Kontakt-ID / Gruppen-ID)",
"wayToGetWahaApiKey": "API-Schl├╝ssel ist der Wert der WHATSAPP_API_KEY-Umgebungsvariable, den du beim Ausf├╝hren von WAHA verwendet hast.",
"wayToWriteWahaChatId": "Die Telefonnummer mit internationaler Vorwahl, ohne den anf├дnglichen Pluszeichen ({0}), die Kontakt-ID ({1}) oder die Gruppen-ID ({2}). Die Benachrichtigungen werden an diese Chat-ID von der WAHA-Sitzung gesendet.",
"telegramServerUrl": "(Optional) Server URL",
"telegramServerUrlDescription": "Um die Telegram-Bot-API-Beschr├дnkungen aufzuheben oder in gesperrten Gebieten (China, Iran usw.) Zugriff zu erhalten. Weitere Informationen findest du unter {0}. Standard: {1}"
} }

View File

@@ -1088,34 +1088,5 @@
"Bubble": "Blase", "Bubble": "Blase",
"Clear": "Klar", "Clear": "Klar",
"Pop": "Pop", "Pop": "Pop",
"Arcade": "Spielhalle", "Arcade": "Spielhalle"
"rabbitmqNodesRequired": "Setze die Knoten f├╝r diesen Monitor.",
"RabbitMQ Username": "RabbitMQ Benutzername",
"RabbitMQ Password": "RabbitMQ Passwort",
"SendGrid API Key": "SendGrid-API-Schl├╝ssel",
"Separate multiple email addresses with commas": "Mehrere E-Mail-Adressen mit Kommas trennen",
"RabbitMQ Nodes": "RabbitMQ-Verwaltungsknoten",
"rabbitmqNodesDescription": "Gib die URL f├╝r die RabbitMQ-Verwaltungsknoten einschlie├Яlich Protokoll und Port ein. Beispiel: {0}",
"rabbitmqNodesInvalid": "Benutze eine vollst├дndig qualifizierte URL (beginnend mit 'http') f├╝r RabbitMQ-Knoten.",
"rabbitmqHelpText": "Um den Monitor zu benutzen, musst du das Management Plugin in deinem RabbitMQ-Setup aktivieren. Weitere Informationen siehe {rabitmq_documentation}.",
"aboutSlackUsername": "├Дndert den Anzeigenamen des Absenders. Wenn du jemanden erw├дhnen m├╢chtest, f├╝ge ihn stattdessen in den Namen ein.",
"templateHostnameOrURL": "Hostname oder URL",
"telegramUseTemplate": "Benutzerdefinierte Nachrichtenvorlage verwenden",
"telegramTemplateFormatDescription": "Telegram erm├╢glicht die Verwendung verschiedener Markup-Sprachen f├╝r Nachrichten, siehe Telegram {0} f├╝r spezifische Details.",
"Plain Text": "Nur Text",
"templateServiceName": "Service-Name",
"YZJ Webhook URL": "YZJ Webhook URL",
"YZJ Robot Token": "YZJ Robot Token",
"templateStatus": "Status",
"telegramUseTemplateDescription": "Wenn diese Option aktiviert ist, wird die Nachricht unter Verwendung einer benutzerdefinierten Vorlage gesendet.",
"Message Template": "Nachrichtenvorlage",
"Template Format": "Vorlagenformat",
"wayToGetWahaApiUrl": "Die URL deiner WAHA-Instanz.",
"wahaSession": "Sitzung",
"wahaChatId": "Chat-ID (Telefonnummer / Kontakt-ID / Gruppen-ID)",
"wayToGetWahaApiKey": "API-Schl├╝ssel ist der Wert der WHATSAPP_API_KEY-Umgebungsvariable, den du beim Ausf├╝hren von WAHA verwendet hast.",
"wayToGetWahaSession": "Von dieser Sitzung aus sendet WAHA Benachrichtigungen an die Chat-ID. Du kannst sie im WAHA Dashboard finden.",
"wayToWriteWahaChatId": "Die Telefonnummer mit internationaler Vorwahl, ohne den anf├дnglichen Pluszeichen ({0}), die Kontakt-ID ({1}) oder die Gruppen-ID ({2}). Die Benachrichtigungen werden an diese Chat-ID von der WAHA-Sitzung gesendet.",
"telegramServerUrlDescription": "Um die Telegram-Bot-API-Beschr├дnkungen aufzuheben oder in gesperrten Gebieten (China, Iran usw.) Zugriff zu erhalten. Weitere Informationen findest du unter {0}. Standard: {1}",
"telegramServerUrl": "(Optional) Server URL"
} }

View File

@@ -97,6 +97,8 @@
"pushOthers": "Others", "pushOthers": "Others",
"programmingLanguages": "Programming Languages", "programmingLanguages": "Programming Languages",
"Save": "Save", "Save": "Save",
"Debug": "Debug",
"Copy": "Copy",
"Notifications": "Notifications", "Notifications": "Notifications",
"Not available, please setup.": "Not available, please set up.", "Not available, please setup.": "Not available, please set up.",
"Setup Notification": "Set Up Notification", "Setup Notification": "Set Up Notification",
@@ -231,9 +233,6 @@
"templateMonitorJSON": "object describing the monitor", "templateMonitorJSON": "object describing the monitor",
"templateLimitedToUpDownCertNotifications": "only available for UP/DOWN/Certificate expiry notifications", "templateLimitedToUpDownCertNotifications": "only available for UP/DOWN/Certificate expiry notifications",
"templateLimitedToUpDownNotifications": "only available for UP/DOWN notifications", "templateLimitedToUpDownNotifications": "only available for UP/DOWN notifications",
"templateServiceName": "service name",
"templateHostnameOrURL": "hostname or URL",
"templateStatus": "status",
"webhookAdditionalHeadersTitle": "Additional Headers", "webhookAdditionalHeadersTitle": "Additional Headers",
"webhookAdditionalHeadersDesc": "Sets additional headers sent with the webhook. Each header should be defined as a JSON key/value.", "webhookAdditionalHeadersDesc": "Sets additional headers sent with the webhook. Each header should be defined as a JSON key/value.",
"webhookBodyPresetOption": "Preset - {0}", "webhookBodyPresetOption": "Preset - {0}",
@@ -252,6 +251,14 @@
"PushUrl": "Push URL", "PushUrl": "Push URL",
"HeadersInvalidFormat": "The request headers are not valid JSON: ", "HeadersInvalidFormat": "The request headers are not valid JSON: ",
"BodyInvalidFormat": "The request body is not valid JSON: ", "BodyInvalidFormat": "The request body is not valid JSON: ",
"CopyToClipboardError": "Couldn't copy to clipboard: {error}",
"CopyToClipboardSuccess": "Copied!",
"CurlDebugInfo": "To debug the monitor, you can either paste this into your own machines terminal or into the machines terminal which uptime kuma is running on and see what you are requesting.{newiline}Please be aware of networking differences like {firewalls}, {dns_resolvers} or {docker_networks}.",
"firewalls": "firewalls",
"dns resolvers": "dns resolvers",
"docker networks": "docker networks",
"CurlDebugInfoOAuth2CCUnsupported": "Full oauth client credential flow is not supported in {curl}.{newline}Please get a bearer token and pass it via the {oauth2_bearer} option.",
"CurlDebugInfoProxiesUnsupported": "Proxy support in the above {curl} command is currently not implemented.",
"Monitor History": "Monitor History", "Monitor History": "Monitor History",
"clearDataOlderThan": "Keep monitor history data for {0} days.", "clearDataOlderThan": "Keep monitor history data for {0} days.",
"PasswordsDoNotMatch": "Passwords do not match.", "PasswordsDoNotMatch": "Passwords do not match.",
@@ -424,13 +431,8 @@
"telegramSendSilentlyDescription": "Sends the message silently. Users will receive a notification with no sound.", "telegramSendSilentlyDescription": "Sends the message silently. Users will receive a notification with no sound.",
"telegramProtectContent": "Protect Forwarding/Saving", "telegramProtectContent": "Protect Forwarding/Saving",
"telegramProtectContentDescription": "If enabled, the bot messages in Telegram will be protected from forwarding and saving.", "telegramProtectContentDescription": "If enabled, the bot messages in Telegram will be protected from forwarding and saving.",
"telegramUseTemplate": "Use custom message template",
"telegramUseTemplateDescription": "If enabled, the message will be sent using a custom template.",
"telegramTemplateFormatDescription": "Telegram allows using different markup languages for messages, see Telegram {0} for specifc details.",
"supportTelegramChatID": "Support Direct Chat / Group / Channel's Chat ID", "supportTelegramChatID": "Support Direct Chat / Group / Channel's Chat ID",
"wayToGetTelegramChatID": "You can get your chat ID by sending a message to the bot and going to this URL to view the chat_id:", "wayToGetTelegramChatID": "You can get your chat ID by sending a message to the bot and going to this URL to view the chat_id:",
"telegramServerUrl": "(Optional) Server Url",
"telegramServerUrlDescription": "To lift Telegram's bot api limitations or gain access in blocked areas (China, Iran, etc). For more information click {0}. Default: {1}",
"YOUR BOT TOKEN HERE": "YOUR BOT TOKEN HERE", "YOUR BOT TOKEN HERE": "YOUR BOT TOKEN HERE",
"chatIDNotFound": "Chat ID is not found; please send a message to this bot first", "chatIDNotFound": "Chat ID is not found; please send a message to this bot first",
"disableCloudflaredNoAuthMsg": "You are in No Auth mode, a password is not required.", "disableCloudflaredNoAuthMsg": "You are in No Auth mode, a password is not required.",
@@ -527,6 +529,9 @@
"leave blank for default subject": "leave blank for default subject", "leave blank for default subject": "leave blank for default subject",
"emailCustomBody": "Custom Body", "emailCustomBody": "Custom Body",
"leave blank for default body": "leave blank for default body", "leave blank for default body": "leave blank for default body",
"emailTemplateServiceName": "Service Name",
"emailTemplateHostnameOrURL": "Hostname or URL",
"emailTemplateStatus": "Status",
"emailTemplateMonitorJSON": "object describing the monitor", "emailTemplateMonitorJSON": "object describing the monitor",
"emailTemplateHeartbeatJSON": "object describing the heartbeat", "emailTemplateHeartbeatJSON": "object describing the heartbeat",
"emailTemplateMsg": "message of the notification", "emailTemplateMsg": "message of the notification",
@@ -726,7 +731,6 @@
"Icon Emoji": "Icon Emoji", "Icon Emoji": "Icon Emoji",
"signalImportant": "IMPORTANT: You cannot mix groups and numbers in recipients!", "signalImportant": "IMPORTANT: You cannot mix groups and numbers in recipients!",
"aboutWebhooks": "More info about Webhooks on: {0}", "aboutWebhooks": "More info about Webhooks on: {0}",
"aboutSlackUsername": "Changes the display name of the message sender. If you want to mention someone, include it in the friendly name instead.",
"aboutChannelName": "Enter the channel name on {0} Channel Name field if you want to bypass the Webhook channel. Ex: #other-channel", "aboutChannelName": "Enter the channel name on {0} Channel Name field if you want to bypass the Webhook channel. Ex: #other-channel",
"aboutKumaURL": "If you leave the Uptime Kuma URL field blank, it will default to the Project GitHub page.", "aboutKumaURL": "If you leave the Uptime Kuma URL field blank, it will default to the Project GitHub page.",
"smtpDkimSettings": "DKIM Settings", "smtpDkimSettings": "DKIM Settings",
@@ -1056,16 +1060,5 @@
"RabbitMQ Password": "RabbitMQ Password", "RabbitMQ Password": "RabbitMQ Password",
"rabbitmqHelpText": "To use the monitor, you will need to enable the Management Plugin in your RabbitMQ setup. For more information, please consult the {rabitmq_documentation}.", "rabbitmqHelpText": "To use the monitor, you will need to enable the Management Plugin in your RabbitMQ setup. For more information, please consult the {rabitmq_documentation}.",
"SendGrid API Key": "SendGrid API Key", "SendGrid API Key": "SendGrid API Key",
"Separate multiple email addresses with commas": "Separate multiple email addresses with commas", "Separate multiple email addresses with commas": "Separate multiple email addresses with commas"
"wahaSession": "Session",
"wahaChatId": "Chat ID (Phone Number / Contact ID / Group ID)",
"wayToGetWahaApiUrl": "Your WAHA Instance URL.",
"wayToGetWahaApiKey": "API Key is WHATSAPP_API_KEY environment variable value you used to run WAHA.",
"wayToGetWahaSession": "From this session WAHA sends notifications to Chat ID. You can find it in WAHA Dashboard.",
"wayToWriteWahaChatId": "The phone number with the international prefix, but without the plus sign at the start ({0}), the Contact ID ({1}) or the Group ID ({2}). Notifications are sent to this Chat ID from WAHA Session.",
"YZJ Webhook URL": "YZJ Webhook URL",
"YZJ Robot Token": "YZJ Robot token",
"Plain Text": "Plain Text",
"Message Template": "Message Template",
"Template Format": "Template Format"
} }

View File

@@ -9,7 +9,7 @@
"passwordNotMatchMsg": "La contrase├▒a repetida no coincide.", "passwordNotMatchMsg": "La contrase├▒a repetida no coincide.",
"notificationDescription": "Por favor asigna una notificaci├│n a el/los monitor(es) para hacerlos funcional(es).", "notificationDescription": "Por favor asigna una notificaci├│n a el/los monitor(es) para hacerlos funcional(es).",
"keywordDescription": "Buscar palabra clave en HTML plano o respuesta JSON. La b├║squeda es sensible a may├║sculas.", "keywordDescription": "Buscar palabra clave en HTML plano o respuesta JSON. La b├║squeda es sensible a may├║sculas.",
"pauseDashboardHome": "Pausar", "pauseDashboardHome": "Pausado",
"deleteMonitorMsg": "┬┐Seguro que quieres eliminar este monitor?", "deleteMonitorMsg": "┬┐Seguro que quieres eliminar este monitor?",
"deleteNotificationMsg": "┬┐Seguro que quieres eliminar esta notificaci├│n para todos los monitores?", "deleteNotificationMsg": "┬┐Seguro que quieres eliminar esta notificaci├│n para todos los monitores?",
"resolverserverDescription": "Cloudflare es el servidor por defecto, puedes cambiar el servidor de resoluci├│n en cualquier momento.", "resolverserverDescription": "Cloudflare es el servidor por defecto, puedes cambiar el servidor de resoluci├│n en cualquier momento.",
@@ -654,7 +654,7 @@
"gorush": "Gorush", "gorush": "Gorush",
"squadcast": "Squadcast", "squadcast": "Squadcast",
"Maintenance Time Window of a Day": "Ventana de tiempo de mantenimiento de un d├нa", "Maintenance Time Window of a Day": "Ventana de tiempo de mantenimiento de un d├нa",
"Effective Date Range": "Rango de Fecha Efectivo(Opcional)", "Effective Date Range": "Rango de Fechas Efectivas (Opcional)",
"Free Mobile User Identifier": "Identificador de Usuario de Free Mobile", "Free Mobile User Identifier": "Identificador de Usuario de Free Mobile",
"Gateway Type": "Tipo de puerta de enlace", "Gateway Type": "Tipo de puerta de enlace",
"SMSManager": "SMSManager", "SMSManager": "SMSManager",
@@ -677,7 +677,7 @@
"alertaRecoverState": "Estado de Recuperaci├│n", "alertaRecoverState": "Estado de Recuperaci├│n",
"serwersms": "SerwerSMS.pl", "serwersms": "SerwerSMS.pl",
"serwersmsAPIUser": "Nombre de usuario de API (inc. webapi_ prefix)", "serwersmsAPIUser": "Nombre de usuario de API (inc. webapi_ prefix)",
"smseagleGroup": "Nombre(s) de grupo(s) de Gu├нa Telef├│nica", "smseagleGroup": "Nombre/s del grupo de la gu├нa telef├│nica",
"Unpin": "Dejar de Fijar", "Unpin": "Dejar de Fijar",
"Prefix Custom Message": "Prefijo personalizado", "Prefix Custom Message": "Prefijo personalizado",
"markdownSupported": "Sintaxis de Markdown soportada", "markdownSupported": "Sintaxis de Markdown soportada",
@@ -818,7 +818,7 @@
"showCertificateExpiry": "Mostrar caducidad del certificado", "showCertificateExpiry": "Mostrar caducidad del certificado",
"noOrBadCertificate": "Certificado Nulo/Incorrecto", "noOrBadCertificate": "Certificado Nulo/Incorrecto",
"aboutNotifyChannel": "Notificar canal activar├б una notificaci├│n de escritorio o m├│vil para todos los miembros del canal, ya sea que su disponibilidad est├й activa o ausente.", "aboutNotifyChannel": "Notificar canal activar├б una notificaci├│n de escritorio o m├│vil para todos los miembros del canal, ya sea que su disponibilidad est├й activa o ausente.",
"Server URL should not contain the nfty topic": "La URL del servidor no puede inclu├нr el t├│pico de ntfy", "Server URL should not contain the nfty topic": "La URL del servidor no debe contener el tema nfty",
"PushDeer Server": "Servidor PushDeer", "PushDeer Server": "Servidor PushDeer",
"pushDeerServerDescription": "Dejar en blanco para usar el servidor oficial", "pushDeerServerDescription": "Dejar en blanco para usar el servidor oficial",
"Badge Duration (in hours)": "Duraci├│n de la insignia (en horas)", "Badge Duration (in hours)": "Duraci├│n de la insignia (en horas)",
@@ -855,26 +855,26 @@
"2faEnabled": "2FA habilitado.", "2faEnabled": "2FA habilitado.",
"2faDisabled": "2FA deshabilitado.", "2faDisabled": "2FA deshabilitado.",
"liquidIntroduction": "La plantilla se logra a trav├йs del lenguaje de plantillas Liquid. Consulte {0} para obtener instrucciones de uso. Estas son las variables disponibles:", "liquidIntroduction": "La plantilla se logra a trav├йs del lenguaje de plantillas Liquid. Consulte {0} para obtener instrucciones de uso. Estas son las variables disponibles:",
"templateLimitedToUpDownCertNotifications": "solo disponible para notificaciones FUNCIONAL/CA├НDO/Caducidad de certificado", "templateLimitedToUpDownCertNotifications": "disponible solo para notificaciones de arriba/abajo/caducidad del certificado",
"emailTemplateMsg": "mensaje de la notificaci├│n", "emailTemplateMsg": "mensaje de la notificaci├│n",
"emailTemplateLimitedToUpDownNotification": "s├│lo disponible para latidos FUNCIONAL/CA├НDO, de lo contrario nulo", "emailTemplateLimitedToUpDownNotification": "disponible solo para latidos de arriba/abajo, de lo contrario, nulo",
"setup a new monitor group": "configurar un nuevo grupo de monitores", "setup a new monitor group": "configurar un nuevo grupo de monitores",
"authUserInactiveOrDeleted": "El usuario est├б inactivo o eliminado.", "authUserInactiveOrDeleted": "El usuario est├б inactivo o eliminado.",
"2faAlreadyEnabled": "2FA ya est├б habilitado.", "2faAlreadyEnabled": "2FA ya est├б activado.",
"remoteBrowsersDescription": "Los navegadores remotos son una alternativa a ejecutar Chromium localmente. Config├║ralos con un servicio como browserless.io o con├йctalos a tu propio servidor", "remoteBrowsersDescription": "Los navegadores remotos son una alternativa a ejecutar Chromium localmente. Config├║ralos con un servicio como browserless.io o con├йctalos a tu propio servidor",
"successKeyword": "Palabra clave de ├йxito", "successKeyword": "Palabra clave de ├йxito",
"successKeywordExplanation": "MQTT Palabra clave que se considerar├б como ├йxito", "successKeywordExplanation": "MQTT Palabra clave que se considerar├б como ├йxito",
"Remove the expiry notification": "Eliminar la notificaci├│n de vencimiento", "Remove the expiry notification": "Eliminar la notificaci├│n de vencimiento",
"Browser Screenshot": "Captura de pantalla del navegador", "Browser Screenshot": "Captura de pantalla del navegador",
"emailCustomisableContent": "Contenido personalizable", "emailCustomisableContent": "Contenido personalizable",
"smtpLiquidIntroduction": "Los dos campos siguientes pueden crear plantillas mediante el lenguaje de plantillas Liquid. Consulte {0} para obtener instrucciones de uso. Estas son las variables disponibles:", "smtpLiquidIntroduction": "Los siguientes dos campos son personalizables a trav├йs del lenguaje de plantillas Liquid. Por favor, consulta {0} para las instrucciones de uso. Estas son las variables disponibles:",
"leave blank for default subject": "dejar en blanco para el asunto predeterminado", "leave blank for default subject": "dejar en blanco para asunto predeterminado",
"emailCustomBody": "Cuerpo personalizado", "emailCustomBody": "Cuerpo personalizado",
"successAuthChangePassword": "La contrase├▒a se ha actualizado correctamente.", "successAuthChangePassword": "La contrase├▒a se ha actualizado correctamente.",
"successDeleted": "Borrado exitosamente.", "successDeleted": "Eliminado con ├йxito.",
"successEdited": "Editado con ├йxito.", "successEdited": "Editado con ├йxito.",
"successDisabled": "Deshabilitado con ├йxito.", "successDisabled": "Desactivado con ├йxito.",
"GrafanaOncallUrl": "URL de llamada de Grafana", "GrafanaOncallUrl": "Grafana URL de llamada",
"Reset Token": "Restablecer Token", "Reset Token": "Restablecer Token",
"Remote Browsers": "Navegadores remotos", "Remote Browsers": "Navegadores remotos",
"Remote Browser": "Navegador remoto", "Remote Browser": "Navegador remoto",
@@ -885,17 +885,17 @@
"successResumed": "Reanudado con ├йxito.", "successResumed": "Reanudado con ├йxito.",
"successPaused": "Pausado con ├йxito.", "successPaused": "Pausado con ├йxito.",
"successBackupRestored": "Copia de seguridad restaurada correctamente.", "successBackupRestored": "Copia de seguridad restaurada correctamente.",
"successEnabled": "Habilitado exitosamente.", "successEnabled": "Activado con ├йxito.",
"tagNotFound": "Etiqueta no encontrada.", "tagNotFound": "Etiqueta no encontrada.",
"foundChromiumVersion": "Se encontr├│ Chromium/Chrome. Versi├│n: {0}", "foundChromiumVersion": "Encontrado Chromium/Chrome. Versi├│n: {0}",
"pushViewCode": "┬┐C├│mo utilizar el monitor Push? (Ver c├│digo)", "pushViewCode": "┬┐C├│mo utilizar el monitor Push? (Ver c├│digo)",
"pushOthers": "Otros", "pushOthers": "Otros",
"programmingLanguages": "Lenguajes de Programaci├│n", "programmingLanguages": "Lenguajes de Programaci├│n",
"templateMsg": "mensaje de la notificaci├│n", "templateMsg": "mensaje de la notificaci├│n",
"templateMonitorJSON": "objeto que describe el monitor", "templateMonitorJSON": "objeto que describe el monitor",
"templateLimitedToUpDownNotifications": "s├│lo disponible para notificaciones FUNCIONAL/CAIDO", "templateLimitedToUpDownNotifications": "disponible solo para notificaciones de arriba/abajo",
"Add a new expiry notification day": "A├▒adir una nueva notificaci├│n de vencimiento", "Add a new expiry notification day": "A├▒adir una nueva notificaci├│n de vencimiento",
"leave blank for default body": "dejar en blanco para el cuerpo predeterminado", "leave blank for default body": "dejar en blanco para el cuerpo por defecto",
"emailTemplateServiceName": "Nombre del Servicio", "emailTemplateServiceName": "Nombre del Servicio",
"emailTemplateHostnameOrURL": "Nombre del Host o URL", "emailTemplateHostnameOrURL": "Nombre del Host o URL",
"emailTemplateStatus": "Estado", "emailTemplateStatus": "Estado",
@@ -916,7 +916,7 @@
"ntfyPriorityHelptextAllExceptDown": "Todos los eventos son enviados con esta prioridad, excepto los eventos {0}, que tienen una prioridad de {1}", "ntfyPriorityHelptextAllExceptDown": "Todos los eventos son enviados con esta prioridad, excepto los eventos {0}, que tienen una prioridad de {1}",
"templateHeartbeatJSON": "objeto que describe el latido", "templateHeartbeatJSON": "objeto que describe el latido",
"What is a Remote Browser?": "┬┐Qu├й es un Navegador Remoto?", "What is a Remote Browser?": "┬┐Qu├й es un Navegador Remoto?",
"Your User ID": "Su ID de usuario", "Your User ID": "Tu ID de usuario",
"Alphanumeric (recommended)": "Alfanum├йrico (recomendado)", "Alphanumeric (recommended)": "Alfanum├йrico (recomendado)",
"Destination": "Destino", "Destination": "Destino",
"wayToGetWhapiUrlAndToken": "Puedes obtener la URL de la API y el token accediendo al canal que desee desde {0}", "wayToGetWhapiUrlAndToken": "Puedes obtener la URL de la API y el token accediendo al canal que desee desde {0}",
@@ -927,7 +927,7 @@
"Refresh Interval": "Intervalo de refresco", "Refresh Interval": "Intervalo de refresco",
"ignoreTLSErrorGeneral": "Ignorar errores SSL/TLS durante la conexi├│n", "ignoreTLSErrorGeneral": "Ignorar errores SSL/TLS durante la conexi├│n",
"documentationOf": "Documentaci├│n de {0}", "documentationOf": "Documentaci├│n de {0}",
"wayToGetHeiiOnCallDetails": "C├│mo obtener el Trigger ID y las API Keys se explica en la {documentaci├│n}", "wayToGetHeiiOnCallDetails": "C├│mo obtener el ID del Disparador y las Claves API se explica en la {documentaci├│n}",
"Command": "Comando", "Command": "Comando",
"wayToGetThreemaGateway": "Puedes registrarte para Threema Gateway {0}.", "wayToGetThreemaGateway": "Puedes registrarte para Threema Gateway {0}.",
"threemaRecipient": "Destinatario", "threemaRecipient": "Destinatario",
@@ -941,7 +941,7 @@
"Host URL": "URL del anfitri├│n", "Host URL": "URL del anfitri├│n",
"Either enter the hostname of the server you want to connect to or localhost if you intend to use a locally configured mail transfer agent": "Ingresa el nombre del host del servidor al que deseas conectarte o {localhost} si deseas usar un {local_mta}", "Either enter the hostname of the server you want to connect to or localhost if you intend to use a locally configured mail transfer agent": "Ingresa el nombre del host del servidor al que deseas conectarte o {localhost} si deseas usar un {local_mta}",
"smspartnerPhoneNumberHelptext": "El n├║mero debe estar en el formato internacional {0}, {1}. M├║ltiples n├║meros deben estar separados por {2}", "smspartnerPhoneNumberHelptext": "El n├║mero debe estar en el formato internacional {0}, {1}. M├║ltiples n├║meros deben estar separados por {2}",
"smspartnerSenderName": "Nombre del emisor del SMS", "smspartnerSenderName": "Nombre del remitente de SMS",
"smspartnerApiurl": "Puedes encontrar tu clave API en tu panel de control en {0}", "smspartnerApiurl": "Puedes encontrar tu clave API en tu panel de control en {0}",
"smspartnerPhoneNumber": "N├║mero(s) de tel├йfono", "smspartnerPhoneNumber": "N├║mero(s) de tel├йfono",
"max 11 alphanumeric characters": "m├бximo 11 caracteres alfanum├йricos", "max 11 alphanumeric characters": "m├бximo 11 caracteres alfanum├йricos",
@@ -951,7 +951,7 @@
"Originator type": "Tipo de originador", "Originator type": "Tipo de originador",
"Telephone number": "N├║mero de tel├йfono", "Telephone number": "N├║mero de tel├йfono",
"Mentioning": "Mencionando", "Mentioning": "Mencionando",
"Don't mention people": "No mencionar personas", "Don't mention people": "No mencionar a las personas",
"Mention group": "Mencionar a {group}", "Mention group": "Mencionar a {group}",
"Bitrix24 Webhook URL": "URL del Webhook de Bitrix24", "Bitrix24 Webhook URL": "URL del Webhook de Bitrix24",
"wayToGetBitrix24Webhook": "Puedes crear un webhook siguiendo los pasos en {0}", "wayToGetBitrix24Webhook": "Puedes crear un webhook siguiendo los pasos en {0}",
@@ -961,11 +961,11 @@
"wayToWriteWhapiRecipient": "El n├║mero de tel├йfono con el prefijo internacional, pero sin el signo m├бs al inicio ({0}), el ID de Contacto ({1}) o el ID de Grupo ({2}).", "wayToWriteWhapiRecipient": "El n├║mero de tel├йfono con el prefijo internacional, pero sin el signo m├бs al inicio ({0}), el ID de Contacto ({1}) o el ID de Grupo ({2}).",
"From Phone Number / Transmission Path Originating Address (TPOA)": "N├║mero de Tel├йfono del Remitente / Direcci├│n de Origen de la Ruta de Transmisi├│n (TPOA)", "From Phone Number / Transmission Path Originating Address (TPOA)": "N├║mero de Tel├йfono del Remitente / Direcci├│n de Origen de la Ruta de Transmisi├│n (TPOA)",
"To Phone Number": "Al N├║mero de Tel├йfono", "To Phone Number": "Al N├║mero de Tel├йfono",
"Select message type": "Seleccionar el tipo de mensaje", "Select message type": "Seleccionar tipo de mensaje",
"Send to channel": "Enviar al canal", "Send to channel": "Enviar al canal",
"max 15 digits": "m├бximo 15 d├нgitos", "max 15 digits": "m├бximo 15 d├нgitos",
"mongodbCommandDescription": "Ejecuta un comando de MongoDB contra la base de datos. Para obtener informaci├│n sobre los comandos disponibles, consulta la {documentaci├│n}", "mongodbCommandDescription": "Ejecuta un comando de MongoDB contra la base de datos. Para obtener informaci├│n sobre los comandos disponibles, consulta la {documentaci├│n}",
"whapiRecipient": "N├║mero de tel├йfono / ID del contacto / ID del grupo", "whapiRecipient": "N├║mero de Tel├йfono / ID de Contacto / ID de Grupo",
"cellsyntSplitLongMessages": "Divide mensajes largos en hasta 6 partes. 153 x 6 = 918 caracteres.", "cellsyntSplitLongMessages": "Divide mensajes largos en hasta 6 partes. 153 x 6 = 918 caracteres.",
"receiverSevenIO": "N├║mero receptor", "receiverSevenIO": "N├║mero receptor",
"apiKeySevenIO": "Clave API de SevenIO", "apiKeySevenIO": "Clave API de SevenIO",
@@ -974,7 +974,7 @@
"gtxMessagingToHint": "Formato internacional, con el signo \"+\" al inicio ({e164}, {e212} o {e214})", "gtxMessagingToHint": "Formato internacional, con el signo \"+\" al inicio ({e164}, {e212} o {e214})",
"locally configured mail transfer agent": "agente de transferencia de correo configurado localmente", "locally configured mail transfer agent": "agente de transferencia de correo configurado localmente",
"wayToGetDiscordThreadId": "Obtener un ID de hilo / publicaci├│n en el foro es similar a obtener un ID de canal. Lee m├бs sobre c├│mo obtener IDs {0}", "wayToGetDiscordThreadId": "Obtener un ID de hilo / publicaci├│n en el foro es similar a obtener un ID de canal. Lee m├бs sobre c├│mo obtener IDs {0}",
"smspartnerSenderNameInfo": "Debe ser entre 3..=11 car├бcteres regulares", "smspartnerSenderNameInfo": "Debe tener entre 3..=11 caracteres normales",
"receiverInfoSevenIO": "Si el n├║mero receptor no est├б ubicado en Alemania, debes agregar el c├│digo de pa├нs delante del n├║mero (por ejemplo, para el c├│digo de pa├нs 1 de EE. UU. usa 117612121212 en lugar de 017612121212)", "receiverInfoSevenIO": "Si el n├║mero receptor no est├б ubicado en Alemania, debes agregar el c├│digo de pa├нs delante del n├║mero (por ejemplo, para el c├│digo de pa├нs 1 de EE. UU. usa 117612121212 en lugar de 017612121212)",
"callMeBotGet": "Aqu├н puedes generar un endpoint para {0}, {1} y {2}. Ten en cuenta que podr├нas recibir limitaciones de tasa. Las limitaciones de tasa parecen ser: {3}", "callMeBotGet": "Aqu├н puedes generar un endpoint para {0}, {1} y {2}. Ten en cuenta que podr├нas recibir limitaciones de tasa. Las limitaciones de tasa parecen ser: {3}",
"cellsyntOriginator": "Visible en el tel├йfono m├│vil del destinatario como originador del mensaje. Los valores permitidos y la funci├│n dependen del par├бmetro originatortype.", "cellsyntOriginator": "Visible en el tel├йfono m├│vil del destinatario como originador del mensaje. Los valores permitidos y la funci├│n dependen del par├бmetro originatortype.",
@@ -982,110 +982,11 @@
"threemaApiAuthenticationSecret": "Clave Secreta del Gateway-ID", "threemaApiAuthenticationSecret": "Clave Secreta del Gateway-ID",
"threemaBasicModeInfo": "Nota: Esta integraci├│n utiliza Threema Gateway en modo b├бsico (encriptaci├│n basada en servidor). Puedes encontrar m├бs detalles en {0}.", "threemaBasicModeInfo": "Nota: Esta integraci├│n utiliza Threema Gateway en modo b├бsico (encriptaci├│n basada en servidor). Puedes encontrar m├бs detalles en {0}.",
"apiKeysDisabledMsg": "Las claves API est├бn desactivadas porque la autenticaci├│n est├б desactivada.", "apiKeysDisabledMsg": "Las claves API est├бn desactivadas porque la autenticaci├│n est├б desactivada.",
"Channel access token (Long-lived)": "Token de acceso al canal (Larga duraci├│n)", "Channel access token (Long-lived)": "Token de acceso al canal (de larga duraci├│n)",
"Create new forum post": "Crear un nuevo post en el foro", "Create new forum post": "Crear nueva publicaci├│n en el foro",
"postToExistingThread": "Publicar en hilo / publicaci├│n existente", "postToExistingThread": "Publicar en hilo / publicaci├│n existente",
"forumPostName": "Nombre de la publicaci├│n en el foro", "forumPostName": "Nombre de la publicaci├│n en el foro",
"threadForumPostID": "ID del hilo / publicaci├│n en el foro", "threadForumPostID": "ID del hilo / publicaci├│n en el foro",
"e.g. {discordThreadID}": "por ejemplo, {discordThreadID}", "e.g. {discordThreadID}": "por ejemplo, {discordThreadID}",
"whatHappensAtForumPost": "Crear una nueva publicaci├│n en el foro. Esto NO publica mensajes en una publicaci├│n existente. Para publicar en una publicaci├│n existente usa \"{option}\"", "whatHappensAtForumPost": "Crear una nueva publicaci├│n en el foro. Esto NO publica mensajes en una publicaci├│n existente. Para publicar en una publicaci├│n existente usa \"{option}\""
"jsonQueryDescription": "Analice y extraiga datos espec├нficos de la respuesta JSON del servidor mediante una consulta JSON o utilice \"$\" para la respuesta sin formato, si no espera JSON. Luego, el resultado se compara con el valor esperado, como cadenas. Consulte {0} para obtener documentaci├│n y use {1} para experimentar con consultas.",
"aboutSlackUsername": "Cambia el nombre que se muestra del remitente del mensaje. Si quieres mencionar a alguien, incl├║yelo en el nombre descriptivo.",
"cacheBusterParam": "A├▒ade el par├бmetro {0}",
"cacheBusterParamDescription": "Par├бmetro generado aleatoriamente para omitir cach├йs.",
"Community String": "Cadena comunitaria",
"snmpCommunityStringHelptext": "Esta cadena funciona como contrase├▒a para autenticar y controlar el acceso a dispositivos habilitados para SNMP. Comp├бrela con la configuraci├│n de su dispositivo SNMP.",
"privateOnesenderDesc": "Aseg├║rese de que el n├║mero de tel├йfono sea v├бlido. Para enviar un mensaje a un n├║mero de tel├йfono privado, por ejemplo: 628123456789",
"wayToGetOnesenderUrlandToken": "Puedes obtener la URL y el token en el sitio web de Onesender. M├бs informaci├│n {0}",
"Optional: Space separated list of scopes": "Opcional: Lista de ├бmbitos separados por espacios",
"No tags found.": "No se han encontrado etiquetas.",
"signl4Docs": "Puede encontrar m├бs informaci├│n sobre c├│mo configurar SIGNL4 y c├│mo obtener la URL del webhook de SIGNL4 en {0}.",
"shrinkDatabaseDescriptionSqlite": "Desencadena la base de datos {vacuum} para SQLite. {auto_vacuum} ya est├б habilitado, pero esto no desfragmenta la base de datos ni reempaqueta p├бginas de base de datos individuales como lo hace el comando {vacuum}.",
"and": "y",
"Message format": "Formato del mensaje",
"Send rich messages": "Enviar mensajes enriquecidos",
"OID (Object Identifier)": "(Identificador de Objeto) OID",
"snmpOIDHelptext": "Ingrese el OID del sensor o el estado que desea monitorear. Use herramientas de administraci├│n de red como navegadores MIB o software SNMP si no est├б seguro acerca del OID.",
"Condition": "Condici├│n",
"SNMP Version": "Versi├│n SNMP",
"Please enter a valid OID.": "Por favor escribe un OID v├бlido.",
"Host Onesender": "Host de Onesender",
"Token Onesender": "Token de Onesender",
"Recipient Type": "Tipo de Receptor",
"Private Number": "N├║mero Privado",
"groupOnesenderDesc": "Aseg├║rese de que el ID del grupo sea v├бlido. Para enviar un mensaje al grupo, por ejemplo: 628123456789-342345",
"Group ID": "ID del grupo",
"Add Remote Browser": "Agregar navegador remoto",
"New Group": "Nuevo grupo",
"Group Name": "Nombre del grupo",
"OAuth2: Client Credentials": "OAuth2: Credenciales del Cliente",
"Authentication Method": "M├йtodo de autentificaci├│n",
"Authorization Header": "Cabecera de Autorizaci├│n",
"Form Data Body": "Cuerpo de datos del formulario",
"OAuth Token URL": "OAuth Token URL",
"Client ID": "ID del Cliente",
"Client Secret": "Secreto de Cliente",
"OAuth Scope": "Alcance OAuth",
"Go back to home page.": "Volver a la p├бgina de inicio.",
"Lost connection to the socket server.": "Se perdi├│ la conexi├│n con el servidor de socket.",
"Cannot connect to the socket server.": "No se puede conectar al servidor de socket.",
"SIGNL4": "SIGNL4",
"SIGNL4 Webhook URL": "URL de SIGNL4 WebhooK",
"Conditions": "Condiciones",
"conditionAdd": "A├▒adir condici├│n",
"now": "ahora",
"time ago": "hace {0}",
"-year": "-a├▒o",
"Json Query Expression": "Expresi├│n de consulta Json",
"ignoredTLSError": "Se han ignorado errores TLS/SSL",
"conditionDelete": "Borrar condici├│n",
"conditionAddGroup": "A├▒adir grupo",
"conditionDeleteGroup": "Borrar grupo",
"conditionValuePlaceholder": "Valor",
"equals": "igual",
"not equals": "no es igual",
"contains": "contiene",
"not contains": "no contiene",
"starts with": "empieza por",
"not starts with": "no empieza por",
"ends with": "termina con",
"not ends with": "No termina en",
"less than": "menor que",
"greater than": "mayor que",
"less than or equal to": "Menor o igual a",
"greater than or equal to": "Mayor o igual a",
"Notification Channel": "Canal de notificaci├│n",
"Sound": "Sonido",
"record": "Registro",
"RabbitMQ Username": "Usuario RabbitMQ",
"RabbitMQ Password": "Contrase├▒a RabbitMQ",
"RabbitMQ Nodes": "Nodos de Gesti├│n RabbitMQ",
"rabbitmqNodesRequired": "Por favor, configure los nodos para este monitor.",
"rabbitmqNodesInvalid": "Por favor, utilice una URL totalmente cualificada (comenzando por 'http') para los nodos RabbitMQ.",
"Separate multiple email addresses with commas": "Separa las m├║ltiples direcciones de correo con comas",
"rabbitmqHelpText": "Para utilizar el monitor, necesitar├б habilitar el Plugin de Gesti├│n en su configuraci├│n RabbitMQ. Para m├бs informaci├│n, por favor consulte {rabitmq_documentation}.",
"SendGrid API Key": "Clave de la API de SendGrid",
"rabbitmqNodesDescription": "Introduzca la URL para los nodos de gesti├│n de RabbitMQ incluyendo el protocolo y el puerto. Ejemplo: {0}",
"Money": "Dinero",
"Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "O bien un texto de ID de origen o un n├║mero de tel├йfono en formato E.164 si quiere ser capaz de recibir respuestas.",
"Harp": "Arpa",
"Scifi": "Ciencia Ficci├│n",
"Alphanumerical string and hyphens only": "S├│lo cadenas alfanum├йricas y guiones",
"Time Sensitive (iOS Only)": "Sensible a la Hora (Solo iOS)",
"Doorbell": "Timbre",
"Flute": "Flauta",
"Guitar": "Guitarra",
"Correct": "Correcto",
"Bubble": "Burbuja",
"Elevator": "Ascensor",
"Fail": "Fallo",
"Reveal": "Mostrar",
"Pop": "Pop",
"From": "De",
"Clear": "Limpiar",
"Can be found on:": "Se puede encontrar en: {0}",
"Custom sound to override default notification sound": "Sonidos personalizados prevalecen sobre los sonidos por defecto de las notificaciones",
"The phone number of the recipient in E.164 format.": "El n├║mero de tel├йfono del receptor en formato E.164.",
"Time sensitive notifications will be delivered immediately, even if the device is in do not disturb mode.": "Las notificaciones sensibles en el tiempo se enviar├бn inmediatamente, incluso si el dispositivo est├б en modo no molestar.",
"Arcade": "Arcade"
} }

View File

@@ -216,19 +216,19 @@
"smtpCC": "CC", "smtpCC": "CC",
"smtpBCC": "BCC", "smtpBCC": "BCC",
"discord": "Discord", "discord": "Discord",
"Discord Webhook URL": "Discord Webhook URLa", "Discord Webhook URL": "Discord Webhook URL",
"wayToGetDiscordURL": "Hona joanda lortu dezakezu: Server Settings -> Integrations -> View Webhooks -> New Webhook", "wayToGetDiscordURL": "You can get this by going to Server Settings -> Integrations -> Create Webhook",
"Bot Display Name": "Botaren erakusteko izena", "Bot Display Name": "Bot Display Name",
"Prefix Custom Message": "Prefix Custom Message", "Prefix Custom Message": "Prefix Custom Message",
"Hello @everyone is...": "Kaixo {'@'}edonor daтАж", "Hello @everyone is...": "Kaixo {'@'}edonor daтАж",
"teams": "Microsoft Teams", "teams": "Microsoft Teams",
"Webhook URL": "Webhook URLa", "Webhook URL": "Webhook URL",
"wayToGetTeamsURL": "You can learn how to create a webhook URL {0}.", "wayToGetTeamsURL": "You can learn how to create a webhook URL {0}.",
"wayToGetZohoCliqURL": "You can learn how to create a webhook URL {0}.", "wayToGetZohoCliqURL": "You can learn how to create a webhook URL {0}.",
"signal": "Signal", "signal": "Signal",
"Number": "Zenbakia", "Number": "Zenbakia",
"Recipients": "Hartzaileak", "Recipients": "Recipients",
"needSignalAPI": "REST APIarekin signal bezeroa eduki behar duzu.", "needSignalAPI": "You need to have a signal client with REST API.",
"wayToCheckSignalURL": "You can check this URL to view how to set one up:", "wayToCheckSignalURL": "You can check this URL to view how to set one up:",
"signalImportant": "IMPORTANT: You cannot mix groups and numbers in recipients!", "signalImportant": "IMPORTANT: You cannot mix groups and numbers in recipients!",
"gotify": "Gotify", "gotify": "Gotify",
@@ -280,8 +280,8 @@
"Read more": "Irakurri gehiago", "Read more": "Irakurri gehiago",
"appriseInstalled": "Apprise instalatuta.", "appriseInstalled": "Apprise instalatuta.",
"appriseNotInstalled": "Apprise ez dago instalatuta. {0}", "appriseNotInstalled": "Apprise ez dago instalatuta. {0}",
"Access Token": "Access Tokena", "Access Token": "Access Token",
"Channel access token": "Kanalaren access tokena", "Channel access token": "Channel access token",
"Line Developers Console": "Line Developers Console", "Line Developers Console": "Line Developers Console",
"lineDevConsoleTo": "Line Developers Console - {0}", "lineDevConsoleTo": "Line Developers Console - {0}",
"Basic Settings": "Oinarrizko ezarpenak", "Basic Settings": "Oinarrizko ezarpenak",
@@ -316,7 +316,7 @@
"One record": "One record", "One record": "One record",
"steamApiKeyDescription": "For monitoring a Steam Game Server you need a Steam Web-API key. You can register your API key here: ", "steamApiKeyDescription": "For monitoring a Steam Game Server you need a Steam Web-API key. You can register your API key here: ",
"Current User": "Uneko erabiltzailea", "Current User": "Uneko erabiltzailea",
"topic": "Gaia", "topic": "Topic",
"topicExplanation": "MQTT topic to monitor", "topicExplanation": "MQTT topic to monitor",
"successMessage": "Arrakasta mezua", "successMessage": "Arrakasta mezua",
"successMessageExplanation": "MQTT message that will be considered as success", "successMessageExplanation": "MQTT message that will be considered as success",
@@ -401,7 +401,7 @@
"proxyDescription": "Proxies must be assigned to a monitor to function.", "proxyDescription": "Proxies must be assigned to a monitor to function.",
"enableProxyDescription": "This proxy will not effect on monitor requests until it is activated. You can control temporarily disable the proxy from all monitors by activation status.", "enableProxyDescription": "This proxy will not effect on monitor requests until it is activated. You can control temporarily disable the proxy from all monitors by activation status.",
"setAsDefaultProxyDescription": "This proxy will be enabled by default for new monitors. You can still disable the proxy separately for each monitor.", "setAsDefaultProxyDescription": "This proxy will be enabled by default for new monitors. You can still disable the proxy separately for each monitor.",
"Certificate Chain": "Zertifikatu katea", "Certificate Chain": "Certificate Chain",
"Valid": "Baliozkoa", "Valid": "Baliozkoa",
"Invalid": "Baliogabea", "Invalid": "Baliogabea",
"AccessKeyId": "AccessKey ID", "AccessKeyId": "AccessKey ID",
@@ -476,7 +476,7 @@
"Footer Text": "Oineko testua", "Footer Text": "Oineko testua",
"Show Powered By": "Erakutsi Honekin egina:", "Show Powered By": "Erakutsi Honekin egina:",
"Domain Names": "Domeinu izenak", "Domain Names": "Domeinu izenak",
"signedInDisp": "{0} bezala logeatua", "signedInDisp": "Signed in as {0}",
"signedInDispDisabled": "Auth desgaituta.", "signedInDispDisabled": "Auth desgaituta.",
"Certificate Expiry Notification": "Zertifikatu iraungitze jakinarazpena", "Certificate Expiry Notification": "Zertifikatu iraungitze jakinarazpena",
"API Username": "API Erabiltzailea", "API Username": "API Erabiltzailea",
@@ -587,113 +587,5 @@
"statusPageRefreshIn": "{0} barru freskatuko da.", "statusPageRefreshIn": "{0} barru freskatuko da.",
"now": "orain", "now": "orain",
"time ago": "duela {0}", "time ago": "duela {0}",
"-year": "-urte", "-year": "-urte"
"styleElapsedTimeShowNoLine": "Erakutsi (Lerrorik ez)",
"styleElapsedTimeShowWithLine": "Erakutsi (Lerroarekin)",
"Select": "Hautatu",
"Docker Container": "Docker edukiontzia",
"Container Name / ID": "Edukiontzi izena / ID",
"Packet Size": "Pakete tamaina",
"telegramSendSilently": "Bidali isilik",
"Examples": "Adibideak",
"default: notify all devices": "Defektuz: jakinarazi gailu guztiak",
"Event type:": "Ekintza mota:",
"Event data:": "Ekintza mota:",
"Optional": "Hautazkoa",
"and": "eta",
"sameAsServerTimezone": "Zerbitzariaren ordu-zona bera",
"endDateTime": "Bukaera data/ordua",
"cronExpression": "Cron espresioa",
"cronSchedule": "Programatu: ",
"invalidCronExpression": "Cron espresio baliogabea: {0}",
"recurringInterval": "Tartea",
"No Maintenance": "Mantenurik ez",
"maintenanceStatus-under-maintenance": "Mantenuan",
"maintenanceStatus-inactive": "Aktibatu gabe",
"maintenanceStatus-scheduled": "Programatuta",
"Display Timezone": "Erakutsi ordu zona",
"statusPageMaintenanceEndDate": "Bukatu",
"IconUrl": "Ikono URLa",
"chromeExecutableAutoDetect": "Auto detektatu",
"Schedule Maintenance": "Programatu mantenua",
"Edit Maintenance": "Editatu mantenua",
"Date and Time": "Data eta ordua",
"plugin": "Plugin | Pluginak",
"installing": "Instalatzen",
"uninstalling": "Desinstalatzen",
"confirmUninstallPlugin": "Ziur zaude plugin hau desinstalatu nahi duzula?",
"Clone": "Klonatu",
"cloneOf": "{0}-(a)ren klona",
"emailTemplateStatus": "Egoera",
"emailTemplateMsg": "jakinarazpenaren mezua",
"Select message type": "Hautatu mezu mota",
"Send to channel": "Bidali kanalera",
"Enable TLS": "Gaitu TLS",
"webhookAdditionalHeadersTitle": "Goiburu gehigarriak",
"Reset Token": "Berrezarri tokena",
"selectedMonitorCount": "Hautatuta: {0}",
"HTTP Headers": "HTTP goiburuak",
"Refresh Interval": "Eguneratze tartea",
"tcp": "TCP / HTTP",
"Notification Service": "Jakinarazpen zerbitzua",
"or": "edo",
"startDateTime": "Hasiera data/ordua",
"pauseMaintenanceMsg": "Ziur zaude gelditu nahi duzula?",
"install": "Instalatu",
"uninstall": "Desinstalatu",
"emailTemplateServiceName": "Zerbitzu izena",
"Your User ID": "Zure erabiltzaile IDa",
"Connection Type": "Konexio mota",
"pushOthers": "Besteak",
"programmingLanguages": "Programatze lengoaiak",
"dbName": "Datubase izena",
"resendEveryXTimes": "Berbidali {0} aldiz",
"Reconnecting...": "Birkonektatzen...",
"setupDatabaseChooseDatabase": "Zein datubase erabili nahi duzu?",
"Recurring": "Errepikakorra",
"Mentioning": "Aipatzen",
"Condition": "Baldintza",
"RabbitMQ Username": "RabbitMQ erabiltzailea",
"Expiry": "Iraungitzea",
"pagertreeSilent": "Isildu",
"Group": "Taldea",
"Saved.": "Gordeta.",
"Conditions": "Baldintzak",
"smseagleTo": "Telefono zenbakia(k)",
"Enable Kafka SSL": "Gaitu Kafka SSL",
"Continue": "Jarraitu",
"apiKey-active": "Aktibo",
"apiKey-expired": "Iraungita",
"apiKey-inactive": "Ez-aktibo",
"Expires": "Iraungitzen da",
"Generate": "Sortu",
"pagertreeUrgency": "Larritasuna",
"pagertreeLow": "Baxua",
"pagertreeHigh": "Altua",
"pagertreeCritical": "Larria",
"Destination": "Helburua",
"conditionValuePlaceholder": "Balioa",
"RabbitMQ Password": "RabbitMQ pasahitza",
"Correct": "Zuzena",
"Fail": "Akatsa",
"Elevator": "Igogailua",
"Guitar": "Gitarra",
"pagertreeMedium": "Ertaina",
"Host URL": "Host URLa",
"Affected Monitors": "Kaltetutako monitoreak",
"Pick Affected Monitors...": "Hautatu kaltetutako monitoreakтАж",
"deleteMaintenanceMsg": "Ziur zaude mantentze lan hau ezabatu nahi duzula?",
"smseagleEncoding": "Unicode gisa bidali",
"Add Another": "Gehitu beste bat",
"Google Analytics ID": "Google Analytics IDa",
"Edit Tag": "Editatu etiketa",
"PushDeer Server": "PushDeer zerbitzaria",
"Show Clickable Link": "Erakutsi lotura klikagarria",
"twilioToNumber": "zenbakira",
"twilioFromNumber": "zenbakitik",
"ntfyUsernameAndPassword": "Erabiltzailea eta pasahitza",
"lunaseaUserID": "Erabiltzaile IDa",
"pagertreeDoNothing": "Ez egin ezer",
"Separate multiple email addresses with commas": "Banatu email helbideak koma ikurrekin",
"settingUpDatabaseMSG": "Datubasea ezartzen. Denbora pixka bat iraun dezake, pazientzia eduki."
} }

View File

@@ -351,7 +351,7 @@
"statusPageRefreshIn": "╪к╪з ╪и╪з╪▒┌п╪░╪з╪▒█М ┘Е╪м╪п╪п:тАМ {0}", "statusPageRefreshIn": "╪к╪з ╪и╪з╪▒┌п╪░╪з╪▒█М ┘Е╪м╪п╪п:тАМ {0}",
"Content Type": "┘Ж┘И╪╣ ┘Е╪н╪к┘И╪з (Content Type)", "Content Type": "┘Ж┘И╪╣ ┘Е╪н╪к┘И╪з (Content Type)",
"Server URL": "╪в╪п╪▒╪│ ╪│╪▒┘И╪▒", "Server URL": "╪в╪п╪▒╪│ ╪│╪▒┘И╪▒",
"Priority": "╪з┘И┘Д┘И█М╪к", "Priority": "╪з┘З┘Е█М╪к",
"emojiCheatSheet": "┌Ж█М╪к ╪┤█М╪к ╪з█М┘Е┘И╪м█М ┘З╪з:тАМ {0}", "emojiCheatSheet": "┌Ж█М╪к ╪┤█М╪к ╪з█М┘Е┘И╪м█М ┘З╪з:тАМ {0}",
"Read more": "╪и█М╪┤╪к╪▒ ╪и╪п╪з┘Ж█М╪п", "Read more": "╪и█М╪┤╪к╪▒ ╪и╪п╪з┘Ж█М╪п",
"webhookJsonDesc": "{0} ╪и╪▒╪з█М ┘З╪▒ HTTP ╪│╪▒┘И╪▒ ╪м╪п█М╪п█М ┘Е╪з┘Ж┘Ж╪п Express.js ┘Е┘Ж╪з╪│╪и ╪з╪│╪к", "webhookJsonDesc": "{0} ╪и╪▒╪з█М ┘З╪▒ HTTP ╪│╪▒┘И╪▒ ╪м╪п█М╪п█М ┘Е╪з┘Ж┘Ж╪п Express.js ┘Е┘Ж╪з╪│╪и ╪з╪│╪к",
@@ -642,7 +642,7 @@
"Push URL": "URL ┘╛┘И╪┤", "Push URL": "URL ┘╛┘И╪┤",
"Schedule maintenance": "╪▓┘Е╪з┘Ж╪и┘Ж╪п█М ┘Ж┌п┘З╪п╪з╪▒█М (╪║█М╪▒┘Б╪╣╪з┘Д ╪│╪з╪▓█М ╪п╪│╪к█М)", "Schedule maintenance": "╪▓┘Е╪з┘Ж╪и┘Ж╪п█М ┘Ж┌п┘З╪п╪з╪▒█М (╪║█М╪▒┘Б╪╣╪з┘Д ╪│╪з╪▓█М ╪п╪│╪к█М)",
"webhookFormDataDesc": "{multipart} ╪и╪▒╪з█М PHP ┘Е┘Ж╪з╪│╪и ╪з╪│╪к. ╪в╪▒╪з█М┘З JSON ┘Ж█М╪з╪▓ ╪з╪│╪к ╪к╪з ╪и┘З ╪з█М┘Ж ╪┤┌й┘Д ╪и╪з╪▓ ╪┤┘И╪п {decodeFunction}", "webhookFormDataDesc": "{multipart} ╪и╪▒╪з█М PHP ┘Е┘Ж╪з╪│╪и ╪з╪│╪к. ╪в╪▒╪з█М┘З JSON ┘Ж█М╪з╪▓ ╪з╪│╪к ╪к╪з ╪и┘З ╪з█М┘Ж ╪┤┌й┘Д ╪и╪з╪▓ ╪┤┘И╪п {decodeFunction}",
"webhookAdditionalHeadersTitle": "┘З╪п╪▒┘З╪з█М ╪з╪╢╪з┘Б█М", "webhookAdditionalHeadersTitle": "┘З╪п╪▒ ╪з╪╢╪з┘Б█М",
"webhookAdditionalHeadersDesc": "╪к┘Ж╪╕█М┘Е ┘З╪п╪▒ ┘З╪з█М ╪з╪╢╪з┘Б█М ┌й┘З ┘Ж█М╪з╪▓ ╪з╪│╪к ╪и╪з ┘И╪и ┘З┘И┌й ╪з╪▒╪│╪з┘Д ╪┤┘И╪п. ┘З╪▒ ┘З╪п╪▒ ╪и╪з█М╪п ╪и┘З ┌й█М┘Д╪п/┘Е┘В╪п╪з╪▒ JSON ╪к╪╣╪▒█М┘Б ╪┤╪п┘З ╪и╪з╪┤╪п.", "webhookAdditionalHeadersDesc": "╪к┘Ж╪╕█М┘Е ┘З╪п╪▒ ┘З╪з█М ╪з╪╢╪з┘Б█М ┌й┘З ┘Ж█М╪з╪▓ ╪з╪│╪к ╪и╪з ┘И╪и ┘З┘И┌й ╪з╪▒╪│╪з┘Д ╪┤┘И╪п. ┘З╪▒ ┘З╪п╪▒ ╪и╪з█М╪п ╪и┘З ┌й█М┘Д╪п/┘Е┘В╪п╪з╪▒ JSON ╪к╪╣╪▒█М┘Б ╪┤╪п┘З ╪и╪з╪┤╪п.",
"Webhook URL": "╪в╪п╪▒╪│ ┘И╪и ┘З┘И┌й", "Webhook URL": "╪в╪п╪▒╪│ ┘И╪и ┘З┘И┌й",
"Application Token": "╪к┘И┌й┘Ж ╪з┘╛┘Д█М┌й█М╪┤┘Ж", "Application Token": "╪к┘И┌й┘Ж ╪з┘╛┘Д█М┌й█М╪┤┘Ж",
@@ -1020,53 +1020,5 @@
"OAuth Token URL": "URL ╪к┘И┌й┘Ж OAuth", "OAuth Token URL": "URL ╪к┘И┌й┘Ж OAuth",
"OAuth Scope": "╪з╪│┌й┘И┘╛ OAuth", "OAuth Scope": "╪з╪│┌й┘И┘╛ OAuth",
"Optional: Space separated list of scopes": "╪з╪о╪к█М╪з╪▒█М: ┘Д█М╪│╪к ╪м╪п╪з ╪┤╪п┘З ╪и╪з ┘Б╪з╪╡┘Д┘З ╪з╪▓ ╪з╪│┌й┘И┘╛тАМ┘З╪з", "Optional: Space separated list of scopes": "╪з╪о╪к█М╪з╪▒█М: ┘Д█М╪│╪к ╪м╪п╪з ╪┤╪п┘З ╪и╪з ┘Б╪з╪╡┘Д┘З ╪з╪▓ ╪з╪│┌й┘И┘╛тАМ┘З╪з",
"signl4Docs": "╪┤┘Е╪з ┘Е█МтАМ╪к┘И╪з┘Ж█М╪п ╪з╪╖┘Д╪з╪╣╪з╪к ╪и█М╪┤╪к╪▒ ╪п╪▒ ╪▒╪з╪и╪╖┘З ╪и╪з ┘Ж╪н┘И┘З ╪к┘Ж╪╕█М┘Е SIGNL4 ┘И ╪и┘З ╪п╪│╪к ╪в┘И╪▒╪п┘Ж URL ┘И╪итАМ┘З┘И┌й SIGNL4 ╪▒╪з ╪п╪▒ {0} ┘╛█М╪п╪з ┌й┘Ж█М╪п.", "signl4Docs": "╪┤┘Е╪з ┘Е█МтАМ╪к┘И╪з┘Ж█М╪п ╪з╪╖┘Д╪з╪╣╪з╪к ╪и█М╪┤╪к╪▒ ╪п╪▒ ╪▒╪з╪и╪╖┘З ╪и╪з ┘Ж╪н┘И┘З ╪к┘Ж╪╕█М┘Е SIGNL4 ┘И ╪и┘З ╪п╪│╪к ╪в┘И╪▒╪п┘Ж URL ┘И╪итАМ┘З┘И┌й SIGNL4 ╪▒╪з ╪п╪▒ {0} ┘╛█М╪п╪з ┌й┘Ж█М╪п."
"ignoredTLSError": "╪о╪╖╪з┘З╪з█М TLS/SSL ┘Ж╪з╪п█М╪п┘З ┌п╪▒┘Б╪к┘З ┘Е█М╪┤┘И╪п",
"Bubble": "╪н╪и╪з╪и",
"Message format": "╪│╪з╪о╪к╪з╪▒ ┘╛█М╪з┘Е",
"Notification Channel": "┌й╪з┘Ж╪з┘Д ╪з╪╖┘Д╪з╪╣тАМ╪▒╪│╪з┘Ж█М",
"Doorbell": "╪▓┘Ж┌п",
"The phone number of the recipient in E.164 format.": "╪┤┘Е╪з╪▒┘З ╪к┘Д┘Б┘Ж ┌п█М╪▒┘Ж╪п┘З ╪и┘З ┘Б╪▒┘Е╪к E.164.",
"Sound": "╪╡╪п╪з",
"Correct": "╪п╪▒╪│╪к",
"Reveal": "┘Ж┘Е╪з█М╪┤",
"Flute": "┘Б┘Д┘И╪к",
"Money": "┘╛┘И┘Д",
"Scifi": "╪╣┘Д┘Е█МтАМ╪к╪о█М┘Д█М",
"Elevator": "╪в╪│╪з┘Ж╪│┘И╪▒",
"Guitar": "┌п█М╪к╪з╪▒",
"Pop": "┘╛╪з┘╛",
"From": "╪з╪▓",
"telegramServerUrl": "(╪з╪о╪к█М╪з╪▒█М) ╪в╪п╪▒╪│ ╪│╪▒┘И╪▒",
"telegramServerUrlDescription": "╪и╪▒╪з█М ┌й╪з┘З╪┤ ┘Е╪н╪п┘И╪п█М╪ктАМ┘З╪з█М ╪и╪з╪к ╪к┘Д┌п╪▒╪з┘Е █М╪з ╪п╪│╪к╪▒╪│█М ╪п╪▒ ┘Е┘Ж╪з╪╖┘В█М ┌й┘З ╪к┘Д┌п╪▒╪з┘Е ┘Б█М┘Д╪к╪▒ ╪┤╪п┘З ╪з╪│╪к (┘Е╪л┘Д ╪з█М╪▒╪з┘Ж █М╪з ┌Ж█М┘Ж ┘И ...). ╪и╪▒╪з█М ╪з╪╖┘Д╪з╪╣╪з╪к ╪и█М╪┤╪к╪▒ {0} ╪▒╪з ╪и╪и█М┘Ж█М╪п. ┘Е┘В╪п╪з╪▒ ┘╛█М╪┤┘Б╪▒╪╢: {1}",
"Alphanumerical string and hyphens only": "┘Б┘В╪╖ ╪н╪▒┘И┘Б ╪з┘Д┘Б╪и╪з╪М ╪з╪╣╪п╪з╪п ┘И -",
"Time sensitive notifications will be delivered immediately, even if the device is in do not disturb mode.": "╪з╪╣┘Д╪з┘ЖтАМ┘З╪з█М ╪н╪│╪з╪│ ╪и┘З ╪▓┘Е╪з┘Ж ╪п╪▒ ┘Д╪н╪╕┘З ╪з╪▒╪│╪з┘Д ╪о┘И╪з┘З┘Ж╪п ╪┤╪п╪М ╪н╪к█М ╪з┌п╪▒ ╪п╪│╪к┌п╪з┘З ╪п╪▒ ╪н╪з┘Д╪к ╪и╪п┘И┘Ж ┘Е╪▓╪з╪н┘Е╪к ┘В╪▒╪з╪▒ ╪п╪з╪┤╪к┘З ╪и╪з╪┤╪п.",
"rabbitmqNodesRequired": "┘Д╪╖┘Б╪з ┌п╪▒┘ЗтАМ┘З╪з█М ╪з█М┘Ж ┘╛╪з█М╪┤тАМ┌п╪▒ ╪▒╪з ╪к┘Ж╪╕█М┘Е ┌й┘Ж█М╪п.",
"RabbitMQ Password": "┌п╪░╪▒┘И╪з┌Ш┘З RabbitMQ",
"RabbitMQ Nodes": "┌п╪▒┘ЗтАМ┘З╪з█М ┘Е╪п█М╪▒█М╪к RabbitMQ",
"rabbitmqHelpText": "╪и╪▒╪з█М ┘╛╪з█М╪┤╪М ┘Д╪з╪▓┘Е ╪з╪│╪к ╪з┘Б╪▓┘И┘Ж┘З ┘Е╪п█М╪▒█М╪к (Management) ╪п╪▒ RabbitMQ ╪▒╪з ┘Б╪╣╪з┘Д ┌й┘Ж█М╪п. ╪и╪▒╪з█М ╪з╪╖┘Д╪з╪╣╪з╪к ╪и█М╪┤╪к╪▒ ╪и┘З {rabitmq_documentation} ┘Е╪▒╪з╪м╪╣┘З ┌й┘Ж█М╪п.",
"wayToWriteWahaChatId": "╪┤┘Е╪з╪▒┘З ┘Е┘И╪и╪з█М┘Д ╪п╪▒ ┘В╪з┘Д╪и ╪и█М┘ЖтАМ╪з┘Д┘Е┘Д┘Д█М ┘И ╪и╪п┘И┘Ж ╪╣┘Д╪з┘Е╪к ┘Е╪л╪и╪к ╪з╪и╪к╪п╪з█М█М ({0})╪М ╪┤┘Ж╪з╪│┘З ┘Е╪о╪з╪╖╪и ({1}) █М╪з ╪┤┘Ж╪з╪│┘З ┌п╪▒┘И┘З ({2}). ╪з╪╣┘Д╪з┘ЖтАМ┘З╪з ╪з╪▓ ┘Ж╪┤╪│╪к WAHA ╪и┘З ╪з█М┘Ж ╪┤┘Ж╪з╪│┘З ┌п┘Б╪к┌п┘И ╪з╪▒╪│╪з┘Д ╪о┘И╪з┘З┘Ж╪п ╪┤╪п.",
"wahaSession": "┘Ж╪┤╪│╪к",
"wahaChatId": "╪┤┘Ж╪з╪│┘З ┌п┘Б╪к┌п┘И (╪┤┘Е╪з╪▒┘З ┘Е┘И╪и╪з█М┘Д / ╪┤┘Ж╪з╪│┘З ┘Е╪о╪з╪╖╪и / ╪┤┘Ж╪з╪│┘З ┌п╪▒┘И┘З)",
"wayToGetWahaSession": "╪и╪з ╪з█М┘Ж ┘Ж╪┤╪│╪к WAHA ╪з╪╣┘Д╪з┘ЖтАМ┘З╪з ╪▒╪з ╪и┘З ╪┤┘Ж╪з╪│┘З ┌п┘Б╪к┌п┘И ╪з╪▒╪│╪з┘Д ┘Е█М┌й┘Ж╪п. ┘В╪з╪и┘Д ┘Е╪┤╪з┘З╪п┘З ╪п╪▒ ┘╛┘Ж┘Д ┌й╪з╪▒╪и╪▒█М WAHA.",
"Message Template": "┘В╪з┘Д╪и ┘╛█М╪з┘Е",
"Template Format": "┘Б╪▒┘Е╪к ┘В╪з┘Д╪и",
"YZJ Webhook URL": "╪в╪п╪▒╪│ ┘И╪итАМ┘З┘И┌й YZJ",
"Fail": "╪┤┌й╪│╪к",
"Custom sound to override default notification sound": "┘Ж┘И╪з█М ╪п┘Д╪о┘И╪з┘З ╪и┘З ╪м╪з█М ┘Ж┘И╪з█М ┘╛█М╪┤┘Б╪▒╪╢ ╪з╪╣┘Д╪з┘Ж",
"Time Sensitive (iOS Only)": "╪н╪│╪з╪│ ╪и┘З ╪▓┘Е╪з┘Ж (┘Б┘В╪╖ iOS)",
"Can be found on:": "╪п╪▒ {0} █М╪з┘Б╪к ┘Е█М╪┤┘И╪п",
"Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "╪┤┘Ж╪з╪│┘З ╪з╪▒╪│╪з┘Д ┌й┘Ж┘Ж╪п┘З ┘Е╪к┘Ж█М ┘И ╪п╪▒ ╪╡┘И╪▒╪к█М ┌й┘З ┘Е█М╪о┘И╪з┘З█М╪п ┘╛╪з╪│╪отАМ┘З╪з ╪▒╪з ╪п╪▒█М╪з┘Б╪к ┌й┘Ж█М╪п╪М ╪┤┘Е╪з╪▒┘З ┘Е┘И╪и╪з█М┘Д ╪п╪▒ ┘В╪з┘Д╪и E.164.",
"rabbitmqNodesDescription": "╪в╪п╪▒╪│ ┌п╪▒┘ЗтАМ┘З╪з█М ┘Е╪п█М╪▒█М╪к RabbitMQ ╪▒╪з ╪и┘З ┘З┘Е╪▒╪з┘З ┘╛╪▒┘И╪к┌й┘Д ┘И ╪┤┘Е╪з╪▒┘З ┘╛┘И╪▒╪к ┘И╪з╪▒╪п ┌й┘Ж█М╪п. ┘Е╪л╪з┘Д: {0}",
"RabbitMQ Username": "┘Ж╪з┘Е ┌й╪з╪▒╪и╪▒█М RabbitMQ",
"Separate multiple email addresses with commas": "╪в╪п╪▒╪│тАМ┘З╪з█М ╪з█М┘Е█М┘Д ╪▒╪з ╪и╪з ╪з╪│╪к┘Б╪з╪п┘З ╪з╪▓ ┘И█М╪▒┌п┘И┘Д ╪з┘Ж┌п┘Д█М╪│█М █М╪з ┌й╪з┘Е╪з ╪м╪п╪з ┌й┘Ж█М╪п",
"Plain Text": "┘Е╪к┘Ж ╪│╪з╪п┘З",
"aboutSlackUsername": "┘Ж╪з┘Е ┘Ж┘Е╪з█М╪┤█М ╪з╪▒╪│╪з┘Д ┌й┘Ж┘Ж╪п┘З ┘╛█М╪з┘Е ╪▒╪з ╪к╪║█М█М╪▒ ┘Е█М╪п┘З╪п. ╪з┌п╪▒ ┘Е█М╪о┘И╪з┘З█М╪п ╪┤╪о╪╡█М ╪▒╪з ┘Ж╪з┘Е ╪и╪и╪▒█М╪п╪М ╪п╪▒ ┘В╪│┘Е╪к ┘Ж╪з┘Е ╪п┘И╪│╪к╪з┘Ж┘З ╪и┘Ж┘И█М╪│█М╪п.",
"Clear": "┘╛╪з┌йтАМ╪│╪з╪▓█М",
"templateServiceName": "┘Ж╪з┘Е ╪о╪п┘Е╪к",
"templateHostnameOrURL": "╪в╪п╪▒╪│ █М╪з ┘Ж╪з┘Е ┘Е█М╪▓╪и╪з┘Ж",
"templateStatus": "┘И╪╢╪╣█М╪к",
"telegramUseTemplate": "╪з╪│╪к┘Б╪з╪п┘З ╪з╪▓ ┘В╪з┘Д╪и ┘╛█М╪з┘Е ╪п┘Д╪о┘И╪з┘З",
"telegramUseTemplateDescription": "╪п╪▒ ╪╡┘И╪▒╪к ┘Б╪╣╪з┘ДтАМ╪│╪з╪▓█М╪М ┘╛█М╪з┘Е ╪и╪з ┘В╪з┘Д╪и ╪п┘Д╪о┘И╪з┘З ╪з╪▒╪│╪з┘Д ╪о┘И╪з┘З╪п ╪┤╪п.",
"telegramTemplateFormatDescription": "╪п╪▒ ╪к┘Д┌п╪▒╪з┘Е ╪з┘Е┌й╪з┘Ж ╪з╪│╪к┘Б╪з╪п┘З ╪з╪▓ ╪▓╪и╪з┘ЖтАМ┘З╪з█М ┘Ж╪┤╪з┘Ж┘ЗтАМ┌п╪░╪з╪▒█М ┘Е╪о╪к┘Д┘Б█М ┘И╪м┘И╪п ╪п╪з╪▒╪п╪М ╪и╪▒╪з█М ╪м╪▓╪ж█М╪з╪к ╪и█М╪┤╪к╪▒ {0} ╪▒╪з ╪и╪и█М┘Ж█М╪п."
} }

View File

@@ -1086,15 +1086,5 @@
"The phone number of the recipient in E.164 format.": "Vastaanottajan puhelinnumero E.164-muodossa.", "The phone number of the recipient in E.164 format.": "Vastaanottajan puhelinnumero E.164-muodossa.",
"Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "Joko l├дhett├дj├дtunnus (sender ID) tai puhelinnumero E-164-muodossa jos haluat pysty├д vastaanottamaan vastausviestej├д.", "Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "Joko l├дhett├дj├дtunnus (sender ID) tai puhelinnumero E-164-muodossa jos haluat pysty├д vastaanottamaan vastausviestej├д.",
"Scifi": "Tieteisseikkailu", "Scifi": "Tieteisseikkailu",
"Pop": "Poksahdus", "Pop": "Poksahdus"
"rabbitmqNodesRequired": "Aseta t├дm├дn seuraimen solmut.",
"rabbitmqNodesInvalid": "K├дyt├д RabbitMQ-solmuille t├дysin hyv├дksytty├д ('http' alkavaa) URL-osoitetta.",
"RabbitMQ Username": "RabbitMQ K├дytt├дj├дnimi",
"RabbitMQ Password": "RabbitMQ Salasana",
"SendGrid API Key": "SendGrid API-avain",
"Separate multiple email addresses with commas": "Erottele useammat s├дhk├╢postiosoitteet pilkuilla",
"RabbitMQ Nodes": "RabbitMQ-hallintasolmut",
"rabbitmqNodesDescription": "Anna URL RabbitMQ-hallintasolmuille sis├дlt├дen protokollan ja portin. Esimerkki: {0}",
"rabbitmqHelpText": "Jotta voit k├дytt├д├д seurainta, sinun on otettava hallintalaajennus k├дytt├╢├╢n RabbitMQ-asetuksissa. Lis├дtietoja saat osoitteesta {rabitmq_documentation}.",
"aboutSlackUsername": "Muuttaa viestin l├дhett├дj├дn n├дytt├╢nime├д. Jos haluat mainita jonkun, lis├д├д se yst├дv├дlliseen nimeen."
} }

View File

@@ -4,7 +4,7 @@
"retryCheckEverySecond": "R├йessayer toutes les {0} secondes", "retryCheckEverySecond": "R├йessayer toutes les {0} secondes",
"resendEveryXTimes": "Renvoyez toutes les {0} fois", "resendEveryXTimes": "Renvoyez toutes les {0} fois",
"resendDisabled": "Renvoi d├йsactiv├й", "resendDisabled": "Renvoi d├йsactiv├й",
"retriesDescription": "Nombre de tentatives avant que le service ne soit d├йclar├й hors ligne et qu'une notification soit envoy├йe", "retriesDescription": "Nombre d'essais avant que le service ne soit d├йclar├й hors ligne et qu'une notification soit envoy├йe",
"ignoreTLSError": "Ignorer les erreurs li├йes au certificat SSL/TLS", "ignoreTLSError": "Ignorer les erreurs li├йes au certificat SSL/TLS",
"upsideDownModeDescription": "Si le service est en ligne, il sera alors not├й hors ligne et vice-versa.", "upsideDownModeDescription": "Si le service est en ligne, il sera alors not├й hors ligne et vice-versa.",
"maxRedirectDescription": "Nombre maximal de redirections avant que le service ne soit marqu├й comme hors ligne.", "maxRedirectDescription": "Nombre maximal de redirections avant que le service ne soit marqu├й comme hors ligne.",
@@ -87,8 +87,8 @@
"Hostname": "Nom d'h├┤te / adresse IP", "Hostname": "Nom d'h├┤te / adresse IP",
"Port": "Port", "Port": "Port",
"Heartbeat Interval": "Intervalle de v├йrification", "Heartbeat Interval": "Intervalle de v├йrification",
"Retries": "Tentatives", "Retries": "Essais",
"Heartbeat Retry Interval": "Intervalle entre chaque nouvelle tentative", "Heartbeat Retry Interval": "Intervalle de r├й-essai",
"Resend Notification if Down X times consecutively": "Renvoyer la notification si hors ligne X fois cons├йcutivement", "Resend Notification if Down X times consecutively": "Renvoyer la notification si hors ligne X fois cons├йcutivement",
"Advanced": "Avanc├й", "Advanced": "Avanc├й",
"Upside Down Mode": "Mode invers├й", "Upside Down Mode": "Mode invers├й",
@@ -310,7 +310,7 @@
"lineDevConsoleTo": "Console d├йveloppeurs Line - {0}", "lineDevConsoleTo": "Console d├йveloppeurs Line - {0}",
"Basic Settings": "Param├иtres de base", "Basic Settings": "Param├иtres de base",
"User ID": "Identifiant utilisateur", "User ID": "Identifiant utilisateur",
"Messaging API": "API de messagerie", "Messaging API": "Messaging API",
"wayToGetLineChannelToken": "Premi├иrement acc├йdez ├а {0}, cr├йez un <i>provider</i> et d├йfinissez un type de salon ├а ┬лMessaging API┬╗. Vous obtiendrez alors le jeton d'acc├иs du salon et l'identifiant utilisateur demand├йs.", "wayToGetLineChannelToken": "Premi├иrement acc├йdez ├а {0}, cr├йez un <i>provider</i> et d├йfinissez un type de salon ├а ┬лMessaging API┬╗. Vous obtiendrez alors le jeton d'acc├иs du salon et l'identifiant utilisateur demand├йs.",
"Icon URL": "URL vers l'ic├┤ne", "Icon URL": "URL vers l'ic├┤ne",
"aboutIconURL": "Vous pouvez mettre un lien vers une image dans ┬л┬аURL vers l'ic├┤ne┬а┬╗ pour remplacer l'image de profil par d├йfaut. Elle ne sera utilis├й que si ┬л┬аIc├┤ne ├йmoji┬а┬╗ n'est pas d├йfini.", "aboutIconURL": "Vous pouvez mettre un lien vers une image dans ┬л┬аURL vers l'ic├┤ne┬а┬╗ pour remplacer l'image de profil par d├йfaut. Elle ne sera utilis├й que si ┬л┬аIc├┤ne ├йmoji┬а┬╗ n'est pas d├йfini.",
@@ -455,7 +455,7 @@
"Huawei": "Huawei", "Huawei": "Huawei",
"High": "Haute", "High": "Haute",
"Retry": "Recommencez", "Retry": "Recommencez",
"Topic": "Sujet", "Topic": "Topic",
"WeCom Bot Key": "Cl├й de robot WeCom", "WeCom Bot Key": "Cl├й de robot WeCom",
"Setup Proxy": "Configurer le proxy", "Setup Proxy": "Configurer le proxy",
"Proxy Protocol": "Protocole proxy", "Proxy Protocol": "Protocole proxy",
@@ -517,7 +517,7 @@
"Domain Names": "Noms de domaine", "Domain Names": "Noms de domaine",
"signedInDisp": "Connect├й en tant que {0}", "signedInDisp": "Connect├й en tant que {0}",
"signedInDispDisabled": "Authentification d├йsactiv├йe.", "signedInDispDisabled": "Authentification d├йsactiv├йe.",
"RadiusSecret": "Secret Radius", "RadiusSecret": "Radius Secret",
"RadiusSecretDescription": "Secret partag├й entre le client et le serveur", "RadiusSecretDescription": "Secret partag├й entre le client et le serveur",
"RadiusCalledStationId": "Identifiant de la station appel├йe", "RadiusCalledStationId": "Identifiant de la station appel├йe",
"RadiusCalledStationIdDescription": "Identifiant de l'appareil appel├й", "RadiusCalledStationIdDescription": "Identifiant de l'appareil appel├й",
@@ -826,7 +826,7 @@
"nostrSender": "├Йmetteur cl├й priv├йe (nsec)", "nostrSender": "├Йmetteur cl├й priv├йe (nsec)",
"nostrRecipientsHelp": "Format npub, un par ligne", "nostrRecipientsHelp": "Format npub, un par ligne",
"nostrRelays": "Relais Nostr", "nostrRelays": "Relais Nostr",
"PushDeer Server": "Serveur PushDeer", "PushDeer Server": "PushDeer Server",
"showCertificateExpiry": "Afficher l'expiration du certificat", "showCertificateExpiry": "Afficher l'expiration du certificat",
"noOrBadCertificate": "Pas/Mauvais certificat", "noOrBadCertificate": "Pas/Mauvais certificat",
"pushDeerServerDescription": "Laissez le champ vide pour utiliser le serveur officiel", "pushDeerServerDescription": "Laissez le champ vide pour utiliser le serveur officiel",
@@ -1088,34 +1088,5 @@
"From": "De", "From": "De",
"Can be found on:": "Disponible sur┬а:┬а{0}", "Can be found on:": "Disponible sur┬а:┬а{0}",
"The phone number of the recipient in E.164 format.": "Le num├йro de t├йl├йphone du destinataire au format E.164.", "The phone number of the recipient in E.164 format.": "Le num├йro de t├йl├йphone du destinataire au format E.164.",
"Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "Soit un identifiant d'exp├йditeur de texte, soit un num├йro de t├йl├йphone au format E.164 si vous souhaitez pouvoir recevoir des r├йponses.", "Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "Soit un identifiant d'exp├йditeur de texte, soit un num├йro de t├йl├йphone au format E.164 si vous souhaitez pouvoir recevoir des r├йponses."
"RabbitMQ Nodes": "N┼Уuds de gestion RabbitMQ",
"rabbitmqNodesDescription": "Entrez l'URL des n┼Уuds de gestion RabbitMQ, y compris le protocole et le port. Exemple┬а:┬а{0}",
"rabbitmqNodesRequired": "Veuillez d├йfinir les n┼Уuds pour cette sonde.",
"rabbitmqNodesInvalid": "Veuillez utiliser une URL compl├иte (commen├зant par ┬л http ┬╗) pour les n┼Уuds RabbitMQ.",
"RabbitMQ Username": "Nom d'utilisateur RabbitMQ",
"RabbitMQ Password": "Mot de passe RabbitMQ",
"rabbitmqHelpText": "Pour utiliser la sonde, vous devrez activer le plug-in de gestion dans votre configuration RabbitMQ. Pour plus d'informations, veuillez consulter la {rabitmq_documentation}.",
"SendGrid API Key": "Cl├й API SendGrid",
"Separate multiple email addresses with commas": "S├йparez plusieurs adresses e-mail par des virgules",
"aboutSlackUsername": "Modifie le nom d'affichage de l'exp├йditeur du message. Si vous souhaitez mentionner quelquтАЩun, incluez-le plut├┤t dans le nom convivial.",
"templateHostnameOrURL": "Nom d'h├┤te ou URL",
"telegramUseTemplate": "Utiliser un mod├иle de message personnalis├й",
"telegramTemplateFormatDescription": "Telegram permet d'utiliser diff├йrents langages de balisage pour les messages, voir Telegram {0} pour plus de d├йtails.",
"Plain Text": "Texte brut",
"YZJ Webhook URL": "URL du webhook YZJ",
"YZJ Robot Token": "Jeton robot YZJ",
"templateServiceName": "Nom du service",
"templateStatus": "Status",
"telegramUseTemplateDescription": "Si cette option est activ├йe, le message sera envoy├й ├а l'aide d'un mod├иle personnalis├й.",
"Message Template": "Mod├иle de message",
"Template Format": "Format du mod├иle",
"wayToGetWahaApiUrl": "LтАЩURL de votre instance WAHA.",
"wayToGetWahaSession": "├А partir de cette session, WAHA envoie des notifications ├а l'ID de discussion. Vous pouvez le trouver dans le tableau de bord WAHA.",
"wahaSession": "Session",
"wahaChatId": "ID de discussion (num├йro de t├йl├йphone / ID de contact / ID de groupe)",
"wayToGetWahaApiKey": "La cl├й API est la valeur de la variable d'environnement WHATSAPP_API_KEY que vous avez utilis├йe pour ex├йcuter WAHA.",
"wayToWriteWahaChatId": "Le num├йro de t├йl├йphone avec le pr├йfixe international, mais sans le signe plus ({0}), l'identifiant de contact ({1}) ni l'identifiant de groupe ({2}). Les notifications sont envoy├йes ├а cet identifiant de chat depuis la session WAHA.",
"telegramServerUrlDescription": "Pour lever les limitations de lтАЩAPI des bots Telegram ou acc├йder aux zones bloqu├йes (Chine, Iran, etc.). Pour plus dтАЩinformations, cliquez sur {0}. Par d├йfaut : {1}",
"telegramServerUrl": "(Facultatif) URL du serveur"
} }

View File

@@ -976,7 +976,7 @@
"SNMP Version": "Leagan SNMP", "SNMP Version": "Leagan SNMP",
"Please enter a valid OID.": "Cuir isteach OID bail├н.", "Please enter a valid OID.": "Cuir isteach OID bail├н.",
"Host Onesender": "├Уstach Onesender", "Host Onesender": "├Уstach Onesender",
"Token Onesender": "Lic├нn Onesender", "Token Onesender": "Token Onesender",
"Recipient Type": "Cine├бl Faighteoir", "Recipient Type": "Cine├бl Faighteoir",
"Private Number": "Uimhir Phr├нobh├бideach", "Private Number": "Uimhir Phr├нobh├бideach",
"privateOnesenderDesc": "Cinntigh go bhfuil an uimhir theileaf├│in bail├н. Chun teachtaireacht a sheoladh chuig uimhir ghuth├бin phr├нobh├бideach, sean: 628123456789", "privateOnesenderDesc": "Cinntigh go bhfuil an uimhir theileaf├│in bail├н. Chun teachtaireacht a sheoladh chuig uimhir ghuth├бin phr├нobh├бideach, sean: 628123456789",
@@ -1016,42 +1016,5 @@
"greater than": "n├нos m├│ n├б", "greater than": "n├нos m├│ n├б",
"less than or equal to": "n├нos l├║ n├б n├│ cothrom le", "less than or equal to": "n├нos l├║ n├б n├│ cothrom le",
"record": "taifead", "record": "taifead",
"shrinkDatabaseDescriptionSqlite": "Bunachar sonra├н truicear {vacuum} le haghaidh SQLite. T├б {auto_vacuum} cumasaithe cheana f├йin ach n├н dh├йanann s├й seo scoilt ar an mbunachar sonra├н n├б athphac├бil leathanaigh aonair an bhunachair sonra├н mar a dh├йanann an t-ord├║ {vacuum}.", "shrinkDatabaseDescriptionSqlite": "Bunachar sonra├н truicear {vacuum} le haghaidh SQLite. T├б {auto_vacuum} cumasaithe cheana f├йin ach n├н dh├йanann s├й seo scoilt ar an mbunachar sonra├н n├б athphac├бil leathanaigh aonair an bhunachair sonra├н mar a dh├йanann an t-ord├║ {vacuum}."
"aboutSlackUsername": "Athra├нtear ainm taispe├бna sheolt├│ir na teachtaireachta. M├бs mian leat duine ├йigin a lua, cuir san ainm cairdi├║il ├й ina ionad sin.",
"Custom sound to override default notification sound": "Fuaim shaincheaptha chun fuaim f├│gra r├йamhshocraithe a sh├бr├║",
"Time sensitive notifications will be delivered immediately, even if the device is in do not disturb mode.": "D├йanfar f├│gra├н at├б ├нogair ├│ thaobh ama a sheachadadh l├бithreach, fi├║ m├б t├б an gl├йas i m├│d n├б cuir isteach.",
"rabbitmqNodesInvalid": "Bain ├║s├бid as URL l├бnch├бilithe (ag tos├║ le 'http') le haghaidh n├│id RabbitMQ.",
"rabbitmqHelpText": "Chun an monat├│ir a ├║s├бid, beidh ort an Breise├бn Bainist├нochta a chumas├║ i do chumr├║ RabbitMQ. Le haghaidh tuilleadh faisn├йise, f├йach ar an {rabitmq_documentation}.",
"Pop": "Popcheol",
"Time Sensitive (iOS Only)": "Am-├нogair (iOS amh├бin)",
"From": "├У",
"Can be found on:": "Is f├йidir ├й a fh├бil ar: {0}",
"The phone number of the recipient in E.164 format.": "Uimhir theileaf├│in an fhaighteora san fhorm├бid E.164.",
"Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "Aitheantas seolt├│ir t├йacs n├│ uimhir theileaf├│in i bhform├бid E.164 m├бs mian leat a bheith in ann freagra├н a fh├бil.",
"RabbitMQ Nodes": "N├│id Bainist├нochta RabbitMQ",
"rabbitmqNodesDescription": "Cuir isteach an URL do na n├│id bhainist├нochta RabbitMQ lena n-├бir├нtear pr├│tacal agus port. Sampla: {0}",
"rabbitmqNodesRequired": "Socraigh na n├│id don mhonat├│ir seo le do thoil.",
"RabbitMQ Username": "Ainm ├Ъs├бideora RabbitMQ",
"RabbitMQ Password": "RabbitMQ Pasfhocal",
"SendGrid API Key": "Eochair API SendGrid",
"Separate multiple email addresses with commas": "Scar seolta├н r├нomhphoist iolracha le cam├│ga",
"ignoredTLSError": "N├нor tugadh aird ar earr├бid├н TLS/SSL",
"Message format": "Form├бid teachtaireachta",
"Send rich messages": "Seol teachtaireachta├н saibhir",
"Notification Channel": "Cain├йal F├│gra├н",
"Sound": "Fuaim",
"Alphanumerical string and hyphens only": "Teaghr├бn alfa-uimhri├║il agus fleisc├нn├н amh├бin",
"Arcade": "Stuara",
"Correct": "Ceart",
"Fail": "Teip",
"Harp": "Cl├бirseach",
"Reveal": "Nocht",
"Bubble": "Mboilgeog",
"Doorbell": "Cloig├нn an dorais",
"Flute": "Fli├║it",
"Money": "Airgead",
"Clear": "Glan",
"Elevator": "Ardaitheoir",
"Guitar": "Giot├бr",
"Scifi": "Ficsean eola├нochta"
} }

View File

@@ -58,53 +58,5 @@
"Cert Exp.": "рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдЕрдиреБрднрд╡.", "Cert Exp.": "рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдЕрдиреБрднрд╡.",
"dbName": "рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдирд╛рдо", "dbName": "рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдирд╛рдо",
"now": "рдЕрднреА", "now": "рдЕрднреА",
"-year": "-рд╡рд░реНрд╖", "-year": "-рд╡рд░реНрд╖"
"Not available, please setup.": "рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИ, рдХреГрдкрдпрд╛ рд╕реЗрдЯ рдЕрдк рдХрд░реЗрдВред",
"Auto": "рд╕реНрд╡рддрдГ",
"styleElapsedTime": "рд╣рд╛рд░реНрдЯрдмреАрдЯ рдмрд╛рд░ рдХреЗ рдиреАрдЪреЗ рдмреАрддрд╛ рд╣реБрдЖ рд╕рдордп",
"Setup Notification": "рд╕реВрдЪрдирд╛ рд╕реЗрдЯ рдЕрдк рдХрд░реЗрдВ",
"Light": "рдкреНрд░рдХрд╛рд╢",
"Dark": "рдЕрдВрдзрдХрд╛рд░",
"Theme - Heartbeat Bar": "рдереАрдо - рд╣рд╛рд░реНрдЯрдмреАрдЯ рдмрд╛рд░",
"Host URL": "рд╣реЛрд╕реНрдЯ рдпреВрдЖрд░рдПрд▓",
"Request Timeout": "рдЕрдиреБрд░реЛрдз рд╕рдордп рд╕реАрдорд╛",
"Accepted Status Codes": "рд╕реНрд╡реАрдХреГрдд рд╕реНрдерд┐рддрд┐ рдХреЛрдб",
"Response": "рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛",
"locally configured mail transfer agent": "рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдореЗрд▓ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдПрдЬреЗрдВрдЯ",
"Heartbeat Interval": "рд╣рд╛рд░реНрдЯрдмреАрдЯ рдЕрдВрддрд░рд╛рд▓",
"Retries": "рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛",
"Heartbeat Retry Interval": "рд╣рд╛рд░реНрдЯрдмреАрдЯ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдЕрдВрддрд░рд╛рд▓",
"Port": "рдкреЛрд░реНрдЯ",
"checkEverySecond": "рд╣рд░ {0} рд╕реЗрдХрдВрдб рдореЗрдВ рдЬрд╛рдВрдЪ рдХрд░реЗрдВ",
"retryCheckEverySecond": "рд╣рд░ {0} рд╕реЗрдХрдВрдб рдореЗрдВ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ",
"ignoreTLSErrorGeneral": "рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП TLS/SSL рддреНрд░реБрдЯрд┐ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░реЗрдВ",
"needPushEvery": "рдЖрдкрдХреЛ рд╣рд░ {0} рд╕реЗрдХрдВрдб рдореЗрдВ рдЗрд╕ URL рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред",
"pushOptionalParams": "рд╡реИрдХрд▓реНрдкрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░: {0}",
"Save": "рд╕рд╣реЗрдЬреЗрдВ",
"retriesDescription": "рд╕реЗрд╡рд╛ рдХреЛ рдбрд╛рдЙрди рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рдиреЗ рдФрд░ рд╕реВрдЪрдирд╛ рднреЗрдЬрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЕрдзрд┐рдХрддрдо рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛",
"Notifications": "рд╕реВрдЪрдирд╛рдПрдБ",
"Check Update On GitHub": "рдЧрд┐рдЯрд╣рдм рдкрд░ рдЕрдкрдбреЗрдЯ рдЬрд╛рдВрдЪреЗрдВ",
"timeoutAfter": "{0} рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж рд╕рдордп рд╕реАрдорд╛ рд╕рдорд╛рдкреНрдд",
"upsideDownModeDescription": "рд╕реНрдерд┐рддрд┐ рдХреЛ рдЙрд▓реНрдЯрд╛ рдХрд░реЗрдВред рдпрджрд┐ рд╕реЗрд╡рд╛ рдкрд╣реБрдВрдЪ рдпреЛрдЧреНрдп рд╣реИ, рддреЛ рдпрд╣ DOWN рд╣реИред",
"Upside Down Mode": "рдЙрд▓реНрдЯрд╛ рдореЛрдб",
"Max. Redirects": "рдЕрдзрд┐рдХрддрдо рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢",
"Push URL": "рдкреБрд╢ рдпреВрдЖрд░рдПрд▓",
"Monitor": "рдореЙрдирд┐рдЯрд░ | рдореЙрдирд┐рдЯрд░реНрд╕",
"maxRedirectDescription": "рдЕрдиреБрд╕рд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХрддрдо рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рдиреЛрдВ рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 0 рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВред",
"Advanced": "рдЙрдиреНрдирдд",
"Invert Keyword": "рдХреАрд╡рд░реНрдб рдЙрд▓рдЯреЗрдВ",
"Json Query Expression": "JSON рдХреНрд╡реЗрд░реА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐",
"URL": "рдпреВрдЖрд░рдПрд▓",
"Hostname": "рд╣реЛрд╕реНрдЯрдиреЗрдо",
"Either enter the hostname of the server you want to connect to or localhost if you intend to use a locally configured mail transfer agent": "рдпрд╛ рддреЛ рдЙрд╕ рд╕рд░реНрд╡рд░ рдХрд╛ рд╣реЛрд╕реНрдЯрдиреЗрдо рджрд░реНрдЬ рдХрд░реЗрдВ рдЬрд┐рд╕рд╕реЗ рдЖрдк рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдпрд╛ {localhost} рдпрджрд┐ рдЖрдк {local_mta} рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ",
"Resend Notification if Down X times consecutively": "рдпрджрд┐ рд▓рдЧрд╛рддрд╛рд░ X рдмрд╛рд░ рдбрд╛рдЙрди рд╣реЛ, рддреЛ рдкреБрдирдГ рд╕реВрдЪрдирд╛ рднреЗрдЬреЗрдВ",
"resendEveryXTimes": "рд╣рд░ {0} рдмрд╛рд░ рдореЗрдВ рдкреБрдирдГ рднреЗрдЬреЗрдВ",
"resendDisabled": "рдкреБрдирдГ рднреЗрдЬрдирд╛ рдирд┐рд╖реНрдХреНрд░рд┐рдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ",
"ignoredTLSError": "TLS/SSL рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ",
"pushOthers": "рдЕрдиреНрдп",
"programmingLanguages": "рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдПрдБ",
"styleElapsedTimeShowNoLine": "рджрд┐рдЦрд╛рдПрдБ (рдХреЛрдИ рд░реЗрдЦрд╛ рдирд╣реАрдВ)",
"Expected Value": "рдЕрдкреЗрдХреНрд╖рд┐рдд рдорд╛рди",
"ignoreTLSError": "HTTPS рд╡реЗрдмрд╕рд╛рдЗрдЯреЛрдВ рдХреЗ рд▓рд┐рдП TLS/SSL рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░реЗрдВ",
"pushViewCode": "рдкреБрд╢ рдореЙрдирд┐рдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ? (рдХреЛрдб рджреЗрдЦреЗрдВ)"
} }

Some files were not shown because too many files have changed in this diff Show More