Update On Wed Nov 26 19:35:55 CET 2025

This commit is contained in:
github-action[bot]
2025-11-26 19:35:56 +01:00
parent ee7416bae7
commit 5f24d5979b
38 changed files with 505 additions and 261 deletions

1
.github/update.log vendored
View File

@@ -1193,3 +1193,4 @@ Update On Sat Nov 22 19:36:29 CET 2025
Update On Sun Nov 23 19:36:55 CET 2025
Update On Mon Nov 24 19:40:17 CET 2025
Update On Tue Nov 25 19:40:43 CET 2025
Update On Wed Nov 26 19:35:47 CET 2025

View File

@@ -289,7 +289,7 @@ func (d *Decoder) decodeBool(name string, data any, val reflect.Value) (err erro
case isInt(kind) && d.option.WeaklyTypedInput:
val.SetBool(dataVal.Int() != 0)
case isUint(kind) && d.option.WeaklyTypedInput:
val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
val.SetBool(dataVal.Uint() != 0)
default:
err = fmt.Errorf(
"'%s' expected type '%s', got unconvertible type '%s'",

View File

@@ -355,7 +355,7 @@ dependencies = [
"objc2-foundation 0.3.2",
"parking_lot",
"percent-encoding",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
"wl-clipboard-rs",
"x11rb",
]
@@ -2853,7 +2853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -5334,14 +5334,15 @@ dependencies = [
[[package]]
name = "mlua"
version = "0.11.4"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be1c2bfc684b8a228fbaebf954af7a47a98ec27721986654a4cc2c40a20cc7e"
checksum = "935ac67539907efcd7198137eb7358e052555f77fe1b2916600a2249351f2b33"
dependencies = [
"bstr",
"either",
"erased-serde",
"futures-util",
"libc",
"mlua-sys",
"num-traits",
"parking_lot",
@@ -5353,9 +5354,9 @@ dependencies = [
[[package]]
name = "mlua-sys"
version = "0.8.3"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d4dc9cfc5a7698899802e97480617d9726f7da78c910db989d4d0fd4991d900"
checksum = "8c968af21bf6b19fc9ca8e7b85ee16f86e4c9e3d0591de101a5608086bda0ad8"
dependencies = [
"cc",
"cfg-if",
@@ -6333,9 +6334,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "open"
version = "5.3.2"
version = "5.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95"
checksum = "43bb73a7fa3799b198970490a51174027ba0d4ec504b03cd08caf513d40024bc"
dependencies = [
"dunce",
"is-wsl",
@@ -7383,7 +7384,7 @@ dependencies = [
"once_cell",
"socket2",
"tracing",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -7937,7 +7938,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.4.15",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -7950,7 +7951,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.9.4",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -9606,7 +9607,7 @@ dependencies = [
"getrandom 0.3.3",
"once_cell",
"rustix 1.0.8",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]

View File

@@ -82,7 +82,7 @@ importers:
version: 4.5.5(@vueuse/core@14.0.0(vue@3.5.25(typescript@5.9.3)))(@vueuse/integrations@14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.25(typescript@5.9.3))
vue-i18n:
specifier: ^11.1.10
version: 11.2.1(vue@3.5.25(typescript@5.9.3))
version: 11.2.2(vue@3.5.25(typescript@5.9.3))
vue-lazyload:
specifier: ^3.0.0
version: 3.0.0
@@ -98,7 +98,7 @@ importers:
devDependencies:
'@intlify/unplugin-vue-i18n':
specifier: ^11.0.1
version: 11.0.1(@vue/compiler-dom@3.5.25)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
version: 11.0.1(@vue/compiler-dom@3.5.25)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
'@tsconfig/node24':
specifier: ^24.0.2
version: 24.0.3
@@ -110,7 +110,7 @@ importers:
version: 24.10.1
'@typescript-eslint/eslint-plugin':
specifier: ^8.37.0
version: 8.47.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)
version: 8.48.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)
'@vitejs/plugin-legacy':
specifier: ^7.2.1
version: 7.2.1(terser@5.44.1)(vite@7.2.4(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0))
@@ -122,7 +122,7 @@ importers:
version: 10.2.0(eslint@9.39.1)(prettier@3.6.2)
'@vue/eslint-config-typescript':
specifier: ^14.6.0
version: 14.6.0(eslint-plugin-vue@10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)
version: 14.6.0(eslint-plugin-vue@10.6.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)
'@vue/tsconfig':
specifier: ^0.8.1
version: 0.8.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))
@@ -140,7 +140,7 @@ importers:
version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2)
eslint-plugin-vue:
specifier: ^10.5.1
version: 10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1))
version: 10.6.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1))
postcss:
specifier: ^8.5.6
version: 8.5.6
@@ -887,20 +887,20 @@ packages:
vue-i18n:
optional: true
'@intlify/core-base@11.2.1':
resolution: {integrity: sha512-2V1A4yaN9ElAnQ6ih3HHEc+jZ+sHV6BlQHjCsnIVlOotL5NCUgJElIxgUFiJs6zV4puoAq3hHuQIfWNp+J+8yQ==}
'@intlify/core-base@11.2.2':
resolution: {integrity: sha512-0mCTBOLKIqFUP3BzwuFW23hYEl9g/wby6uY//AC5hTgQfTsM2srCYF2/hYGp+a5DZ/HIFIgKkLJMzXTt30r0JQ==}
engines: {node: '>= 16'}
'@intlify/message-compiler@11.2.1':
resolution: {integrity: sha512-J2454D3Agg3Kvgaj14gxTleJU8/H06Sisz7C2BwiHF0/i5Soyfb5ySpwn8GCL6yscDbOGj6xM+lUe6gO6BFQyg==}
'@intlify/message-compiler@11.2.2':
resolution: {integrity: sha512-XS2p8Ff5JxWsKhgfld4/MRQzZRQ85drMMPhb7Co6Be4ZOgqJX1DzcZt0IFgGTycgqL8rkYNwgnD443Q+TapOoA==}
engines: {node: '>= 16'}
'@intlify/shared@11.1.12':
resolution: {integrity: sha512-Om86EjuQtA69hdNj3GQec9ZC0L0vPSAnXzB3gP/gyJ7+mA7t06d9aOAiqMZ+xEOsumGP4eEBlfl8zF2LOTzf2A==}
engines: {node: '>= 16'}
'@intlify/shared@11.2.1':
resolution: {integrity: sha512-O67LZM4dbfr70WCsZLW+g+pIXdgQ66laLVd/FicW7iYgP/RuH0X1FDGSh+Hr9Gou/8TeldUE6KmTGdLwX2ufIA==}
'@intlify/shared@11.2.2':
resolution: {integrity: sha512-OtCmyFpSXxNu/oET/aN6HtPCbZ01btXVd0f3w00YsHOb13Kverk1jzA2k47pAekM55qbUw421fvPF1yxZ+gicw==}
engines: {node: '>= 16'}
'@intlify/unplugin-vue-i18n@11.0.1':
@@ -1127,11 +1127,11 @@ packages:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/eslint-plugin@8.47.0':
resolution: {integrity: sha512-fe0rz9WJQ5t2iaLfdbDc9T80GJy0AeO453q8C3YCilnGozvOyCG5t+EZtg7j7D88+c3FipfP/x+wzGnh1xp8ZA==}
'@typescript-eslint/eslint-plugin@8.48.0':
resolution: {integrity: sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
'@typescript-eslint/parser': ^8.47.0
'@typescript-eslint/parser': ^8.48.0
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
@@ -1154,8 +1154,8 @@ packages:
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/project-service@8.47.0':
resolution: {integrity: sha512-2X4BX8hUeB5JcA1TQJ7GjcgulXQ+5UkNb0DL8gHsHUHdFoiCTJoYLTpib3LtSDPZsRET5ygN4qqIWrHyYIKERA==}
'@typescript-eslint/project-service@8.48.0':
resolution: {integrity: sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
@@ -1168,8 +1168,8 @@ packages:
resolution: {integrity: sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/scope-manager@8.47.0':
resolution: {integrity: sha512-a0TTJk4HXMkfpFkL9/WaGTNuv7JWfFTQFJd6zS9dVAjKsojmv9HT55xzbEpnZoY+VUb+YXLMp+ihMLz/UlZfDg==}
'@typescript-eslint/scope-manager@8.48.0':
resolution: {integrity: sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/tsconfig-utils@8.37.0':
@@ -1184,8 +1184,8 @@ packages:
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/tsconfig-utils@8.47.0':
resolution: {integrity: sha512-ybUAvjy4ZCL11uryalkKxuT3w3sXJAuWhOoGS3T/Wu+iUu1tGJmk5ytSY8gbdACNARmcYEB0COksD2j6hfGK2g==}
'@typescript-eslint/tsconfig-utils@8.48.0':
resolution: {integrity: sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
@@ -1197,8 +1197,8 @@ packages:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/type-utils@8.47.0':
resolution: {integrity: sha512-QC9RiCmZ2HmIdCEvhd1aJELBlD93ErziOXXlHEZyuBo3tBiAZieya0HLIxp+DoDWlsQqDawyKuNEhORyku+P8A==}
'@typescript-eslint/type-utils@8.48.0':
resolution: {integrity: sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -1212,8 +1212,8 @@ packages:
resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/types@8.47.0':
resolution: {integrity: sha512-nHAE6bMKsizhA2uuYZbEbmp5z2UpffNrPEqiKIeN7VsV6UY/roxanWfoRrf6x/k9+Obf+GQdkm0nPU+vnMXo9A==}
'@typescript-eslint/types@8.48.0':
resolution: {integrity: sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@8.37.0':
@@ -1228,8 +1228,8 @@ packages:
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/typescript-estree@8.47.0':
resolution: {integrity: sha512-k6ti9UepJf5NpzCjH31hQNLHQWupTRPhZ+KFF8WtTuTpy7uHPfeg2NM7cP27aCGajoEplxJDFVCEm9TGPYyiVg==}
'@typescript-eslint/typescript-estree@8.48.0':
resolution: {integrity: sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
@@ -1241,8 +1241,8 @@ packages:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/utils@8.47.0':
resolution: {integrity: sha512-g7XrNf25iL4TJOiPqatNuaChyqt49a/onq5YsJ9+hXeugK+41LVg7AxikMfM02PC6jbNtZLCJj6AUcQXJS/jGQ==}
'@typescript-eslint/utils@8.48.0':
resolution: {integrity: sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -1256,8 +1256,8 @@ packages:
resolution: {integrity: sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/visitor-keys@8.47.0':
resolution: {integrity: sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ==}
'@typescript-eslint/visitor-keys@8.48.0':
resolution: {integrity: sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@videojs/http-streaming@3.17.2':
@@ -1668,8 +1668,8 @@ packages:
eslint-config-prettier:
optional: true
eslint-plugin-vue@10.6.0:
resolution: {integrity: sha512-TsoFluWxOpsJlE/l2jJygLQLWBPJ3Qdkesv7tBIunICbTcG0dS1/NBw/Ol4tJw5kHWlAVds4lUmC29/vlPUcEQ==}
eslint-plugin-vue@10.6.1:
resolution: {integrity: sha512-OMvDAFbewocYrJamF1EoSWoT4xa7/QRb/yYouEZMiroTE+WRmFUreR+kAFQHqM45W3kg5oljVfUYfH9HEwX1Bg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
'@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
@@ -2496,8 +2496,8 @@ packages:
focus-trap: '>=7.2.0'
vue: '>=3.2.0'
vue-i18n@11.2.1:
resolution: {integrity: sha512-cc3Wx4eJZac9WMS8mxhfYiCipm9PBQ2Dz15piWYm7DwNcCehaKRgpolEdiqrjjT27T3Wijz3xJ7NeIc8ofIWAA==}
vue-i18n@11.2.2:
resolution: {integrity: sha512-ULIKZyRluUPRCZmihVgUvpq8hJTtOqnbGZuv4Lz+byEKZq4mU0g92og414l6f/4ju+L5mORsiUuEPYrAuX2NJg==}
engines: {node: '>= 16'}
peerDependencies:
vue: ^3.0.0
@@ -3359,9 +3359,9 @@ snapshots:
'@humanwhocodes/retry@0.4.3': {}
'@intlify/bundle-utils@11.0.1(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))':
'@intlify/bundle-utils@11.0.1(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))':
dependencies:
'@intlify/message-compiler': 11.2.1
'@intlify/message-compiler': 11.2.2
'@intlify/shared': 11.1.12
acorn: 8.15.0
esbuild: 0.25.12
@@ -3371,28 +3371,28 @@ snapshots:
source-map-js: 1.2.1
yaml-eslint-parser: 1.2.3
optionalDependencies:
vue-i18n: 11.2.1(vue@3.5.25(typescript@5.9.3))
vue-i18n: 11.2.2(vue@3.5.25(typescript@5.9.3))
'@intlify/core-base@11.2.1':
'@intlify/core-base@11.2.2':
dependencies:
'@intlify/message-compiler': 11.2.1
'@intlify/shared': 11.2.1
'@intlify/message-compiler': 11.2.2
'@intlify/shared': 11.2.2
'@intlify/message-compiler@11.2.1':
'@intlify/message-compiler@11.2.2':
dependencies:
'@intlify/shared': 11.2.1
'@intlify/shared': 11.2.2
source-map-js: 1.2.1
'@intlify/shared@11.1.12': {}
'@intlify/shared@11.2.1': {}
'@intlify/shared@11.2.2': {}
'@intlify/unplugin-vue-i18n@11.0.1(@vue/compiler-dom@3.5.25)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))':
'@intlify/unplugin-vue-i18n@11.0.1(@vue/compiler-dom@3.5.25)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))':
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
'@intlify/bundle-utils': 11.0.1(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))
'@intlify/bundle-utils': 11.0.1(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))
'@intlify/shared': 11.1.12
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.25)(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.25)(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
'@rollup/pluginutils': 5.3.0(rollup@4.53.3)
'@typescript-eslint/scope-manager': 8.46.4
'@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3)
@@ -3403,7 +3403,7 @@ snapshots:
unplugin: 2.3.10
vue: 3.5.25(typescript@5.9.3)
optionalDependencies:
vue-i18n: 11.2.1(vue@3.5.25(typescript@5.9.3))
vue-i18n: 11.2.2(vue@3.5.25(typescript@5.9.3))
transitivePeerDependencies:
- '@vue/compiler-dom'
- eslint
@@ -3411,14 +3411,14 @@ snapshots:
- supports-color
- typescript
'@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.25)(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))':
'@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.25)(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))':
dependencies:
'@babel/parser': 7.28.5
optionalDependencies:
'@intlify/shared': 11.1.12
'@vue/compiler-dom': 3.5.25
vue: 3.5.25(typescript@5.9.3)
vue-i18n: 11.2.1(vue@3.5.25(typescript@5.9.3))
vue-i18n: 11.2.2(vue@3.5.25(typescript@5.9.3))
'@jridgewell/gen-mapping@0.3.13':
dependencies:
@@ -3576,14 +3576,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/eslint-plugin@8.47.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)':
'@typescript-eslint/eslint-plugin@8.48.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
'@typescript-eslint/parser': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.47.0
'@typescript-eslint/type-utils': 8.47.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/utils': 8.47.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.47.0
'@typescript-eslint/scope-manager': 8.48.0
'@typescript-eslint/type-utils': 8.48.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/utils': 8.48.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.48.0
eslint: 9.39.1
graphemer: 1.4.0
ignore: 7.0.5
@@ -3623,10 +3623,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/project-service@8.47.0(typescript@5.9.3)':
'@typescript-eslint/project-service@8.48.0(typescript@5.9.3)':
dependencies:
'@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.9.3)
'@typescript-eslint/types': 8.47.0
'@typescript-eslint/tsconfig-utils': 8.48.0(typescript@5.9.3)
'@typescript-eslint/types': 8.48.0
debug: 4.4.3
typescript: 5.9.3
transitivePeerDependencies:
@@ -3642,10 +3642,10 @@ snapshots:
'@typescript-eslint/types': 8.46.4
'@typescript-eslint/visitor-keys': 8.46.4
'@typescript-eslint/scope-manager@8.47.0':
'@typescript-eslint/scope-manager@8.48.0':
dependencies:
'@typescript-eslint/types': 8.47.0
'@typescript-eslint/visitor-keys': 8.47.0
'@typescript-eslint/types': 8.48.0
'@typescript-eslint/visitor-keys': 8.48.0
'@typescript-eslint/tsconfig-utils@8.37.0(typescript@5.9.3)':
dependencies:
@@ -3655,7 +3655,7 @@ snapshots:
dependencies:
typescript: 5.9.3
'@typescript-eslint/tsconfig-utils@8.47.0(typescript@5.9.3)':
'@typescript-eslint/tsconfig-utils@8.48.0(typescript@5.9.3)':
dependencies:
typescript: 5.9.3
@@ -3671,11 +3671,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/type-utils@8.47.0(eslint@9.39.1)(typescript@5.9.3)':
'@typescript-eslint/type-utils@8.48.0(eslint@9.39.1)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/types': 8.47.0
'@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.47.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/types': 8.48.0
'@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.48.0(eslint@9.39.1)(typescript@5.9.3)
debug: 4.4.3
eslint: 9.39.1
ts-api-utils: 2.1.0(typescript@5.9.3)
@@ -3687,7 +3687,7 @@ snapshots:
'@typescript-eslint/types@8.46.4': {}
'@typescript-eslint/types@8.47.0': {}
'@typescript-eslint/types@8.48.0': {}
'@typescript-eslint/typescript-estree@8.37.0(typescript@5.9.3)':
dependencies:
@@ -3721,17 +3721,16 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/typescript-estree@8.47.0(typescript@5.9.3)':
'@typescript-eslint/typescript-estree@8.48.0(typescript@5.9.3)':
dependencies:
'@typescript-eslint/project-service': 8.47.0(typescript@5.9.3)
'@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.9.3)
'@typescript-eslint/types': 8.47.0
'@typescript-eslint/visitor-keys': 8.47.0
'@typescript-eslint/project-service': 8.48.0(typescript@5.9.3)
'@typescript-eslint/tsconfig-utils': 8.48.0(typescript@5.9.3)
'@typescript-eslint/types': 8.48.0
'@typescript-eslint/visitor-keys': 8.48.0
debug: 4.4.3
fast-glob: 3.3.3
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.7.3
tinyglobby: 0.2.15
ts-api-utils: 2.1.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
@@ -3748,12 +3747,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@8.47.0(eslint@9.39.1)(typescript@5.9.3)':
'@typescript-eslint/utils@8.48.0(eslint@9.39.1)(typescript@5.9.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
'@typescript-eslint/scope-manager': 8.47.0
'@typescript-eslint/types': 8.47.0
'@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.48.0
'@typescript-eslint/types': 8.48.0
'@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3)
eslint: 9.39.1
typescript: 5.9.3
transitivePeerDependencies:
@@ -3769,9 +3768,9 @@ snapshots:
'@typescript-eslint/types': 8.46.4
eslint-visitor-keys: 4.2.1
'@typescript-eslint/visitor-keys@8.47.0':
'@typescript-eslint/visitor-keys@8.48.0':
dependencies:
'@typescript-eslint/types': 8.47.0
'@typescript-eslint/types': 8.48.0
eslint-visitor-keys: 4.2.1
'@videojs/http-streaming@3.17.2(video.js@8.23.4)':
@@ -3892,11 +3891,11 @@ snapshots:
transitivePeerDependencies:
- '@types/eslint'
'@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)':
'@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.6.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/utils': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
eslint: 9.39.1
eslint-plugin-vue: 10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1))
eslint-plugin-vue: 10.6.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1))
fast-glob: 3.3.3
typescript-eslint: 8.37.0(eslint@9.39.1)(typescript@5.9.3)
vue-eslint-parser: 10.2.0(eslint@9.39.1)
@@ -4229,7 +4228,7 @@ snapshots:
optionalDependencies:
eslint-config-prettier: 10.1.8(eslint@9.39.1)
eslint-plugin-vue@10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)):
eslint-plugin-vue@10.6.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)):
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
eslint: 9.39.1
@@ -5021,10 +5020,10 @@ snapshots:
focus-trap: 7.6.2
vue: 3.5.25(typescript@5.9.3)
vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)):
vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)):
dependencies:
'@intlify/core-base': 11.2.1
'@intlify/shared': 11.2.1
'@intlify/core-base': 11.2.2
'@intlify/shared': 11.2.2
'@vue/devtools-api': 6.6.4
vue: 3.5.25(typescript@5.9.3)

View File

@@ -102,7 +102,7 @@
"username": "Korisničko ime",
"usernameTaken": "Korisničko ime zauzeto",
"wrongCredentials": "Neispravno korisničko ime/lozinka",
"passwordTooShort": "Password must be at least {min} characters",
"passwordTooShort": "Lozinka mora sadržavati minimalno {min} znakova",
"logout_reasons": {
"inactivity": "Odjavljeni ste zbog neaktivnosti."
}
@@ -167,7 +167,7 @@
"allowNew": "Stvori nove datoteke i mape",
"allowPublish": "Objavi nove objave i stranice",
"allowSignup": "Dopusti registraciju korisnicima",
"hideLoginButton": "Hide the login button from public pages",
"hideLoginButton": "Sakrij tipku za prijavu s javnih stranica",
"avoidChanges": "(ostavite prazno kako biste izbjegli promjene)",
"branding": "Brendiranje",
"brandingDirectoryPath": "Put brendiranja",

View File

@@ -90,7 +90,7 @@
// MAC1 ---SGMII---> QCA8337 SerDes
&dp2 {
status = "okay";
nvmem-cells = <&macaddr_dp2>;
nvmem-cells = <&macaddr_dp2 0>;
nvmem-cell-names = "mac-address";
fixed-link {
@@ -230,11 +230,8 @@
compatible = "qcom,smem-part";
partition-0-art {
compatible = "fixed-partitions";
label = "0:ART";
label = "0:art";
read-only;
#address-cells = <1>;
#size-cells = <1>;
nvmem-layout {
compatible = "fixed-layout";
@@ -244,7 +241,7 @@
macaddr_dp2: macaddr@0 {
compatible = "mac-base";
#nvmem-cell-cells = <1>;
reg = <0x0 0x6>;
reg = <0x6 0x6>;
};
};
};

View File

@@ -683,7 +683,7 @@ func (m *Mux) maybePickExistingUnderlay() Underlay {
// cleanUnderlay removes closed underlays.
// This method MUST be called only when holding the mu lock.
func (m *Mux) cleanUnderlay(alsoDisableIdleUnderlay bool) {
func (m *Mux) cleanUnderlay(alsoDisableIdleOrOverloadUnderlay bool) {
remaining := make([]Underlay, 0)
disable := 0
close := 0
@@ -691,11 +691,24 @@ func (m *Mux) cleanUnderlay(alsoDisableIdleUnderlay bool) {
select {
case <-underlay.Done():
default:
if alsoDisableIdleUnderlay && underlay.SessionCount() == 0 {
if underlay.Scheduler().TryDisable() {
if alsoDisableIdleOrOverloadUnderlay {
// Disable idle underlay.
if underlay.SessionCount() == 0 {
if underlay.Scheduler().TryDisableIdle() {
disable++
}
}
// Disable overloaded underlay.
// If multiplexFactor is 1, the limit is 1 GiB.
var trafficVolumeLimit int64 = 512 * 1024 * 1024 << m.multiplexFactor
if underlay.Scheduler().DisableTime().IsZero() && (underlay.InBytes() > trafficVolumeLimit || underlay.OutBytes() > trafficVolumeLimit) {
underlay.Scheduler().SetRemainingTime(0)
disable++
}
}
// Close idle underlay.
if underlay.SessionCount() == 0 && underlay.Scheduler().Idle() {
underlay.Close()
close++

View File

@@ -57,6 +57,13 @@ func (c *ScheduleController) DecPending() {
c.lastScheduleTime = time.Now()
}
// DisableTime returns the underlay disable time.
func (c *ScheduleController) DisableTime() time.Time {
c.mu.Lock()
defer c.mu.Unlock()
return c.disableTime
}
// IsDisabled returns true if scheduling new sessions to the underlay is disabled.
func (c *ScheduleController) IsDisabled() bool {
c.mu.Lock()
@@ -71,8 +78,8 @@ func (c *ScheduleController) Idle() bool {
return !c.disableTime.IsZero() && time.Since(c.lastScheduleTime) > scheduleIdleTime && time.Since(c.disableTime) > scheduleIdleTime
}
// TryDisable tries to disable scheduling new sessions.
func (c *ScheduleController) TryDisable() (successful bool) {
// TryDisableIdle tries to disable scheduling new sessions on idle underlay.
func (c *ScheduleController) TryDisableIdle() (ok bool) {
c.mu.Lock()
defer c.mu.Unlock()
if !c.disableTime.IsZero() {
@@ -88,12 +95,12 @@ func (c *ScheduleController) TryDisable() (successful bool) {
return true
}
// SetRemainingTime disables the scheduler after the given duration.
// SetRemainingTime unconditionally disables the scheduler after the given duration.
// Do nothing if the scheduler has already been disabled.
func (c *ScheduleController) SetRemainingTime(d time.Duration) {
c.mu.Lock()
defer c.mu.Unlock()
if d <= 0 || !c.disableTime.IsZero() {
if d < 0 || !c.disableTime.IsZero() {
return
}
c.disableTime = time.Now().Add(d)

View File

@@ -72,6 +72,12 @@ type Underlay interface {
// Returns detailed information of all the sessions.
SessionInfos() []*appctlpb.SessionInfo
// Number of bytes received from the network.
InBytes() int64
// Number of bytes sent to the network.
OutBytes() int64
// Run event loop.
// The underlay needs to be closed when this returns.
RunEventLoop(context.Context) error

View File

@@ -21,6 +21,7 @@ import (
"io"
"net"
"sync"
"sync/atomic"
"time"
"github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
@@ -52,6 +53,9 @@ type baseUnderlay struct {
sendMutex sync.Mutex // protect writing data to the connection
closeMutex sync.Mutex // protect closing the connection
inBytes atomic.Int64
outBytes atomic.Int64
// ---- client fields ----
scheduler *ScheduleController
}
@@ -193,6 +197,14 @@ func (b *baseUnderlay) SessionInfos() []*appctlpb.SessionInfo {
return res
}
func (b *baseUnderlay) InBytes() int64 {
return b.inBytes.Load()
}
func (b *baseUnderlay) OutBytes() int64 {
return b.outBytes.Load()
}
func (b *baseUnderlay) RunEventLoop(ctx context.Context) error {
return stderror.ErrUnsupported
}

View File

@@ -356,6 +356,7 @@ func (u *PacketUnderlay) readOneSegment() error {
continue
}
b = b[:n]
u.inBytes.Add(int64(n))
if u.isClient {
metrics.DownloadBytes.Add(int64(n))
} else {
@@ -692,6 +693,7 @@ func (u *PacketUnderlay) writeOneSegment(seg *segment, addr net.Addr) error {
if _, err := u.conn.WriteTo(dataToSend, addr); err != nil {
return fmt.Errorf("WriteTo() failed: %w", err)
}
u.outBytes.Add(int64(len(dataToSend)))
if u.isClient {
metrics.UploadBytes.Add(int64(len(dataToSend)))
} else {
@@ -731,6 +733,7 @@ func (u *PacketUnderlay) writeOneSegment(seg *segment, addr net.Addr) error {
if _, err := u.conn.WriteTo(dataToSend, addr); err != nil {
return fmt.Errorf("WriteTo() failed: %w", err)
}
u.outBytes.Add(int64(len(dataToSend)))
if u.isClient {
metrics.UploadBytes.Add(int64(len(dataToSend)))
} else {

View File

@@ -305,6 +305,7 @@ func (t *StreamUnderlay) readOneSegment() (*segment, error) {
err = fmt.Errorf("metadata: read %d bytes from StreamUnderlay failed: %w", readLen, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
}
t.inBytes.Add(int64(len(encryptedMeta)))
if t.isClient {
metrics.DownloadBytes.Add(int64(len(encryptedMeta)))
} else {
@@ -398,6 +399,7 @@ func (t *StreamUnderlay) readSessionSegment(ss *sessionStruct) (*segment, error)
err = fmt.Errorf("payload: read %d bytes from StreamUnderlay failed: %w", ss.payloadLen+cipher.DefaultOverhead, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
}
t.inBytes.Add(int64(len(encryptedPayload)))
if t.isClient {
metrics.DownloadBytes.Add(int64(len(encryptedPayload)))
} else {
@@ -428,6 +430,7 @@ func (t *StreamUnderlay) readSessionSegment(ss *sessionStruct) (*segment, error)
err = fmt.Errorf("padding: read %d bytes from StreamUnderlay failed: %w", ss.suffixLen, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
}
t.inBytes.Add(int64(len(padding)))
if t.isClient {
metrics.DownloadBytes.Add(int64(len(padding)))
} else {
@@ -453,6 +456,7 @@ func (t *StreamUnderlay) readDataAckSegment(das *dataAckStruct) (*segment, error
err = fmt.Errorf("padding: read %d bytes from StreamUnderlay failed: %w", das.prefixLen, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
}
t.inBytes.Add(int64(len(padding1)))
if t.isClient {
metrics.DownloadBytes.Add(int64(len(padding1)))
} else {
@@ -465,6 +469,7 @@ func (t *StreamUnderlay) readDataAckSegment(das *dataAckStruct) (*segment, error
err = fmt.Errorf("payload: read %d bytes from StreamUnderlay failed: %w", das.payloadLen+cipher.DefaultOverhead, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
}
t.inBytes.Add(int64(len(encryptedPayload)))
if t.isClient {
metrics.DownloadBytes.Add(int64(len(encryptedPayload)))
} else {
@@ -495,6 +500,7 @@ func (t *StreamUnderlay) readDataAckSegment(das *dataAckStruct) (*segment, error
err = fmt.Errorf("padding: read %d bytes from StreamUnderlay failed: %w", das.suffixLen, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
}
t.inBytes.Add(int64(len(padding2)))
if t.isClient {
metrics.DownloadBytes.Add(int64(len(padding2)))
} else {
@@ -549,6 +555,7 @@ func (t *StreamUnderlay) writeOneSegment(seg *segment) error {
if _, err := t.conn.Write(dataToSend); err != nil {
return fmt.Errorf("Write() failed: %w", err)
}
t.outBytes.Add(int64(len(dataToSend)))
if t.isClient {
metrics.UploadBytes.Add(int64(len(dataToSend)))
} else {
@@ -590,6 +597,7 @@ func (t *StreamUnderlay) writeOneSegment(seg *segment) error {
if _, err := t.conn.Write(dataToSend); err != nil {
return fmt.Errorf("Write() failed: %w", err)
}
t.outBytes.Add(int64(len(dataToSend)))
if t.isClient {
metrics.UploadBytes.Add(int64(len(dataToSend)))
} else {

View File

@@ -289,7 +289,7 @@ func (d *Decoder) decodeBool(name string, data any, val reflect.Value) (err erro
case isInt(kind) && d.option.WeaklyTypedInput:
val.SetBool(dataVal.Int() != 0)
case isUint(kind) && d.option.WeaklyTypedInput:
val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
val.SetBool(dataVal.Uint() != 0)
default:
err = fmt.Errorf(
"'%s' expected type '%s', got unconvertible type '%s'",

View File

@@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ddns-go
PKG_VERSION:=6.13.2
PKG_VERSION:=6.13.3
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/jeessy2/ddns-go/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=a729096b6d0d769223a21dfd82040b264d6f672d6018d08157f400de321d381e
PKG_HASH:=b2b6e48988abec12bba37ac9fb2f9a6777d28125c0ab2ac3be1d8659b8b7b9a5
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE

File diff suppressed because one or more lines are too long

View File

@@ -216,7 +216,7 @@ o.cfgvalue = function(t, n)
str = str ~= "" and "<br>" .. str or ""
local num = 0
m.uci:foreach(appname, "nodes", function(s)
if s["group"] ~= "" and s["group"] == remark then
if s["group"] and s["group"]:lower() == remark:lower() then
num = num + 1
end
end)

View File

@@ -1,6 +1,7 @@
<%
local api = require "luci.passwall.api"
-%>
<script src="<%=resource%>/view/<%=api.appname%>/Sortable.min.js"></script>
<style>
table th, .table .th {
@@ -66,7 +67,34 @@ table td, .table .td {
margin-right: 0 !important;
}
.node-wrapper .drag-handle {
cursor: grab !important;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 18px;
padding: 0 !important;
line-height: inherit;
user-select: none;
height: 32px !important;
width: 32px;
min-width: 32px;
}
.sortable-chosen {
background-color: rgba(220, 235, 245, 0.4) !important;
opacity: 0.7;
}
.sortable-ghost {
background: #cce5ff !important;
height: 3px !important;
}
.dragging-row {
background-color: rgba(131, 191, 255, 0.7) !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
</style>
<% if api.is_js_luci() then -%>
@@ -210,21 +238,6 @@ table td, .table .td {
document.getElementById("set_node_name").innerHTML = "";
}
function row_swap(btn, up) {
const row = btn.closest("tr");
if (!row) return;
const parent = row.parentNode;
if (up) {
const prev = row.previousElementSibling;
if (prev && !prev.classList.contains("cbi-section-table-titles")) {
parent.insertBefore(row, prev);
}
} else {
const next = row.nextElementSibling;
if (next) parent.insertBefore(next, row);
}
}
function row_top(btn) {
const row = btn.closest("tr");
if (!row) return;
@@ -548,6 +561,60 @@ table td, .table .td {
}
}
}
//列表拖动重排
function initSortableForTable(table) {
if (!table) return null;
var root = table.querySelector('tbody') || table;
if (root._sortable_initialized) return root._sortable_instance;
root._sortable_initialized = true;
var opts = {
handle: ".drag-handle",
draggable: "tr.cbi-section-table-row",
animation: 150,
ghostClass: "dragging-row",
fallbackOnBody: true,
forceFallback: false,
swapThreshold: 0.65,
onEnd: function (evt) {
//var group = evt.to.id.replace("cbi-passwall-nodes-", "").replace("-table", "");
//save_current_page_order(group); // 自动提交保存
}
};
try {
var instance = Sortable.create(root, opts);
root._sortable_instance = instance;
return instance;
} catch (err) {
root._sortable_initialized = false;
console.error("Sortable init failed:", err);
return null;
}
}
function initAllSortable(group_nodes) {
if (typeof Sortable === 'undefined') {
var retries = 0;
var maxRetries = 25;
var t = setInterval(function () {
retries++;
if (typeof Sortable !== 'undefined') {
clearInterval(t);
for (var group in group_nodes) {
var table = document.getElementById("cbi-passwall-nodes-" + group + "-table");
initSortableForTable(table);
}
} else if (retries >= maxRetries) {
clearInterval(t);
}
}, 200);
} else {
for (var group in group_nodes) {
var table = document.getElementById("cbi-passwall-nodes-" + group + "-table");
initSortableForTable(table);
}
}
}
</script>
<script type="text/template" id="nodes-table-template">
@@ -584,10 +651,9 @@ table td, .table .td {
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:To Top%>" onclick="row_top(this)" title="<%:To Top%>"/>
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_{{id}}" onclick="open_set_node_div('{{id}}')"/>
<input class="btn cbi-button cbi-button-add" type="button" value="<%:Copy%>" onclick="copy_node('{{id}}')"/>
<input class="btn cbi-button cbi-button-up" type="button" value="<%:Move up%>" onclick="return row_swap(this, true)" title="<%:Move up%>">
<input class="btn cbi-button cbi-button-down" type="button" value="<%:Move down%>" onclick="return row_swap(this, false)" title="<%:Move down%>">
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=api.url("node_config")%>/{{id}}'" alt="<%:Edit%>" title="<%:Edit%>">
<input class="btn cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="del_node('{{id}}')" alt="<%:Delete%>" title="<%:Delete%>">
<input class="cbi-button drag-handle center" type="button" value="☰" title="<%:Drag to reorder%>"/>
</div>
</td>
</tr>
@@ -749,6 +815,8 @@ table td, .table .td {
cbi_t_switch("passwall.nodes", default_group)
}
initAllSortable(group_nodes);
//clear expire data
if (localStorage && localStorage.length > 0) {
const now = Date.now();

View File

@@ -427,6 +427,9 @@ msgstr "保存当前顺序"
msgid "Saved current page order successfully."
msgstr "保存当前页面顺序成功。"
msgid "Drag to reorder"
msgstr "拖动以重排"
msgid "Type"
msgstr "类型"

View File

@@ -504,8 +504,8 @@ local function processData(szType, content, add_mode, group)
end
result.obfs_param = base64Decode(params.obfsparam)
result.protocol_param = base64Decode(params.protoparam)
local group = base64Decode(params.group)
if group then result.group = group end
-- local ssr_group = base64Decode(params.group)
-- if ssr_group then result.ssr_group = ssr_group end
result.remarks = base64Decode(params.remarks)
elseif szType == 'vmess' then
local info = jsonParse(content)

View File

@@ -83,6 +83,7 @@ function index()
entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true
entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true
entry({"admin", "services", appname, "get_node"}, call("get_node")).leaf = true
entry({"admin", "services", appname, "save_node_order"}, call("save_node_order")).leaf = true
entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true
entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true
entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true
@@ -591,13 +592,12 @@ function delete_select_nodes()
end
end
function get_node()
local id = http.formvalue("id")
local result = {}
local show_node_info = api.uci_get_type("global_other", "show_node_info", "0")
function add_is_ipv6_key(o)
local function add_is_ipv6_key(o)
if o and o.address and show_node_info == "1" then
local f = api.get_ipv6_full(o.address)
if f ~= "" then
@@ -611,14 +611,35 @@ function get_node()
result = uci:get_all(appname, id)
add_is_ipv6_key(result)
else
local default_nodes = {}
local other_nodes = {}
uci:foreach(appname, "nodes", function(t)
add_is_ipv6_key(t)
result[#result + 1] = t
if not t.group or t.group == "" then
default_nodes[#default_nodes + 1] = t
else
other_nodes[#other_nodes + 1] = t
end
end)
for i = 1, #default_nodes do result[#result + 1] = default_nodes[i] end
for i = 1, #other_nodes do result[#result + 1] = other_nodes[i] end
end
http_write_json(result)
end
function save_node_order()
local ids = http.formvalue("ids") or ""
local new_order = {}
for id in ids:gmatch("([^,]+)") do
new_order[#new_order + 1] = id
end
for idx, name in ipairs(new_order) do
luci.sys.call(string.format("uci -q reorder %s.%s=%d", appname, name, idx - 1))
end
api.sh_uci_commit(appname)
http_write_json({ status = "ok" })
end
function update_rules()
local update = http.formvalue("update")
luci.sys.call("lua /usr/share/passwall/rule_update.lua log '" .. update .. "' > /dev/null 2>&1 &")

View File

@@ -210,19 +210,28 @@ table td, .table .td {
document.getElementById("set_node_name").innerHTML = "";
}
function _cbi_row_top(id) {
//此函数已经损坏,等待修复或其他解决方案。
var dom = document.getElementById("cbi-passwall-" + id);
if (dom) {
var trs = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-section-table-row");
if (trs && trs.length > 0) {
for (var i = 0; i < trs.length; i++) {
var up = dom.getElementsByClassName("cbi-button-up");
if (up) {
cbi_row_swap(up[0], true, 'cbi.sts.passwall.nodes');
}
}
function row_swap(btn, up) {
const row = btn.closest("tr");
if (!row) return;
const parent = row.parentNode;
if (up) {
const prev = row.previousElementSibling;
if (prev && !prev.classList.contains("cbi-section-table-titles")) {
parent.insertBefore(row, prev);
}
} else {
const next = row.nextElementSibling;
if (next) parent.insertBefore(next, row);
}
}
function row_top(btn) {
const row = btn.closest("tr");
if (!row) return;
const parent = row.parentNode;
let firstDataRow = parent.querySelector("tr:not(.cbi-section-table-titles)");
if (firstDataRow && firstDataRow !== row) {
parent.insertBefore(row, firstDataRow);
}
}
@@ -305,6 +314,39 @@ table td, .table .td {
return { address: address, port: port };
}
function save_current_page_order(group) {
var table = document.getElementById("cbi-passwall-nodes-" + group + "-table");
if (!table) {
alert("<%:No table!%>");
return;
}
var rows = table.querySelectorAll("tr.cbi-section-table-row");
if (!rows || rows.length === 0) {
alert("<%:No nodes!%>");
return;
}
var btn = document.getElementById("save_order_btn_" + group);
if (btn) btn.disabled = true;
var ids = [];
rows.forEach(function(row) {
var id = row.id.replace("cbi-passwall-", "");
ids.push(id);
});
XHR.get('<%=api.url("save_node_order")%>', {
group: group,
ids: ids.join(",")
},
function(x, result) {
if (btn) btn.disabled = false;
if (x && x.status === 200) {
alert("<%:Saved current page order successfully.%>");
} else {
alert("<%:Save failed!%>");
}
}
);
}
//获取当前使用的节点
function get_now_use_node() {
XHR.get('<%=api.url("get_now_use_node")%>', null,
@@ -522,6 +564,7 @@ table td, .table .td {
</table>
<div class="cbi-section-create cbi-tblsection-create">
<input class="cbi-button cbi-button-add" type="button" value="<%:Add%>" onclick="to_add_node()">
<input class="cbi-button cbi-button-apply" type="button" id="save_order_btn_{{group}}" value="<%:Save Order%>" onclick="save_current_page_order('{{group}}')">
</div>
</fieldset>
</script>
@@ -537,11 +580,12 @@ table td, .table .td {
<td class="td cbi-value-field">{{url_test}}</td>
<td class="td cbi-section-table-cell nowrap cbi-section-actions">
<div class="node-wrapper">
<!--It has been damaged and awaits repair or other solutions.-->
<!--<input class="btn cbi-button" type="button" value="<%:To Top%>" onclick="_cbi_row_top('{{id}}')"/>-->
<input class="cbi-input-checkbox nodes_select" type="checkbox" cbid="{{id}}" />
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:To Top%>" onclick="row_top(this)" title="<%:To Top%>"/>
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_{{id}}" onclick="open_set_node_div('{{id}}')"/>
<input class="btn cbi-button cbi-button-add" type="button" value="<%:Copy%>" onclick="copy_node('{{id}}')"/>
<input class="btn cbi-button cbi-button-up" type="button" value="<%:Move up%>" onclick="return row_swap(this, true)" title="<%:Move up%>">
<input class="btn cbi-button cbi-button-down" type="button" value="<%:Move down%>" onclick="return row_swap(this, false)" title="<%:Move down%>">
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=api.url("node_config")%>/{{id}}'" alt="<%:Edit%>" title="<%:Edit%>">
<input class="btn cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="del_node('{{id}}')" alt="<%:Delete%>" title="<%:Delete%>">
</div>

View File

@@ -421,6 +421,12 @@ msgstr "节点备注"
msgid "Add Mode"
msgstr "添加方式"
msgid "Save Order"
msgstr "保存当前顺序"
msgid "Saved current page order successfully."
msgstr "保存当前页面顺序成功。"
msgid "Type"
msgstr "类型"

View File

@@ -760,13 +760,16 @@ local function processData(szType, content)
-- 未指定peersni默认使用remote addr
result.tls_host = params.peer or params.sni
end
if params.allowInsecure then
params.allowinsecure = params.allowinsecure or params.insecure
if params.allowinsecure then
-- 处理 insecure 参数
if params.allowinsecure == "1" or params.allowinsecure == "0" then
result.insecure = params.allowInsecure
result.insecure = params.allowinsecure
else
result.insecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
end
else
result.insecure = "0"
end
if params.tfo then
-- 处理 fast open 参数

View File

@@ -21,13 +21,13 @@ define Download/geoip
HASH:=2445b44d9ae3ab9a867c9d1e0e244646c4c378622e14b9afaf3658ecf46a40b9
endef
GEOSITE_VER:=20251125142217
GEOSITE_VER:=20251126114359
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
define Download/geosite
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
URL_FILE:=dlc.dat
FILE:=$(GEOSITE_FILE)
HASH:=ae6033c884713da8e98f2c1d8167141fbb47aadd297b3ba81450d87582827d5c
HASH:=74559fa06bfb073ac5eaa8be34213ff66e6bcbab96512e94c6e6693ee083ac66
endef
GEOSITE_IRAN_VER:=202511240043

View File

@@ -37,7 +37,7 @@ jobs:
fetch-depth: '0'
- name: Setup .NET
uses: actions/setup-dotnet@v5.0.0
uses: actions/setup-dotnet@v5.0.1
with:
dotnet-version: '8.0.x'

View File

@@ -32,7 +32,7 @@ jobs:
fetch-depth: '0'
- name: Setup
uses: actions/setup-dotnet@v5.0.0
uses: actions/setup-dotnet@v5.0.1
with:
dotnet-version: '8.0.x'

View File

@@ -32,7 +32,7 @@ jobs:
fetch-depth: '0'
- name: Setup
uses: actions/setup-dotnet@v5.0.0
uses: actions/setup-dotnet@v5.0.1
with:
dotnet-version: '8.0.x'

View File

@@ -30,7 +30,7 @@ jobs:
uses: actions/checkout@v6.0.0
- name: Setup
uses: actions/setup-dotnet@v5.0.0
uses: actions/setup-dotnet@v5.0.1
with:
dotnet-version: '8.0.x'

View File

@@ -118,22 +118,15 @@ public class BaseFmt
}
if (item.Extra.IsNotEmpty())
{
var extra = item.Extra;
try
{
var node = JsonNode.Parse(item.Extra);
if (node != null)
var node = JsonUtils.ParseJson(item.Extra);
var extra = node != null
? JsonUtils.Serialize(node, new JsonSerializerOptions
{
extra = node.ToJsonString(new JsonSerializerOptions
{
WriteIndented = false,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
});
}
}
catch
{
}
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
})
: item.Extra;
dicQuery.Add("extra", Utils.UrlEncode(extra));
}
break;
@@ -253,7 +246,21 @@ public class BaseFmt
item.RequestHost = GetQueryDecoded(query, "host");
item.Path = GetQueryDecoded(query, "path", "/");
item.HeaderType = GetQueryDecoded(query, "mode");
item.Extra = GetQueryDecoded(query, "extra");
var extraDecoded = GetQueryDecoded(query, "extra");
if (extraDecoded.IsNotEmpty())
{
var node = JsonUtils.ParseJson(extraDecoded);
if (node != null)
{
extraDecoded = JsonUtils.Serialize(node, new JsonSerializerOptions
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
});
}
}
item.Extra = extraDecoded;
break;
case nameof(ETransport.http):

View File

@@ -77,6 +77,7 @@ public class ProfilesViewModel : MyReactiveObject
public ReactiveCommand<Unit, Unit> AddSubCmd { get; }
public ReactiveCommand<Unit, Unit> EditSubCmd { get; }
public ReactiveCommand<Unit, Unit> DeleteSubCmd { get; }
#endregion Menu
@@ -235,6 +236,10 @@ public class ProfilesViewModel : MyReactiveObject
{
await EditSubAsync(false);
});
DeleteSubCmd = ReactiveCommand.CreateFromTask(async () =>
{
await DeleteSubAsync();
});
#endregion WhenAnyValue && ReactiveCommand
@@ -884,5 +889,23 @@ public class ProfilesViewModel : MyReactiveObject
}
}
private async Task DeleteSubAsync()
{
var item = await AppManager.Instance.GetSubItem(_config.SubIndexId);
if (item is null)
{
return;
}
if (await _updateView?.Invoke(EViewAction.ShowYesNo, null) == false)
{
return;
}
await ConfigHandler.DeleteSubItem(_config, item.Id);
await RefreshSubscriptions();
await SubSelectedChangedAsync(true);
}
#endregion Subscription
}

View File

@@ -28,6 +28,14 @@
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem x:Name="menuSubEdit" Header="{x:Static resx:ResUI.menuSubEdit}" />
<MenuItem x:Name="menuSubAdd" Header="{x:Static resx:ResUI.menuSubAdd}" />
<MenuItem x:Name="menuSubDelete" Header="{x:Static resx:ResUI.menuSubDelete}" />
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
<Button

View File

@@ -49,6 +49,9 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
this.Bind(ViewModel, vm => vm.ServerFilter, v => v.txtServerFilter.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddSubCmd, v => v.btnAddSub).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.EditSubCmd, v => v.btnEditSub).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.EditSubCmd, v => v.menuSubEdit).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddSubCmd, v => v.menuSubAdd).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.DeleteSubCmd, v => v.menuSubDelete).DisposeWith(disposables);
//servers delete
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.menuEditServer).DisposeWith(disposables);

View File

@@ -43,19 +43,19 @@ jobs:
uses: actions/cache/restore@v4
with:
path: ${{ github.workspace }}/libs
key: libtun2socks-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('.git/modules/badvpn/HEAD') }}-${{ hashFiles('.git/modules/libancillary/HEAD') }}
key: libtun2socks-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('.git/modules/badvpn/HEAD') }}-${{ hashFiles('.git/modules/libancillary/HEAD') }}-${{ hashFiles('compile-tun2socks.sh') }}--${{ hashFiles('compile-hevtun.sh') }}
- name: Build libtun2socks
if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true'
run: |
bash compile-tun2socks.sh
bash compile-tun2socks.sh && bash compile-hevtun.sh
- name: Save libtun2socks
if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ${{ github.workspace }}/libs
key: libtun2socks-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('.git/modules/badvpn/HEAD') }}-${{ hashFiles('.git/modules/libancillary/HEAD') }}
key: libtun2socks-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('.git/modules/badvpn/HEAD') }}-${{ hashFiles('.git/modules/libancillary/HEAD') }}-${{ hashFiles('compile-tun2socks.sh') }}--${{ hashFiles('compile-hevtun.sh') }}
- name: Copy libtun2socks
run: |

View File

@@ -72,7 +72,8 @@ class TProxyService(
appendLine(" udp: 'udp'")
appendLine("misc:")
appendLine(" read-write-timeout: ${MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT) ?: AppConfig.HEVTUN_RW_TIMEOUT}")
appendLine(" tcp-read-write-timeout: ${MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT) ?: AppConfig.HEVTUN_RW_TIMEOUT}")
appendLine(" udp-read-write-timeout: ${MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT) ?: AppConfig.HEVTUN_RW_TIMEOUT}")
val hevTunLogLevel = MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_LOGLEVEL) ?: "none"
if (hevTunLogLevel != "none") {
appendLine(" log-level: $hevTunLogLevel")

40
v2rayng/compile-hevtun.sh Normal file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
# Set magic variables for current file & dir
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
if [[ ! -d $NDK_HOME ]]; then
echo "Android NDK: NDK_HOME not found. please set env \$NDK_HOME"
exit 1
fi
TMPDIR=$(mktemp -d)
clear_tmp () {
rm -rf $TMPDIR
}
trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; clear_tmp; exit 1' ERR INT
#build hev-socks5-tunnel
mkdir -p "$TMPDIR/jni"
pushd "$TMPDIR"
echo 'include $(call all-subdir-makefiles)' > jni/Android.mk
ln -s "$__dir/hev-socks5-tunnel" jni/hev-socks5-tunnel
"$NDK_HOME/ndk-build" \
NDK_PROJECT_PATH=. \
APP_BUILD_SCRIPT=jni/Android.mk \
"APP_ABI=armeabi-v7a arm64-v8a x86 x86_64" \
APP_PLATFORM=android-21 \
NDK_LIBS_OUT="$TMPDIR/libs" \
NDK_OUT="$TMPDIR/obj" \
"APP_CFLAGS=-O3 -DPKGNAME=com/v2ray/ang/service" \
"APP_LDFLAGS=-Wl,--build-id=none -Wl,--hash-style=gnu" \
cp -r "$TMPDIR/libs/"* "$__dir/libs/"
popd
rm -rf $TMPDIR

View File

@@ -30,29 +30,3 @@ $NDK_HOME/ndk-build \
cp -r $TMPDIR/libs $__dir/
popd
rm -rf $TMPDIR
#build hev-socks5-tunnel
HEVTUN_TMP=$(mktemp -d)
trap 'rm -rf "$HEVTUN_TMP"' EXIT
mkdir -p "$HEVTUN_TMP/jni"
pushd "$HEVTUN_TMP"
echo 'include $(call all-subdir-makefiles)' > jni/Android.mk
ln -s "$__dir/hev-socks5-tunnel" jni/hev-socks5-tunnel
"$NDK_HOME/ndk-build" \
NDK_PROJECT_PATH=. \
APP_BUILD_SCRIPT=jni/Android.mk \
"APP_ABI=armeabi-v7a arm64-v8a x86 x86_64" \
APP_PLATFORM=android-21 \
NDK_LIBS_OUT="$HEVTUN_TMP/libs" \
NDK_OUT="$HEVTUN_TMP/obj" \
"APP_CFLAGS=-O3 -DPKGNAME=com/v2ray/ang/service" \
"APP_LDFLAGS=-WI,--build-id=none -WI,--hash-style=gnu" \
cp -r "$HEVTUN_TMP/libs/"* "$__dir/libs/"
popd
rm -rf "$HEVTUN_TMP"

View File

@@ -2404,60 +2404,52 @@ class YoutubeDL(object):
return res
def _format_note(self, fdict):
res = ''
if fdict.get('ext') in ['f4f', 'f4m']:
res += '(unsupported) '
if fdict.get('language'):
if res:
res += ' '
res += '[%s] ' % fdict['language']
if fdict.get('format_note') is not None:
res += fdict['format_note'] + ' '
if fdict.get('tbr') is not None:
res += '%4dk ' % fdict['tbr']
def simplified_codec(f, field):
assert field in ('acodec', 'vcodec')
codec = f.get(field)
return (
'unknown' if not codec
else '.'.join(codec.split('.')[:4]) if codec != 'none'
else 'images' if field == 'vcodec' and f.get('acodec') == 'none'
else None if field == 'acodec' and f.get('vcodec') == 'none'
else 'audio only' if field == 'vcodec'
else 'video only')
res = join_nonempty(
fdict.get('ext') in ('f4f', 'f4m') and '(unsupported)',
fdict.get('language') and ('[%s]' % (fdict['language'],)),
fdict.get('format_note') is not None and fdict['format_note'],
fdict.get('tbr') is not None and ('%4dk' % fdict['tbr']),
delim=' ')
res = [res] if res else []
if fdict.get('container') is not None:
if res:
res += ', '
res += '%s container' % fdict['container']
if (fdict.get('vcodec') is not None
and fdict.get('vcodec') != 'none'):
if res:
res += ', '
res += fdict['vcodec']
if fdict.get('vbr') is not None:
res += '@'
res.append('%s container' % (fdict['container'],))
if fdict.get('vcodec') not in (None, 'none'):
codec = simplified_codec(fdict, 'vcodec')
if codec and fdict.get('vbr') is not None:
codec += '@'
elif fdict.get('vbr') is not None and fdict.get('abr') is not None:
res += 'video@'
if fdict.get('vbr') is not None:
res += '%4dk' % fdict['vbr']
codec = 'video@'
else:
codec = None
codec = join_nonempty(codec, fdict.get('vbr') is not None and ('%4dk' % fdict['vbr']))
if codec:
res.append(codec)
if fdict.get('fps') is not None:
if res:
res += ', '
res += '%sfps' % fdict['fps']
if fdict.get('acodec') is not None:
if res:
res += ', '
if fdict['acodec'] == 'none':
res += 'video only'
else:
res += '%-5s' % fdict['acodec']
elif fdict.get('abr') is not None:
if res:
res += ', '
res += 'audio'
if fdict.get('abr') is not None:
res += '@%3dk' % fdict['abr']
if fdict.get('asr') is not None:
res += ' (%5dHz)' % fdict['asr']
res.append('%sfps' % (fdict['fps'],))
codec = (
simplified_codec(fdict, 'acodec') if fdict.get('acodec') is not None
else 'audio' if fdict.get('abr') is not None else None)
if codec:
res.append(join_nonempty(
'%-4s' % (codec + (('@%3dk' % fdict['abr']) if fdict.get('abr') else ''),),
fdict.get('asr') and '(%5dHz)' % fdict['asr'], delim=' '))
if fdict.get('filesize') is not None:
if res:
res += ', '
res += format_bytes(fdict['filesize'])
res.append(format_bytes(fdict['filesize']))
elif fdict.get('filesize_approx') is not None:
if res:
res += ', '
res += '~' + format_bytes(fdict['filesize_approx'])
return res
res.append('~' + format_bytes(fdict['filesize_approx']))
return ', '.join(res)
def list_formats(self, info_dict):
formats = info_dict.get('formats', [info_dict])

View File

@@ -1669,10 +1669,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
'_rtmp': {'protocol': 'rtmp'},
# av01 video only formats sometimes served with "unknown" codecs
'394': {'acodec': 'none', 'vcodec': 'av01.0.05M.08'},
'395': {'acodec': 'none', 'vcodec': 'av01.0.05M.08'},
'396': {'acodec': 'none', 'vcodec': 'av01.0.05M.08'},
'397': {'acodec': 'none', 'vcodec': 'av01.0.05M.08'},
'394': {'acodec': 'none', 'vcodec': 'av01.0.00M.08'},
'395': {'acodec': 'none', 'vcodec': 'av01.0.00M.08'},
'396': {'acodec': 'none', 'vcodec': 'av01.0.01M.08'},
'397': {'acodec': 'none', 'vcodec': 'av01.0.04M.08'},
'398': {'acodec': 'none', 'vcodec': 'av01.0.05M.08'},
'399': {'acodec': 'none', 'vcodec': 'av01.0.08M.08'},
}
_PLAYER_JS_VARIANT_MAP = (
@@ -3811,7 +3813,7 @@ class YoutubeTabIE(YoutubeBaseInfoExtractor):
continuation = None
for is_renderer in traverse_obj(slr_renderer, (
'contents', Ellipsis, 'itemSectionRenderer', T(dict))):
for isr_content in traverse_obj(slr_renderer, (
for isr_content in traverse_obj(is_renderer, (
'contents', Ellipsis, T(dict))):
renderer = isr_content.get('playlistVideoListRenderer')
if renderer: