From a16b42f98c5bbbdcd6fc057d791609948c2c4d0d Mon Sep 17 00:00:00 2001 From: Neel Bhanushali Date: Sun, 11 Feb 2024 21:33:58 +0530 Subject: [PATCH 002/237] poc done --- server/model/monitor.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/model/monitor.js b/server/model/monitor.js index b2fed86f..140a9442 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -606,7 +606,9 @@ class Monitor extends BeanModel { if (result.toString() === this.expectedValue) { bean.msg += ", expected value is found"; bean.status = UP; + console.log('json-query successful') } else { + console.log('json-query unsuccessful') throw new Error(bean.msg + ", but value is not equal to expected value, value was: [" + result + "]"); } } @@ -898,7 +900,7 @@ class Monitor extends BeanModel { retries = 0; } catch (error) { - + console.log('came in catch') if (error?.name === "CanceledError") { bean.msg = `timeout by AbortSignal (${this.timeout}s)`; } else { @@ -913,6 +915,7 @@ class Monitor extends BeanModel { } else if ((this.maxretries > 0) && (retries < this.maxretries)) { retries++; bean.status = PENDING; + console.log('checking retries', retries, this.maxretries) } else { // Continue counting retries during DOWN retries++; @@ -971,6 +974,7 @@ class Monitor extends BeanModel { } else if (bean.status === MAINTENANCE) { log.warn("monitor", `Monitor #${this.id} '${this.name}': Under Maintenance | Type: ${this.type}`); } else { + beatInterval = this.retryInterval log.warn("monitor", `Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type} | Down Count: ${bean.downCount} | Resend Interval: ${this.resendInterval}`); } From a5d0f7a7db9ddc4863731c86895b66664c0055a2 Mon Sep 17 00:00:00 2001 From: Neel Bhanushali Date: Sun, 11 Feb 2024 21:37:45 +0530 Subject: [PATCH 003/237] console added with double quotes and semicolons. console added with username so i can remove later --- server/model/monitor.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/model/monitor.js b/server/model/monitor.js index 140a9442..c2b40b9b 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -606,9 +606,9 @@ class Monitor extends BeanModel { if (result.toString() === this.expectedValue) { bean.msg += ", expected value is found"; bean.status = UP; - console.log('json-query successful') + console.log("neelbhanushali: json-query successful"); } else { - console.log('json-query unsuccessful') + console.log("neelbhanushali: json-query unsuccessful"); throw new Error(bean.msg + ", but value is not equal to expected value, value was: [" + result + "]"); } } @@ -900,7 +900,7 @@ class Monitor extends BeanModel { retries = 0; } catch (error) { - console.log('came in catch') + console.log("neelbhanushali: came in catch"); if (error?.name === "CanceledError") { bean.msg = `timeout by AbortSignal (${this.timeout}s)`; } else { @@ -915,7 +915,7 @@ class Monitor extends BeanModel { } else if ((this.maxretries > 0) && (retries < this.maxretries)) { retries++; bean.status = PENDING; - console.log('checking retries', retries, this.maxretries) + console.log("neelbhanushali: checking retries", retries, this.maxretries); } else { // Continue counting retries during DOWN retries++; @@ -974,7 +974,7 @@ class Monitor extends BeanModel { } else if (bean.status === MAINTENANCE) { log.warn("monitor", `Monitor #${this.id} '${this.name}': Under Maintenance | Type: ${this.type}`); } else { - beatInterval = this.retryInterval + beatInterval = this.retryInterval; log.warn("monitor", `Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type} | Down Count: ${bean.downCount} | Resend Interval: ${this.resendInterval}`); } From 81e465f41896ab2369f554ba30d7f36ec672b5b2 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Feb 2024 20:02:09 +0100 Subject: [PATCH 004/237] Removed debug statement --- server/model/monitor.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/model/monitor.js b/server/model/monitor.js index c2b40b9b..2543cf1b 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -606,9 +606,7 @@ class Monitor extends BeanModel { if (result.toString() === this.expectedValue) { bean.msg += ", expected value is found"; bean.status = UP; - console.log("neelbhanushali: json-query successful"); } else { - console.log("neelbhanushali: json-query unsuccessful"); throw new Error(bean.msg + ", but value is not equal to expected value, value was: [" + result + "]"); } } @@ -900,7 +898,6 @@ class Monitor extends BeanModel { retries = 0; } catch (error) { - console.log("neelbhanushali: came in catch"); if (error?.name === "CanceledError") { bean.msg = `timeout by AbortSignal (${this.timeout}s)`; } else { @@ -915,7 +912,6 @@ class Monitor extends BeanModel { } else if ((this.maxretries > 0) && (retries < this.maxretries)) { retries++; bean.status = PENDING; - console.log("neelbhanushali: checking retries", retries, this.maxretries); } else { // Continue counting retries during DOWN retries++; From 4d6ea433e62c9b1e0bc3cc685ed1e93b879f3191 Mon Sep 17 00:00:00 2001 From: NihadBadalov <32594553+NihadBadalov@users.noreply.github.com> Date: Wed, 14 Feb 2024 22:51:06 +0100 Subject: [PATCH 005/237] Feat: Add background color change on hover to nav links --- src/layouts/Layout.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/layouts/Layout.vue b/src/layouts/Layout.vue index 61068183..56e35a6e 100644 --- a/src/layouts/Layout.vue +++ b/src/layouts/Layout.vue @@ -211,6 +211,10 @@ export default { @import "../assets/vars.scss"; .nav-link { + &:hover { + background-color: rgba($primary, 0.2); + } + &.status-page { background-color: rgba(255, 255, 255, 0.1); } From 94154c49aabc22019ec814cea274226030ca6467 Mon Sep 17 00:00:00 2001 From: NihadBadalov <32594553+NihadBadalov@users.noreply.github.com> Date: Thu, 15 Feb 2024 08:21:43 +0100 Subject: [PATCH 006/237] Feat: Change hover colors to shades of gray --- src/layouts/Layout.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/layouts/Layout.vue b/src/layouts/Layout.vue index 56e35a6e..94eaa731 100644 --- a/src/layouts/Layout.vue +++ b/src/layouts/Layout.vue @@ -212,7 +212,11 @@ export default { .nav-link { &:hover { - background-color: rgba($primary, 0.2); + background-color: rgba(0, 0, 0, 0.05); + + .dark & { + background-color: rgba(255, 255, 255, 0.05); + } } &.status-page { From 17dfdacd933c62cbadc04d4afb473ce63b223c6d Mon Sep 17 00:00:00 2001 From: NihadBadalov <32594553+NihadBadalov@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:52:59 +0100 Subject: [PATCH 007/237] Fix: Correct colors --- src/layouts/Layout.vue | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/layouts/Layout.vue b/src/layouts/Layout.vue index 94eaa731..9faedf58 100644 --- a/src/layouts/Layout.vue +++ b/src/layouts/Layout.vue @@ -212,10 +212,16 @@ export default { .nav-link { &:hover { - background-color: rgba(0, 0, 0, 0.05); + background-color: $primary; + color: #fff; .dark & { - background-color: rgba(255, 255, 255, 0.05); + background-color: $primary; + color: #000; + } + + &.active { + background-color: $highlight; } } From d92003e1726f0dfd3f162973d2f29064a6dbf709 Mon Sep 17 00:00:00 2001 From: Matt Visnovsky Date: Fri, 26 Apr 2024 19:05:56 -0600 Subject: [PATCH 008/237] SNMP Initial Commits This commit introduces a new SNMP monitor feature to the application, allowing users to monitor devices using SNMP (Simple Network Management Protocol). --- .../2024-04-26-0000-snmp-monitor.js | 10 + package-lock.json | 6 + package.json | 1 + server/monitor-types/snmp.js | 69 + server/uptime-kuma-server.js | 2 + src/pages/.EditMonitor.vue.swp | Bin 0 -> 102400 bytes src/pages/EditMonitor.vue | 1107 ++++++++--------- 7 files changed, 631 insertions(+), 564 deletions(-) create mode 100644 db/knex_migrations/2024-04-26-0000-snmp-monitor.js create mode 100644 server/monitor-types/snmp.js create mode 100644 src/pages/.EditMonitor.vue.swp diff --git a/db/knex_migrations/2024-04-26-0000-snmp-monitor.js b/db/knex_migrations/2024-04-26-0000-snmp-monitor.js new file mode 100644 index 00000000..8b93ecd4 --- /dev/null +++ b/db/knex_migrations/2024-04-26-0000-snmp-monitor.js @@ -0,0 +1,10 @@ +exports.up = function (knex) { + return knex.schema + .alterTable("monitor", function (table) { + table.string("snmp_community_string", 255).defaultTo("public"); // Add community_string column + table.string("snmp_oid").notNullable(); // Add oid column + table.enum("snmp_version", ["1", "2c", "3"]).defaultTo("2c"); // Add snmp_version column with enum values + table.float("snmp_control_value").notNullable(); // Add control_value column as float + table.string("snmp_condition").notNullable(); // Add oid column + }); +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a6ef4f03..7728a0cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,6 +72,7 @@ "redbean-node": "~0.3.0", "redis": "~4.5.1", "semver": "~7.5.4", + "snmp-native": "^1.2.0", "socket.io": "~4.6.1", "socket.io-client": "~4.6.1", "socks-proxy-agent": "6.1.1", @@ -12609,6 +12610,11 @@ "npm": ">= 3.0.0" } }, + "node_modules/snmp-native": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/snmp-native/-/snmp-native-1.2.0.tgz", + "integrity": "sha512-JIyuLX3bQmuAI4gHztHSQd3M/M2hqgLhiHBZYEk8YnYRJ2ooxqwON4gUQfgp/WCZVDca4tIX3vFJgv6lz5iY+g==" + }, "node_modules/socket.io": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.2.tgz", diff --git a/package.json b/package.json index 567efa1b..7ee8afb4 100644 --- a/package.json +++ b/package.json @@ -137,6 +137,7 @@ "redbean-node": "~0.3.0", "redis": "~4.5.1", "semver": "~7.5.4", + "snmp-native": "^1.2.0", "socket.io": "~4.6.1", "socket.io-client": "~4.6.1", "socks-proxy-agent": "6.1.1", diff --git a/server/monitor-types/snmp.js b/server/monitor-types/snmp.js new file mode 100644 index 00000000..4ddc8823 --- /dev/null +++ b/server/monitor-types/snmp.js @@ -0,0 +1,69 @@ +const { MonitorType } = require("./monitor-type"); +const { UP, DOWN } = require("../../src/util"); +const snmp = require("snmp-native"); + +class SNMPMonitorType extends MonitorType { + name = "snmp"; + + /** + * Checks the SNMP value against the condition and control value. + * @param {object} monitor The monitor object associated with the check. + * @param {object} heartbeat The heartbeat object to update. + * @param {object} _server Unused server object. + */ + async check(monitor, heartbeat, _server) { + try { + const session = new snmp.Session({ host: monitor.ipAddress, community: monitor.snmpCommunityString, version: monitor.snmpVersion }); + + session.get({ oid: monitor.snmpOid }, (err, varbinds) => { + if (err) { + heartbeat.status = DOWN; + heartbeat.msg = `Error: ${err.message}`; + return; + } + + // Assuming only one varbind is returned + const value = varbinds[0].value; + + // Convert value to appropriate type based on SNMP type (assuming it's integer or string for simplicity) + const numericValue = parseInt(value); + const stringValue = value.toString(); + + // Check against condition and control value + switch (monitor.snmpCondition) { + case '>': + heartbeat.status = numericValue > monitor.snmpControlValue ? UP : DOWN; + break; + case '>=': + heartbeat.status = numericValue >= monitor.snmpControlValue ? UP : DOWN; + break; + case '<': + heartbeat.status = numericValue < monitor.snmpControlValue ? UP : DOWN; + break; + case '<=': + heartbeat.status = numericValue <= monitor.snmpControlValue ? UP : DOWN; + break; + case '==': + heartbeat.status = value === monitor.snmpControlValue ? UP : DOWN; + break; + case 'contains': + heartbeat.status = stringValue.includes(monitor.snmpControlValue) ? UP : DOWN; + break; + default: + heartbeat.status = DOWN; + heartbeat.msg = `Invalid condition: ${monitor.snmpCondition}`; + } + + session.close(); + }); + } catch (err) { + heartbeat.status = DOWN; + heartbeat.msg = `Error: ${err.message}`; + } + } + +} + +module.exports = { + SNMPMonitorType, +}; diff --git a/server/uptime-kuma-server.js b/server/uptime-kuma-server.js index bcf497b5..db7b4797 100644 --- a/server/uptime-kuma-server.js +++ b/server/uptime-kuma-server.js @@ -113,6 +113,7 @@ class UptimeKumaServer { UptimeKumaServer.monitorTypeList["tailscale-ping"] = new TailscalePing(); UptimeKumaServer.monitorTypeList["dns"] = new DnsMonitorType(); UptimeKumaServer.monitorTypeList["mqtt"] = new MqttMonitorType(); + UptimeKumaServer.monitorTypeList["snmp"] = new SNMPMonitorType(); // Allow all CORS origins (polling) in development let cors = undefined; @@ -516,3 +517,4 @@ const { RealBrowserMonitorType } = require("./monitor-types/real-browser-monitor const { TailscalePing } = require("./monitor-types/tailscale-ping"); const { DnsMonitorType } = require("./monitor-types/dns"); const { MqttMonitorType } = require("./monitor-types/mqtt"); +const { SNMPMonitorType } = require("./monitor-types/snmp"); diff --git a/src/pages/.EditMonitor.vue.swp b/src/pages/.EditMonitor.vue.swp new file mode 100644 index 0000000000000000000000000000000000000000..638a932fef267fe4c62c92fee964e9c04b6a3abf GIT binary patch literal 102400 zcmeI52b^42b^nKefly2_V0xa{##-5$85PTz)vjz=E6c)a)~;=gapc*Zx4VO;tfy$T z2w^%2IP?-)0wIN7LJ9}jzv;N9md%Oz@8*+T^oy*IL0^Q&{q^0?n;&$j95{M7EL z=_@98?duV^SgW^-v&Ab~ezR4qmD=sY#chj=lcjd4c%V_LRqFG_ot3tCz+Y^%ik-!F zrRL`kb!w$zt2tX-EY16^;*N5qy{A#Hv>VOB;f~)Uvy-n*a^NHfLJoA=bNLHSy<*eG z4eRCMnImU-r``98@cqeOCpmDE11C9fk^?6>aFPQjIdGB#CpmDE1OMwe&|W+}cLSyT zHB-__^L>Zd_npk&Tg~^5*!xq=-(%+cX|eZrHh&k*_j_aS?_&P8@xKv!e^>MOCi8u^ zA<)wK>*o1p^L=&f{oP{mpBsCBck}*y^ZowV`+LOR|0wqUp62~|<~wf~YJ%lXHP1)Q zcPaM%Ugr5l=KHr}?@`UD&sy{SkFodnG0!)e@9)Ll-`70fWxmh4qyAy(JIy?=o9|le z{r${ys}TBZ?EU>?@uy9LvFSg+ysw(?55(S|Zk``7-v!g4Z2SkB=VkN#!oV=JCm|lN>n7fs-6K$$^s`ILU#N95~5=lN>n7fs-8gKg)p<0@b;c{wfi)5HcqX zCw_=P`eE>1a3i=5JOF$LLH7OND0l+6415LQ_gUaP@IwUUzXZ#g+O?7rSK>F z#~a{tS!wQ2$=ly-lsmJ2GnX~ycmofKM%_DHs&@Q|kwcP7e$k{dvNd};MV(Og7((Hm z%crNaXAvc}c740O>ICjA)%?lI{IE366TMuSUv)B%9`(*@kB&^W{Zh>nn!PE%dDw4` zto4o^8cj~2teIN$XDf4+SmhrBhq$jb7}xOKXSaXwxrM^D{b+tZhYA%ur*H={u8+ z*+Ud*d!ybiQK;kVI%Snu##S*r>63e>hUIa&-dc6?<`3-Ot{aTu@n!zei}xqMuOcs$AEuUE;O@FJ{4C7dY!Pwm~af7lk@ zs@E1*y@~I~-E>$27m2&-1Ws??@9l3i+d~sc+*K#ibhBY;TxhpfzoyLquu~Q}$JO`M zf+izN)0b5{edec9HMwB$`h3P)e$}6CdzJFUNSmeDh<7+&Ym{ZVRx|F<`tfX)HOa)t zT%%db>o^$*9#<y+_0Ga^7-%wH*w{T+H^|&+oztHz;eDlu&Mn)yQtNfsa4vA#ioDQueT>g^xyHY3mY5;z%SS@F7SIr zL^yVAytuF-EW41mH8)Qi8gDmC^;Sg*hIN9HdbLva^K+##ZKkxi=$D#=Z2PsvYN_pS z&58WK4S87PW|9A`{q)Vq`Zs{f!Fo^xUqjZv2|OLt!DGR0unk-U9squX4&Y_rM(`YP z1GpO858Q$-;Qipw!Arok-~hNB>;Pwjuc06KOYkc2e6R%egB@TJTmVi3A4g~K`{3!| z2zV?gg0sMx;B@d~^a$?&F9pvA*MS1KEBHA&g`a^hfxiV$1djsWMX&H3a1%HJYM=^4 z=Wq(R2_3^Tz%4lY$-1n%?3E5TDrJN( z&tGg+stEKmoluC2R<*7?x0z70+ojnB71pgjBF%4+E>xE$o8J(nScNJ#OLJ`{S*V5C zgcp4f#weA`et9woJsJ(?lIfjO3Gy=hvg ztO2F|rM0RoX~c*@1viIn<#Nj_rN1tob57V~V$C+fCapI+xX_?MO(3SkORm&vm-2SB zQa--Y)>St-Mjqa-NhzDo+LNr^V(qAxW~#pGy1M*EPbfr4Z&o!z$ME8NN9VndDNEg;$aA1G3C5$pD-yEtOmZ7h~^{fbYMH{>Je<6#~d`V)jR4Pi;dno{Z`fY z7e`q-tao0QTFdoWuf;N=yoe44@VdqUcP1d zFsrA(z5bFWIx^lkfte7dq-bh%tous{*lMgdjPn@Une8zHs_~-SsQckq=p>`LEpzs$ z!@5KOU3cw9sntH%f@H25gOdMc z7jQ-F+sOaczyD*%`_BQ71`h7EJpKmode8xvfd4=iuYz6RQt%s~f&6_M_#I^H$Ab#k z0=|Mg{d90Qa2vXeuYz}h$AeSAi?Q!N4%`X65xf4=fCs)zng0sB47?Nw4;H|xeBAaB z|2=+2KJOXrzL(GU(~T9Cx+k7U{O|GNOb10&MtiE!?$I(?NKZEo`E{jZ%f(ZT|2?iV zkrk@w9cS9C$=Y@N5Gu72rWQ}Mk~~(FjCdE#Rx7iICS<(w+d7v}ixp4W{ym@E~LDnv? zRf^*?O|O`tV2)B$DQrbzi|GL^6Ws6d?Ty7{S={WZFN%DEPFPBu?=-89URWMoabUNt z0`;<7X-PaH*k2==2zB(sVNRyX73EPKv2f@Lh!O5)R}UY~SLUMXY;R&>!doLbt{Jf{ z%xI5Ye#C#P?j$sLlz-*=QzhWGvSdcNZQFsolA@c2uWHnit~iCP)NVEi(DbkGRGK1U z$LWv%?W*U)th=*cYJFu`@0x4}uL7|muT~YLb6-8xLyr3C@+e^ZA}7!I&HBWMSf5%K zjunfAbBC>tL@v>euyQpaw65`<_(ab(G%2O-AI7BHOcpa}&4->i7 z8Ov;;^W^&I^&PW`ATm3g%P zP%1;~iE~byww(5a)jdlpgxOEvrluyuGqm7Psn0dg4Q>y-oUG$#l=m5y4?#9VIb9t< zuxRCM8vVY5qG%^orn}1OdoLX*l`Ea$X;iUSosWAO_4&r+#lv!v5pljzo>_e|m!~e@ zUEEV@R!YY~>~ib+>Z+5vAH^OjdgvXNshm3}DXe}A-BX!uHd>9jwg(Rh`qYX2Up{vdxfl80?!UhgnST_#4OxE)oCod+zK)##pWx5I`QRPM_}74k zg6|{azXvqIWndJn0pCZ)e>JE9vC+Q``Tkn)K=5D4^=||7U>w{Z+z)&LIsb9s^~m>6 z0oKPq&+mUn&c7b~H?sW?!3)4v@I~bNcYzmy7lJdutB~`T!4a?*JQRGGvK|7e%oJNV z((B_o--us$%EClHcGnKZ`DWN-*fgB;_-D4r|qoE z6d?j1d#_PvRU~?go?H|qhs0R1^~`uEk@-h(SZ^DHVoLqQ-mlUMGL}n9^_eBu4nwY| z44~1qWKSjvgV8SZ=Cle_tZcZTp2un{fA#x}m%N3hkMylXA|#@AbGaar17~v<8qN8l zb--G);5XR^pyc|}kZDKLb^aPJW=L{em&K2^0gN2E{`nLdaW~7?H%4&+nwK zjo8>57$$Rl`4P4(Nn$^Vr8KJW)he~8FoW(*>Cw>V_%$E@Xdszt59h%Lgpin(>*U$B zf8*O`#h^5$T_qC^l1;zXX!{54_5^QC?@B^zso$8r5iPAb#08>)$^g|`wZreRl1h7G zL|akLqPMgPk$97pQnfK(Xe~6BM%QLit4S+#bvrt_VE;r!Z4?zn52&Kp-5k;Jqi@?5 zt)mv?BJ{VW8}sv3KU4P@piZ&}6~fK<7$MBiC4)|`U*Y7v>#P|L3K<8hER(5Agdw=o z@^zhoSq#tCOLTm#xlz%O(5 z(`D*!tJ10%l12VUq|SW~i2PraZ$8gQ_P^5T0Dgho|5@-E@NBRbJOsQ3`TsM>_wNLM z3XTBr)Bi_g{PV%Rz^UM4$oa1Xr-LUW+g}YH10DfxL&m=v{2U_Q1)c-SU>2+g-$Tyd z3O zT)OV8qjs1H=Ox+sz6O6z`QEj-uPMH0lIa0|-amqrA$BR8JS$yZ9lLH=J5^YO?rqW% zlYKeavr&q_aTk-5G7_X4v)J9*C6e0I-sPRuV5Fz1xt?k}Ybs@LmsF#g^)7*Av*O@_ zlHJ^gC#;wT_+m#e|Lb!Ait2a;{?wXmenc$^5|I6s1L$3B-Da5z!p%Y5x{ZCF(L5u; zGYxV!UHLW(3*)R9JtM>0*1@fDy0ORs1>42hOT_w2Ya&TG)4D?)r-6^7I+J5twc1#c zJXMxKju}M?XG)SYI{GA?3tKJ7pSamVuE7p$rZ99N_v<+fF<^e#PU4-S%SiR{O!AXwkoJG)DcGmaoynbUV{ z&kizl>nFDUlaU}e^T)F>v|?2S?LWA<@?8dvy&_pT8m8vme`Xl8t9Ge1HHP-9GZW}U z)tJeyUwx@y1G;~t^{%X{5Z$H1Tvxu1uI%`GI@NYXTdR~SVPqsioyFNI=sy$M)bwCu zHA!tz96ZF8AH8XyWWDBE{$khhtiRBxmVG*n95l2;HYO?*qeWIG4?S;>;ahP*M9 z{P{$b{a9#Q>|#(6)$RrpM@3;5lGzA1F|v96dY#C;cs&LriHbH~Z{!2glz%lLXRD2t zpGWu3 zVYzOJ$@7dW*C8B>Sc+z=H6epVu81yj7C^hboLRxG8!o(1bC0AT`MN*!R+5c}v_P+)EDR>-s3iAG$;04J1bx;Fh|Nk0x|0eh( za{oKP+rbR@9&&#PYy}fQ^Z>6#{@)CKf!zOb@LEs-vhV)x;FIV9{s=6AJ>VR$7JLUi zz+Z!9a0&P@`hZ7(|3nY)O0WoaflI-I!ENXRo&mm%PT-xO3bugu zxlh1HYP;XZwFMyuA7pH4R1fpr1BB}|XMOL0Kg%Ia>a4cxLcCCwvXsd6 zrFM{2JIl*~dWD>c2MgrH*IEzb=zN@7}=0vF`%eYb*{}pI{)s2y0GoI8$jRsm$jtiwDPNx z>@7=(G@1g_TbkM#>Q~un+`emEvy$tlv_O5AyP1gXja}ttgFx?rlm283v=K zdp>1mX*^|o>D9dYPxsI+b9~Q4qm@5Y|*;l>3L&w2hq1< zCP#tDTetHW_rdraH}iNonQd2@V*%LI?l;$FpL!KfyNNWZmW35&`D~+B>#%cq`Jg^T;&#UW zBzfH{W4kR1Mie;@V>N4`+W;odl>uILu|4`^KD8cSxj7{4FS=(WG&8@-4x{t#UP=20 zTAB9j9+Fizo1C0~-Q}IgzvAq?vZlh+zS_5y$m+zg1g0DR)Y8Qm{4%XzgvXhio7n#m zy>s6Y85sM&y z0bC8v27iIve+3y8jI4h*zCVv_{}wP0&I9j9w%-mO3LXN!hK%0<-$$nZ2>3AgU2raV zBl3M6tOdV7rvF#)Y4AEAckjI&xqb>rxxOuBGoM~{;=YS5MM9@o>j^y)`nsBtMr&pI z&)7DbSQgf6#2&O6brBgPad-J4w(srYPbkeOWpt0dcYCf`f()>OK}zOMpFI*c6RBJy zU54d2BgFM zaFvsMg?f$2{tEACPI)PXTAV?nX!qmZsTb1Mv|3|5>=QtxosB2Hy# z?+aDGKHpwY=QD^2Qtu>LBU?%E6-(Vq5@rzFNHS(eU~9k3aI%aV!qnKH6~;Po!`hTK zZ&aw0`X&wGMt12*<>ijXGwOKno-JO2cN2Rxt%JMNDOH~?K=#(}lsNN}xmU>)GeQYX zm*t?0{Q7E=v z9Y?GSMZz1yc$Cam2X@AYd!6j(6f&>m9XODmhKNF;pj=0~`D~2!@+r~O4(qugHj1&5 zxR>TRlE01B-jtrBB{^!+W6^mCUDi5Jj%DMFR)4O9gN;7=1Dn72M3+6gX?LDG2s$$b zlxD@&0@}z@qj;<2fX|>0*bTmd4&blBd%?589f6N7;D^Zm z9|Io+uK@P}*Gt*JFHPCpuS~tbncW0XoU| ztaQJ;igoUnvsSr7#)+%(7lJ>_$@Y{Dbu__}sWrI|8| z>Yk;uv{l+$vk4g^6J^WLH85rnws^OU!wVVFb7QR&%ow{7uin z=yCM8XeX9{xZ5|AJKdEzn#q9{CHtY6$I*a8a@;CRWpF^)@iMsQ7-Z#$t`e{2QU;$@ zo6^ckBw??KonMpaGqLxwfJZ4Iht@{-9}RxQsW8wLR%1D()TG@Xc04EPs9dw0rlSI8 zm)u-eiE!;e{V%j@=7L=@D8)~vQTOXgR{cK8#O!mkSG}D#imH5_YRL1%_gM26@ov|- z^%rz)W{%2Rh&z#I-Utb9?T7hyulR)dP4(~$JwxXCsP0MBtAUM7pQ$Po3~>mKDu~E* zA$8d*V337M_I4=bn10gg%*uK4#;EwKHcU-Ls7YD-NR^mCc5hVQ$)kVWtLkxN7bh2M zZH)|MX3}ttlu&W_#0Uo#&8UHW9i@*!PEI18(2)SR*_umAbhrBQT z{)fO?Amw_cl(Of^4vP+^^bA`I)qG^Gr5f|(PFPgNrbmUF)N?({ zlWkOUCMg85=5pSiyPqUbrj%-22Bb5}}PlsFm3xQxMsEe_`^ek-oE>q)#scMA|M_4?O_(~!|FOEr*tN+af_ z@L0Xn>+NhU*lsu(pxL?;qeD_kl^UK|sxwPZF0)p$wnGV~$8Zq78ibEMMgnXWvYUth zg8t)OG*j)cvo-Aszzn|ZZqEwI?Op+4KMp96y7269GAoW>T}Bd{z8yp|ET2=VPr5+2 zk2#5oZMtkd?7s{iFRqSwEAlD#I+c|1io=qX)RofHxbv|zQ)>CWr=R%?`fG)18m1EWsnp5|3+lvvyJ?JzLAqBk@^1udH+S=gQjI1wr`rQC_0uTHgIsa#%3_gdve6Pxqm140W$wP!Lz{ua98jJgyFa}Ns4*;L1Y%c^- z#z#mw2mZJNLfUV499%5P)tvcOX9DDFV2 z7U_}Go=wvEd0|9eZK=w@?r=g$iJzQOEd3R(GnO4g`?$jaH!Sh7%A2D?tRt5Cwhy%v zR-Oe3ny*BecLdiT^0uC{Nk;NYPX&bO;sZZUGSP)@vLtr%)aGh!dsdhFGx`)re;BYCg(%(R^|p|9U%HjfZeUA2X3@<|Oq`4khac&^P zicQq5G0i2*18=Lhek7KkQq4X_3}@b~&#lT~{w&dy| z{{~P=*SOV+7myr2C0NxKagJ)5;X96kXL#3QqKfPM6yz946 z9#d7m#+@J6c<0K-4n04k@+;uU-)DSQIqAW7O!i6kO)oivx;gHelpT!MxQ`%$6C&Lf z*=uE&X-ZWkck_@FD)m-L_o;hcrTbjik|ank-&#wR_UwX}ZMazMO|9_Obi2K5w<#Uw z#$GuqcAbYp9%GQ~yXhUWsdjt%XxVfYT4y4Ww&#Z=u=gzK7Ey)iwl$eI`X!k zDWG>z6!V;kDw4E2G^jAaVl(bAk;(bRZ5~*$LTJuh3FU9P1wVSt zV(;->Euc@3M{~q-oM=G$t+E#n-h4KMM~};B6nce<{C^hm@V!MYM*cs~$i{z%%)b*n z96SvCF0y|Iw88%%|K9{&3SI&hfZPM{N-zcP48DL4;Pc?g;H&5Xt_P0>yTE6V|K%P4 z(Fc4I`M(9^5W;`K_WucRIk0E{zY|@+5|F+B=YX}~yXXSm1s1@m;Irrfj)DnrZ*U_r zzYl&5Jdbio+3uB5?(f~*!?$ktid=;C@>Rd zq2|vnl$BvaeCJT1s`pyh_X^d{|05xGvs+=LVO8AjRJdn~lAKa-4S z1IxFWsDtthutL?#o#d3IwW*29472E8l$6DcOLW?AS2dHcyIiL3)lxNQ8;S1QVu49Z z%|7ezs;J5tx!uObP5V}JmZrvDFcj{>NsC~gIT77rWRZ@T{d*Tu@)$49blUB#7vz{$ zqfc<7AV;zqD0C)vn44+WJplJAwGy__nvbo_%%D2thsi{iM&d>Rc*iZs5((6r==3GEf@(v}BSJg34nTdT)DGlg)I* z6MycB5%qU4eXBJ^ik@EFy&GA~@UmbxS4gRpLk+$9(^bufl(-|Y$~==EUNK~V{?Vs$ zlyO1PWVgQuO>J*OZdEix#Xzmx5#^#uXQ(MT3vyL!N$kp68Lwz_ReoYuwqsq`CI+aM z3?>q(Khu|w&rG5kLex}}D3FYSn96e!w%4cUWb8JAzVol{39jvaWyR1wg;CS45X>&W zEOTwvNz~Msou6b;npW&{UdH2jn_jxOo*Ss6zE2d4o-*Ce~n6>0kp) z*D2I3fXgiRITq35nNVp9k<`=s~={_AY61mt=2LtyX zkK9=M_f1Xb+y}jW$LS;PsuQ?#$I$c8ban%2U51eq#mJ=d>OZ7Q#WJpD)p`1KlVOyYD$A8@0&)(d7}V5} zN-3jS*TU%Y6`iO9H-uQ$X>B1ms4&|InxRqj$TZ$AB&af*YTo=GYZ^h#iX@+y?7B9K zl5I;8O*aX>skhI#5XtUDG=;7iMw>wpjEnKinpy?O)*#h{JFtmE1jjYEgVAAIhow%l z@&t1dwA>5WW^dg9jUhdOL7GK+3MZt2^v^ohRNM&W9!2=|e{9?c4n-KCorJ500Vk0# zv$PhGt&jGdG}1GP)_oA>1l9J?R?rn*Km^v`0cx9rIn1R=0}KRVM(H&z^8abb(nVxz zk^e8^OFsXE?EibM z3TD9R;5|lXFv<7Bz(c{e&>g%7Tn#>i{@``s55VK8yAQ3h5{GZg3oo6jwwS@bHv@_`|vufF`>TtZca9;nRFH}-V68$w) zx^rZ5cu+y@F>tDy7r3y8+u&2Af#6NrM9sbx_YNZyc7OOx?OQP?-SscBqD!sBv>#1s z-qDrXrH1f<7HY#PPEBU3To*Hqa++ACA7`iq3Akcakjyp8|BHp#6T*DSY2`UT_)4Uq z>@M~ki6b>soR8VFd+_Nsw%!mM`N-BI`K6_$yt0>fn%veXn-I#!owghsKeF}FQ~UM~ zmXvEK5w*Nj!49EG?y*mb2+1IBYaM!G=$&k`IeGz!C!}54+-?tTb10+WzWvj?_U#>d zp=_eB`cm}L9or^zGDBqf#5$M6U3CH{Ic9ZwM=lF_5++8Xj=kzc?%y`O{nBA+RFPMo z#4Dzi{l9>q`z;Z6k^k2kq4&+m{MUm!0@?eY2j4@!ed1+sO4h!2Q8r zBF{e&`~X>g5j+Ikj0}GxxB&bo^84GsGI%t&7kD1>`=^lG{}>zs-$iB@U;b0Uz~#ub(4rn`HI+0oSt5k1@pLP%e|y?BIec5{+Kz;1myFalG{~LFmP_(|9DRQ! z>ZL7y4F_2ickS;^h#~4lkB`c2z`NqW?v<<^hp_Io6U%?NK7NAhXkg*Vwx_|w5F5*W z8>QqWNKD=&$K!i}5Sp_=vVO-FVaZWzfYpx8b43a#I-kH;>uJSWoZ?CjPRH54jlp-|dn$s$ zI4#4{<>nuo6Stkvx)&mcnG6%$<~Fu;c5}T|W_}aan?a=$nd=6yx9Alc!dO6@UGw&tv>M?&dK}xLI%li|_es|DwH?+jZJF&XT zP$%~P1qA5bV(&)&m%9Mua{+SyDd3-x`(FzVf%V{B$p7~OV&|7L0RIrI1GC8f=Yd<0 z{a+2v22Vrw-w*bIdxPg8|KEzd|3+{aTml{pWUs(?!QX)EK@ofwJ;1BM-N4(>11y5= z;4a|r(FeQ&w7^F2OLPOz0bisH?*U@RzX3>@E(0g(W1D}s?;#eAc59Ga+M*oSJ-G^G zUo@_~Be@l{z%GfZvY3@ff%^RUkcn70N9Dyf_GJl6wp#No~Z`?pUI;#c7ELK#k! zgK9SI%s?BZ98z~EQa#*D)F_&hSN%Swjkr@{WNR<9PmHKDU^F8#o|P`yItsFQ0!b^4 zgwXU0o9$GpIG3_*S3Qy|6Rg22gFxigh)mJ?d`y*6me|fYlL>3Ov<}ZW;F}4o-!@9c zAa%By>U6g8YbHw-s$r{F?RA^HWUSHJF2!|LJWGvcx!+1%jh*vOIr?!UV52A!ooN84r#xIf)Z*APcDtlZ39_WP$_+8#lpso9C%(ucIhUF& zzuoyj{IsGZyF);9UU2dqZh5BIm0TeYRDc0TZ_5v75K=`hH)^Fyw+fmxFNdfb9d%`@ z#nRZlMhu|?&CZr1T`I$U-RpO^VJE(37H;<&bliM~s9&dUmBvU&P`3%D^gk8gpoBOm zj^K9Ni2SDGqM_!MbG0Cck2?1fx)sqwQ(*nG2W|y!$BdW6%{$sHZFa-;$@p~0c#?DL zqu1}1sw;8Q?p;?p#1Q?_x^k~jU1&PG*M-e)#pEu31l8r2$-6aJpj*F&@uy=p5}$Gj=d43s0xIartjeal{zlY+g*oTu|v?MUQ* z#QEGFk&}`CcNt;%g~s=5AZMGPrwb}IK;_1jJ83&H?-> zI)T@K7l0c;3p7CmYytNG|BRmC#b6(}D-fN*6Tx)C5w(MH8BAaPwsIQux{< zm3W|N5_=QJwxp7h3>Hm>eGAbO#8XpAgo-87SX>rG#V&QZa$4)!?uLj)j-2eC7S|0B zje0a_=RrfE>E=}@2rgg<8%*>BMN?3TQ0r9N6=QVUk{fT$HYbc4hF3p%}aE4g5+BMU>&japeJ%k}Nh=_7 zV1e6h5E<=)?y6plQs(s8oXg_0-%5jLDIN3V$nZu}&hRu1+gmCzYS!mP@5$vFN7~;0 z1D-nhR&KeM8{Ism|Kq|S?h7*2(q9WGr1WXNF169dA$Hy_4MTa)MD@Vt?3S22q@;0N zEy8ULnxO72K~XhOD;TB)h+bH7T4nAt&b1rLCX|q?q-!$KnAa{px^zvI*2SGU@qAjb z+6W1BDTww>MI{$a$jWy>>+!HvqqAHc+u~qDt+7#=fs`Y|ewBARh)C6?Gczoy^UMYm z&{h5GxNe(b9ddn#%OT3iRfId#*xzpd&fcO7$&tP;^8b2d*gGNfiu_+U^6WQ}|8D{B z18)Q`0ylu`z@x#LK+XsJ3i^N#gFge}C-58~_XNyYm;<}O zgTPPF8;DQAt>6~$VIb!Sh=0Lz!7`WuqGLE0+z0#s9m9Ws4}$lBzX76qcr9oF*^_WK zxEHt$-NP%ubHH`rQ9$$&|Aao`*`N+~fDZbHvw`?2ycSG@9pFsx6Lb&X0=I#$f=`1_ zf%k*=0r6e93Y-fb2JQrYf-d66;7j1$;N{?Ya2Z$!9u9tnenR#lL%$oYu7!6U$Z z!LI?i=kQ;F+;b@BB|a8x180G6Qg=@SQipexdK~a$TUGqKSd{DUypmToCu(Xj!<*5f zs$3?Dk6+VA4Cj1tzu@hYKbMes*2xPIqnh4QrCRkCSZnGjxyt<~64>L4whmMEav>Mb zR{kdG(e^^6Rj@}T=&TRgtj%c&a?_Oxrq9NWh(WP4a@TrCQ*%<$BN1ELXj?|%AxCj< zNkkLk4wtGOKb|JsN`G-oYiOio_QNKJ4hoMR*>ja=FBY7k4~&SCHxC6aRndY?H|FQ7 zXoW&f#0WdKHkzCedo1}#9xDcn*|xyxq{$*mFg3GNTFxuWGZcI*geVkM8{)*cl)W4uTnz94~UBqQp0^C*{&d7`}zn{lNjf!vyrBFe`m zvb`$3VvoL$4DEt?Y5og(L#3sH#nY+MOKm#a%4Kga_sk_zTI5Q^y^yTf5Tu{Z2RXzb zN<*^vF3T#5t{N{IQ>Z^fY3ky1Gr(-CRvSw)G_>W)TeVPcpao%{ zj&9ia$ijO5Z5Z3UY5n@Op@GLx5Ef2!b{(|d(%e;Pos!1dbhNdY?my-!F(uksqu1)W z+E-g&PA>M5+$uQVD9?qU6 zty^RvE?k)yUv6}o%ArdB+`2_fRU8~%7HhRBQUk>uSGM+}qf?h4pxy$qOZ&y_tCeYi)aLjL!%YCfHQFiEKKJ z&{{=_)^dkksmOVXCUaC;BdT5BZtq&$r*yf(0=ILGrE1Pcr6_BojkPjZ3bEMgsKT_X zZ^pc9u8n3ySEVg9s)v194V%$68BESNj9y#VHE2pNVz8KO$RXAq3e8|iqNX8FRw2Qa zy~_WI%M2%+%Lp4MyD3AWBl|6(pJY&=(H1icX%D$gr&SR%wQ%?C0bf^M<*GT zwlDazho-e{(fHw+IP!L?qmD7%gQ}Uu23a`o6x*VY>;N5oDxgve&eGaHFB+{%Dv=q%-dj$yfn;8bJ^`Sk%kdo>^J6ZK3^x)S!`9x{$yh*+Q2IF z^+wajoivg_ufeQcsrii#lgxP+I3zMN$%F)bBL92Hi=N1h$p6bmcKl;x`{#ota3Q!0 z_#txqZQvI0A@B%f=L0elL)3A_Qk6g&?+9Xt(`!59#qg$IKB zfIEXzfanZv1}_Fzf(_sy;Mc+bpab|K_*d|0@M5qNoCUs&?EfVo=NUc=><149pGNNg zAh;Pk8HhgMY9Qwu%6^Dj!3V+3;FaJAm;w92J|OiiJ`epq?qnsuWiemdP+0OS^9yZt zsbFoR`Ab&!YMgT8B*g}KoBmYZm}xG*Au2=2EBUDGHx^2)!_X+Gn_^P4m9Tv?>6OQZ zL>`i)`!Sp_q{#V=a6j=8mn{WkINtqSSC6y|E5O6`ldo#

YJAmoRLUs*4My8DGvjt47%#lUps#XGD|G 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 Ping + @@ -100,19 +103,19 @@ -

+
-
+
-
+
@@ -159,12 +162,7 @@
- +
@@ -198,22 +196,7 @@
- +
@@ -246,646 +229,639 @@ - -
+ +
- -
+ +
- - - - - + + + - -
- - + + + -

{{ $t("Advanced") }}

+ +
+ + +
-
- - -
-
+
+ + +
+ {{ $t("retriesDescription") }}
+
-
- - +
+ + +
+ + +
+ + +
+ +
+ + +
+ +

{{ $t("Advanced") }}

+ +
+ + +
+
-
- - +
+ + +
+ +
+ + +
+ {{ $t("upsideDownModeDescription") }} +
+
+ +
+ + +
+ {{ $t("gamedigGuessPortDescription") }} +
+
+ + +
+ + +
+ + + - -
- - -
+ +
+ + +
- - +
+
- -
- - -
+ +

{{ $t("Notifications") }}

+

+ {{ $t("Not available, please setup.") }} +

- -
- - -
+
+ -
- -
+ + + {{ $t("Default") }}
-
-
+ - -

{{ $t("Notifications") }}

-

+ +

+

{{ $t("Proxy") }}

+

{{ $t("Not available, please setup.") }}

-
- +
+ + +
+ +
+ -
- +
- -
-

{{ $t("Proxy") }}

-

- {{ $t("Not available, please setup.") }} -

- -
- - + + + -
- + +