💋 Sync 2026-10-04 04:16:09
No files matched your search
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# Vantage - a LuCI theme for OpenWrt
|
||||
# Copyright (C) 2026 anothaDev
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License,
|
||||
# version 3 or (at your option) any later version.
|
||||
# Original work; see NOTICE.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-theme-vantage
|
||||
PKG_VERSION:=1.0.1
|
||||
PKG_RELEASE:=1
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
|
||||
LUCI_TITLE:=Vantage theme
|
||||
LUCI_DESCRIPTION:=A console-style LuCI theme: icon rail with flyouts, \
|
||||
breadcrumb, page tabs, Ctrl+K command palette, light and dark modes.
|
||||
LUCI_DEPENDS:=+luci-base
|
||||
LUCI_MAINTAINER:=anothaDev <10740588+anothaDev@users.noreply.github.com>
|
||||
LUCI_URL:=https://github.com/anothaDev/luci-theme-vantage
|
||||
|
||||
# The stylesheet uses modern CSS (custom properties, :is(), :has(),
|
||||
# :where(), color-mix(), inset) that csstidy mangles, so it ships as
|
||||
# written. JavaScript still goes through LuCI's jsmin when CONFIG_LUCI_JSMIN
|
||||
# is set (checked: the minified theme scripts parse and keep every regex).
|
||||
LUCI_MINIFY_CSS:=0
|
||||
|
||||
# Language packages (po/<lang>/vantage-theme.po): luci.mk would name them
|
||||
# after "vantage", like the app's; this keeps them apart
|
||||
# (luci-i18n-vantage-theme-<lang>, i18n/vantage-theme.<lang>.lmo) and gives
|
||||
# them the package version instead of one derived from git history.
|
||||
LUCI_BASENAME:=vantage-theme
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)-r$(PKG_RELEASE)
|
||||
|
||||
define Package/luci-theme-vantage/postrm
|
||||
#!/bin/sh
|
||||
[ -n "$${IPKG_INSTROOT}" ] || {
|
||||
# never leave LuCI pointing at a theme that is gone: fall back to
|
||||
# Bootstrap when it is registered, else to any other registered theme
|
||||
# (LuCI itself also falls back to the first theme that renders)
|
||||
if [ "$$(uci -q get luci.main.mediaurlbase)" = "/luci-static/vantage" ]; then
|
||||
alt="$$(uci -q get luci.themes.Bootstrap)"
|
||||
[ -n "$$alt" ] || alt="$$(uci -q show luci.themes | sed -n "s|^luci\.themes\.[A-Za-z0-9_]*='\(/luci-static/[A-Za-z0-9_.-]*\)'$$|\1|p" | grep -v '^/luci-static/vantage$$' | head -n 1)"
|
||||
[ -z "$$alt" ] || uci -q set luci.main.mediaurlbase="$$alt"
|
||||
fi
|
||||
uci -q delete luci.themes.Vantage
|
||||
uci -q commit luci
|
||||
}
|
||||
exit 0
|
||||
endef
|
||||
|
||||
# In the LuCI tree (themes/luci-theme-vantage) use ../../luci.mk; built from
|
||||
# an external feed, use the luci feed installed in the build tree.
|
||||
include $(TOPDIR)/feeds/luci/luci.mk)
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -0,0 +1,32 @@
|
||||
Vantage - a LuCI theme for OpenWrt
|
||||
Copyright (C) 2026 anothaDev
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Origin
|
||||
------
|
||||
This theme is original work. Its stylesheet, templates, scripts, logo and
|
||||
icons were written for Vantage; no code, markup, styles or artwork were
|
||||
copied from other LuCI themes (Bootstrap, Material, Argon, OpenWrt 2020,
|
||||
UniWRT or others). The status icons are drawn by dev/icons/build.js in the
|
||||
Vantage source tree.
|
||||
|
||||
The theme targets LuCI, the OpenWrt web interface (https://github.com/openwrt/luci),
|
||||
which is licensed under the Apache License 2.0 (compatible with GPL-3.0). It uses LuCI's public
|
||||
interfaces only - the template scope, luci.js (L, E, ui.menu, rpc), the
|
||||
luci.themes/luci.main.mediaurlbase configuration and the CSS classes that
|
||||
LuCI's views emit - and ships no LuCI source. The package is built with
|
||||
LuCI's luci.mk.
|
||||
@@ -0,0 +1,67 @@
|
||||
'use strict';
|
||||
'require baseclass';
|
||||
|
||||
/*
|
||||
* Vantage theme - device naming for the host chip and title.
|
||||
*
|
||||
* `system board` model strings are often the SoC vendor's reference-design
|
||||
* name ("Qualcomm Technologies, Inc. IPQ5332/RDP442/AP-MI01.3") rather than
|
||||
* the product. In that case (or when the model is missing) the product name
|
||||
* is derived from board_name ("zyxel,nwa50be" -> "Zyxel NWA50BE"): vendor
|
||||
* capitalised (or its usual spelling), model upper-cased. Pure functions,
|
||||
* no DOM, unit tested in tests/host.test.js.
|
||||
*/
|
||||
|
||||
/* SoC vendors, reference boards and placeholders: not a product name.
|
||||
A bare chip id only counts at the start ("IPQ8074/AP-HK01"); inside a
|
||||
product name it is part of the model ("GL.iNet GL-MT3000"). */
|
||||
const REFERENCE = /\b(qualcomm|qca|mediatek|broadcom|realtek|marvell|airoha|econet|ralink|allwinner|rockchip|amlogic|rdp\d*|rfb|reference|ref[\s_-]?board|evb|eval(?:uation)?\s*board|dev(?:elopment)?\s*board|generic|default\s*string|to be filled|unknown)\b|^(ipq|qca|mt|bcm|rtl|en)\d{3,}/i;
|
||||
|
||||
/* board_name vendor prefixes whose usual spelling is not simply Capitalised */
|
||||
const VENDORS = {
|
||||
'tplink': 'TP-Link', 'tp-link': 'TP-Link', 'dlink': 'D-Link', 'd-link': 'D-Link', 'asus': 'ASUS',
|
||||
'netgear': 'NETGEAR', 'glinet': 'GL.iNet', 'gl-inet': 'GL.iNet', 'ubnt': 'Ubiquiti', 'ubiquiti': 'Ubiquiti',
|
||||
'mikrotik': 'MikroTik', 'avm': 'AVM', 'zte': 'ZTE', 'tenda': 'Tenda', 'openwrt': 'OpenWrt', 'bananapi': 'Banana Pi',
|
||||
'sinovoip': 'Banana Pi', 'raspberrypi': 'Raspberry Pi', 'friendlyarm': 'FriendlyElec', 'friendlyelec': 'FriendlyElec',
|
||||
'iodata': 'I-O DATA', 'nec': 'NEC', 'wavlink': 'Wavlink', 'cudy': 'Cudy', 'xiaomi': 'Xiaomi', 'linksys': 'Linksys',
|
||||
'zyxel': 'Zyxel', 'edgecore': 'Edgecore', 'engenius': 'EnGenius', 'aruba': 'Aruba', 'meraki': 'Meraki', 'buffalo': 'Buffalo'
|
||||
};
|
||||
|
||||
function clean(s) {
|
||||
return (typeof s === 'string') ? s.replace(/[\u0000-\u001f\u007f]+/g, ' ').replace(/\s+/g, ' ').trim() : '';
|
||||
}
|
||||
|
||||
function looksLikeReference(model) {
|
||||
const m = clean(model);
|
||||
return !m || REFERENCE.test(m);
|
||||
}
|
||||
|
||||
function vendorName(v) {
|
||||
const key = v.toLowerCase();
|
||||
if (Object.prototype.hasOwnProperty.call(VENDORS, key)) return VENDORS[key];
|
||||
return key.split(/[-_]+/).filter(Boolean).map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
||||
}
|
||||
|
||||
/* "zyxel,nwa50be" -> "Zyxel NWA50BE"; null when there is no vendor,model pair */
|
||||
function fromBoardName(boardName) {
|
||||
const b = clean(boardName);
|
||||
const i = b.indexOf(',');
|
||||
if (i <= 0 || i === b.length - 1) return null;
|
||||
const vendor = b.slice(0, i).trim(), model = b.slice(i + 1).trim();
|
||||
if (!/^[A-Za-z0-9._-]+$/.test(vendor) || !/^[A-Za-z0-9._+,-]+$/.test(model)) return null;
|
||||
return vendorName(vendor) + ' ' + model.replace(/,/g, ' ').toUpperCase();
|
||||
}
|
||||
|
||||
/* product name for a `system board` reply, '' when nothing usable */
|
||||
function productName(board) {
|
||||
if (!board || typeof board !== 'object') return '';
|
||||
const model = clean(board.model);
|
||||
if (model && !looksLikeReference(model)) return model;
|
||||
return fromBoardName(board.board_name) || clean(board.board_name);
|
||||
}
|
||||
|
||||
return baseclass.extend({
|
||||
productName,
|
||||
fromBoardName,
|
||||
looksLikeReference
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Vantage status icons - GENERATED by dev/icons/build.js, do not edit.
|
||||
* Replaces luci-base's /luci-static/resources/icons/*.svg in place: LuCI keeps
|
||||
* its <img> (size, title, alt); the image content comes from this theme.
|
||||
* ?h= is a content hash so a changed icon is never served from cache.
|
||||
*/
|
||||
|
||||
/* light (default) */
|
||||
img[src*="/resources/icons/wifi.svg"] { content: url("icons/light/wifi.svg?h=2f84b7d6"); }
|
||||
img[src*="/resources/icons/wifi_disabled.svg"] { content: url("icons/light/wifi_disabled.svg?h=e62a2fea"); }
|
||||
img[src*="/resources/icons/ethernet.svg"] { content: url("icons/light/ethernet.svg?h=1694dc92"); }
|
||||
img[src*="/resources/icons/ethernet_disabled.svg"] { content: url("icons/light/ethernet_disabled.svg?h=56e10306"); }
|
||||
img[src*="/resources/icons/bridge.svg"] { content: url("icons/light/bridge.svg?h=f75682a4"); }
|
||||
img[src*="/resources/icons/bridge_disabled.svg"] { content: url("icons/light/bridge_disabled.svg?h=a02590f3"); }
|
||||
img[src*="/resources/icons/switch.svg"] { content: url("icons/light/switch.svg?h=501f6012"); }
|
||||
img[src*="/resources/icons/switch_disabled.svg"] { content: url("icons/light/switch_disabled.svg?h=5b30a77e"); }
|
||||
img[src*="/resources/icons/vlan.svg"] { content: url("icons/light/vlan.svg?h=0f80d5ad"); }
|
||||
img[src*="/resources/icons/vlan_disabled.svg"] { content: url("icons/light/vlan_disabled.svg?h=c2e85689"); }
|
||||
img[src*="/resources/icons/vrf.svg"] { content: url("icons/light/vrf.svg?h=cca1a791"); }
|
||||
img[src*="/resources/icons/vrf_disabled.svg"] { content: url("icons/light/vrf_disabled.svg?h=8be0a928"); }
|
||||
img[src*="/resources/icons/tunnel.svg"] { content: url("icons/light/tunnel.svg?h=0b457444"); }
|
||||
img[src*="/resources/icons/tunnel_disabled.svg"] { content: url("icons/light/tunnel_disabled.svg?h=3aad88c8"); }
|
||||
img[src*="/resources/icons/wireguard.svg"] { content: url("icons/light/wireguard.svg?h=6aea13cf"); }
|
||||
img[src*="/resources/icons/wireguard_disabled.svg"] { content: url("icons/light/wireguard_disabled.svg?h=073850b0"); }
|
||||
img[src*="/resources/icons/alias.svg"] { content: url("icons/light/alias.svg?h=388af309"); }
|
||||
img[src*="/resources/icons/alias_disabled.svg"] { content: url("icons/light/alias_disabled.svg?h=c3b30647"); }
|
||||
img[src*="/resources/icons/signal-075-100.svg"] { content: url("icons/light/signal-075-100.svg?h=9a9f0e12"); }
|
||||
img[src*="/resources/icons/signal-050-075.svg"] { content: url("icons/light/signal-050-075.svg?h=9f8ba4f1"); }
|
||||
img[src*="/resources/icons/signal-025-050.svg"] { content: url("icons/light/signal-025-050.svg?h=24bf1a04"); }
|
||||
img[src*="/resources/icons/signal-000-025.svg"] { content: url("icons/light/signal-000-025.svg?h=b49c7e88"); }
|
||||
img[src*="/resources/icons/signal-000-000.svg"] { content: url("icons/light/signal-000-000.svg?h=2aace352"); }
|
||||
img[src*="/resources/icons/signal-none.svg"] { content: url("icons/light/signal-none.svg?h=afc17393"); }
|
||||
img[src*="/resources/icons/port_up.svg"] { content: url("icons/light/port_up.svg?h=4eeb8507"); }
|
||||
img[src*="/resources/icons/port_down.svg"] { content: url("icons/light/port_down.svg?h=7c1dcc4d"); }
|
||||
img[src*="/resources/icons/port_pse_up.svg"] { content: url("icons/light/port_pse_up.svg?h=c9ef298d"); }
|
||||
img[src*="/resources/icons/port_pse_down.svg"] { content: url("icons/light/port_pse_down.svg?h=680fe699"); }
|
||||
img[src*="/resources/icons/loading.svg"] { content: url("icons/light/loading.svg?h=6a5fac64"); }
|
||||
|
||||
/* dark */
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/wifi.svg"] { content: url("icons/dark/wifi.svg?h=32f37eb8"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/wifi_disabled.svg"] { content: url("icons/dark/wifi_disabled.svg?h=036c48a6"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/ethernet.svg"] { content: url("icons/dark/ethernet.svg?h=6de09bc1"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/ethernet_disabled.svg"] { content: url("icons/dark/ethernet_disabled.svg?h=d7ba9f4a"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/bridge.svg"] { content: url("icons/dark/bridge.svg?h=26c06162"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/bridge_disabled.svg"] { content: url("icons/dark/bridge_disabled.svg?h=c2e75ebc"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/switch.svg"] { content: url("icons/dark/switch.svg?h=842b842a"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/switch_disabled.svg"] { content: url("icons/dark/switch_disabled.svg?h=c944f98d"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/vlan.svg"] { content: url("icons/dark/vlan.svg?h=760897df"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/vlan_disabled.svg"] { content: url("icons/dark/vlan_disabled.svg?h=3659cd38"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/vrf.svg"] { content: url("icons/dark/vrf.svg?h=d6b4fc63"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/vrf_disabled.svg"] { content: url("icons/dark/vrf_disabled.svg?h=eaca5a7e"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/tunnel.svg"] { content: url("icons/dark/tunnel.svg?h=f6b093c6"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/tunnel_disabled.svg"] { content: url("icons/dark/tunnel_disabled.svg?h=af44617f"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/wireguard.svg"] { content: url("icons/dark/wireguard.svg?h=0d8b6e28"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/wireguard_disabled.svg"] { content: url("icons/dark/wireguard_disabled.svg?h=3dcfe102"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/alias.svg"] { content: url("icons/dark/alias.svg?h=efa08bd5"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/alias_disabled.svg"] { content: url("icons/dark/alias_disabled.svg?h=a7cd9175"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/signal-075-100.svg"] { content: url("icons/dark/signal-075-100.svg?h=8a92ab56"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/signal-050-075.svg"] { content: url("icons/dark/signal-050-075.svg?h=6959aac7"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/signal-025-050.svg"] { content: url("icons/dark/signal-025-050.svg?h=f6c8bda3"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/signal-000-025.svg"] { content: url("icons/dark/signal-000-025.svg?h=1a4d332a"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/signal-000-000.svg"] { content: url("icons/dark/signal-000-000.svg?h=c614ea16"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/signal-none.svg"] { content: url("icons/dark/signal-none.svg?h=6eb009ad"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/port_up.svg"] { content: url("icons/dark/port_up.svg?h=f4492ac4"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/port_down.svg"] { content: url("icons/dark/port_down.svg?h=86d6f109"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/port_pse_up.svg"] { content: url("icons/dark/port_pse_up.svg?h=30276fcf"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/port_pse_down.svg"] { content: url("icons/dark/port_pse_down.svg?h=90d4fded"); }
|
||||
html[data-darkmode="true"] img[src*="/resources/icons/loading.svg"] { content: url("icons/dark/loading.svg?h=7b69fe88"); }
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#a9afb7" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="12" width="12" height="6" rx="3" transform="rotate(-45 9 15)"/><rect x="9" y="6" width="12" height="6" rx="3" transform="rotate(-45 15 9)"/></svg>
|
||||
|
After Width: | Height: | Size: 361 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><rect x="3" y="12" width="12" height="6" rx="3" transform="rotate(-45 9 15)"/><rect x="9" y="6" width="12" height="6" rx="3" transform="rotate(-45 15 9)"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 598 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#a9afb7" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 8h19M6 8v12M18 8v12M6 16.5a6 6 0 0 1 12 0M2.5 20h3.5M18 20h3.5"/></svg>
|
||||
|
After Width: | Height: | Size: 285 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M2.5 8h19M6 8v12M18 8v12M6 16.5a6 6 0 0 1 12 0M2.5 20h3.5M18 20h3.5"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 522 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#a9afb7" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M8.5 8v2.5M10.83 8v2.5M13.17 8v2.5M15.5 8v2.5" stroke-width="1.5"/></svg>
|
||||
|
After Width: | Height: | Size: 438 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M8.5 8v2.5M10.83 8v2.5M13.17 8v2.5M15.5 8v2.5" stroke-width="1.5"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 675 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><style>.a{transform-box:view-box;transform-origin:50% 50%;animation:r 1.1s linear infinite}@keyframes r{to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){.a{animation-duration:3.5s}}</style><circle cx="12" cy="12" r="8" stroke="#383b40"/><path class="a" d="M12 4a8 8 0 0 1 8 8" stroke="#a9afb7"/></svg>
|
||||
|
After Width: | Height: | Size: 504 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M8.5 8v2.5M10.83 8v2.5M13.17 8v2.5M15.5 8v2.5" stroke-width="1.5"/></svg>
|
||||
|
After Width: | Height: | Size: 438 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M13.3 6.6 9.6 11.7h2.9l-1.2 4.2 3.8-5.2h-2.9z" fill="currentColor" stroke-width="1.1"/></svg>
|
||||
|
After Width: | Height: | Size: 458 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#2dd4bf" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z" fill="currentColor" fill-opacity=".16" stroke="none"/><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M13.3 6.6 9.6 11.7h2.9l-1.2 4.2 3.8-5.2h-2.9z" fill="currentColor" stroke-width="1.1"/></svg>
|
||||
|
After Width: | Height: | Size: 667 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#2dd4bf" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z" fill="currentColor" fill-opacity=".16" stroke="none"/><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M8.5 8v2.5M10.83 8v2.5M13.17 8v2.5M15.5 8v2.5" stroke-width="1.5"/></svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#383b40" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#383b40" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#383b40" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#383b40" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#ff6b6b" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#383b40" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#383b40" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#383b40" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#f5b84a" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#f5b84a" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#383b40" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#383b40" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#29af9f" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#29af9f" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#29af9f" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#383b40" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#2dd4bf" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#2dd4bf" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#2dd4bf" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#2dd4bf" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#383b40" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#383b40" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#383b40" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#383b40" stroke="none"/><path d="M3.5 4.5l4.5 4.5M8 4.5 3.5 9" stroke="#60646b" stroke-width="1.9"/></svg>
|
||||
|
After Width: | Height: | Size: 601 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#a9afb7" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 8h15.5M16 4.5 19.5 8 16 11.5M20 16H4.5M8 12.5 4.5 16 8 19.5"/></svg>
|
||||
|
After Width: | Height: | Size: 280 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M4 8h15.5M16 4.5 19.5 8 16 11.5M20 16H4.5M8 12.5 4.5 16 8 19.5"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 517 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#a9afb7" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 20v-8a8.5 8.5 0 0 1 17 0v8M8.5 20v-7a3.5 3.5 0 0 1 7 0v7M2 20h20"/></svg>
|
||||
|
After Width: | Height: | Size: 287 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M3.5 20v-8a8.5 8.5 0 0 1 17 0v8M8.5 20v-7a3.5 3.5 0 0 1 7 0v7M2 20h20"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 524 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#a9afb7" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 5v6.38a1.5 1.5 0 0 0 .44 1.06l7.62 7.62a1.5 1.5 0 0 0 2.12 0l6.38-6.38a1.5 1.5 0 0 0 0-2.12L12.44 3.94A1.5 1.5 0 0 0 11.38 3.5H5A1.5 1.5 0 0 0 3.5 5z"/><circle cx="8" cy="8" r="1.4" fill="currentColor" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 437 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M3.5 5v6.38a1.5 1.5 0 0 0 .44 1.06l7.62 7.62a1.5 1.5 0 0 0 2.12 0l6.38-6.38a1.5 1.5 0 0 0 0-2.12L12.44 3.94A1.5 1.5 0 0 0 11.38 3.5H5A1.5 1.5 0 0 0 3.5 5z"/><circle cx="8" cy="8" r="1.4" fill="currentColor" stroke="none"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 674 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#a9afb7" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.5 20.5 8 12 12.5 3.5 8z"/><path d="m3.5 12 8.5 4.5 8.5-4.5M3.5 16l8.5 4.5 8.5-4.5"/></svg>
|
||||
|
After Width: | Height: | Size: 305 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M12 3.5 20.5 8 12 12.5 3.5 8z"/><path d="m3.5 12 8.5 4.5 8.5-4.5M3.5 16l8.5 4.5 8.5-4.5"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 542 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#a9afb7" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="18.6" r="1.35" fill="currentColor" stroke="none"/><path d="M8.46 15.06a5 5 0 0 1 7.08 0M5.28 11.88a9.5 9.5 0 0 1 13.44 0M2.1 8.7a14 14 0 0 1 19.8 0"/></svg>
|
||||
|
After Width: | Height: | Size: 376 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><circle cx="12" cy="18.6" r="1.35" fill="currentColor" stroke="none"/><path d="M8.46 15.06a5 5 0 0 1 7.08 0M5.28 11.88a9.5 9.5 0 0 1 13.44 0M2.1 8.7a14 14 0 0 1 19.8 0"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 613 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#a9afb7" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3 19.5 6v5.5c0 4.6-3.1 8-7.5 9.5-4.4-1.5-7.5-4.9-7.5-9.5V6z"/><path d="M9 16v-3a3 3 0 0 1 6 0v3"/></svg>
|
||||
|
After Width: | Height: | Size: 317 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#60646b" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M12 3 19.5 6v5.5c0 4.6-3.1 8-7.5 9.5-4.4-1.5-7.5-4.9-7.5-9.5V6z"/><path d="M9 16v-3a3 3 0 0 1 6 0v3"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 554 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#4a515a" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="12" width="12" height="6" rx="3" transform="rotate(-45 9 15)"/><rect x="9" y="6" width="12" height="6" rx="3" transform="rotate(-45 15 9)"/></svg>
|
||||
|
After Width: | Height: | Size: 361 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><rect x="3" y="12" width="12" height="6" rx="3" transform="rotate(-45 9 15)"/><rect x="9" y="6" width="12" height="6" rx="3" transform="rotate(-45 15 9)"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 598 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#4a515a" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 8h19M6 8v12M18 8v12M6 16.5a6 6 0 0 1 12 0M2.5 20h3.5M18 20h3.5"/></svg>
|
||||
|
After Width: | Height: | Size: 285 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M2.5 8h19M6 8v12M18 8v12M6 16.5a6 6 0 0 1 12 0M2.5 20h3.5M18 20h3.5"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 522 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#4a515a" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M8.5 8v2.5M10.83 8v2.5M13.17 8v2.5M15.5 8v2.5" stroke-width="1.5"/></svg>
|
||||
|
After Width: | Height: | Size: 438 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M8.5 8v2.5M10.83 8v2.5M13.17 8v2.5M15.5 8v2.5" stroke-width="1.5"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 675 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><style>.a{transform-box:view-box;transform-origin:50% 50%;animation:r 1.1s linear infinite}@keyframes r{to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){.a{animation-duration:3.5s}}</style><circle cx="12" cy="12" r="8" stroke="#d5d7da"/><path class="a" d="M12 4a8 8 0 0 1 8 8" stroke="#4a515a"/></svg>
|
||||
|
After Width: | Height: | Size: 504 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M8.5 8v2.5M10.83 8v2.5M13.17 8v2.5M15.5 8v2.5" stroke-width="1.5"/></svg>
|
||||
|
After Width: | Height: | Size: 438 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M13.3 6.6 9.6 11.7h2.9l-1.2 4.2 3.8-5.2h-2.9z" fill="currentColor" stroke-width="1.1"/></svg>
|
||||
|
After Width: | Height: | Size: 458 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#0b7f6c" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z" fill="currentColor" fill-opacity=".16" stroke="none"/><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M13.3 6.6 9.6 11.7h2.9l-1.2 4.2 3.8-5.2h-2.9z" fill="currentColor" stroke-width="1.1"/></svg>
|
||||
|
After Width: | Height: | Size: 667 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#0b7f6c" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z" fill="currentColor" fill-opacity=".16" stroke="none"/><path d="M5 4.5h14A1.5 1.5 0 0 1 20.5 6v9.5A1.5 1.5 0 0 1 19 17h-2.5v2.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V17H5a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 5 4.5z"/><path d="M8.5 8v2.5M10.83 8v2.5M13.17 8v2.5M15.5 8v2.5" stroke-width="1.5"/></svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#d5d7da" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#d5d7da" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#d5d7da" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#d5d7da" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#c42b2b" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#d5d7da" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#d5d7da" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#d5d7da" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#9a5b00" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#9a5b00" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#d5d7da" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#d5d7da" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#3c9989" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#3c9989" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#3c9989" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#d5d7da" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#0b7f6c" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#0b7f6c" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#0b7f6c" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#0b7f6c" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="15" width="3.5" height="6" rx="1.25" fill="#d5d7da" stroke="none"/><rect x="7.5" y="11" width="3.5" height="10" rx="1.25" fill="#d5d7da" stroke="none"/><rect x="13" y="7" width="3.5" height="14" rx="1.25" fill="#d5d7da" stroke="none"/><rect x="18.5" y="3" width="3.5" height="18" rx="1.25" fill="#d5d7da" stroke="none"/><path d="M3.5 4.5l4.5 4.5M8 4.5 3.5 9" stroke="#9ca0a6" stroke-width="1.9"/></svg>
|
||||
|
After Width: | Height: | Size: 601 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#4a515a" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 8h15.5M16 4.5 19.5 8 16 11.5M20 16H4.5M8 12.5 4.5 16 8 19.5"/></svg>
|
||||
|
After Width: | Height: | Size: 280 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M4 8h15.5M16 4.5 19.5 8 16 11.5M20 16H4.5M8 12.5 4.5 16 8 19.5"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 517 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#4a515a" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 20v-8a8.5 8.5 0 0 1 17 0v8M8.5 20v-7a3.5 3.5 0 0 1 7 0v7M2 20h20"/></svg>
|
||||
|
After Width: | Height: | Size: 287 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M3.5 20v-8a8.5 8.5 0 0 1 17 0v8M8.5 20v-7a3.5 3.5 0 0 1 7 0v7M2 20h20"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 524 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#4a515a" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 5v6.38a1.5 1.5 0 0 0 .44 1.06l7.62 7.62a1.5 1.5 0 0 0 2.12 0l6.38-6.38a1.5 1.5 0 0 0 0-2.12L12.44 3.94A1.5 1.5 0 0 0 11.38 3.5H5A1.5 1.5 0 0 0 3.5 5z"/><circle cx="8" cy="8" r="1.4" fill="currentColor" stroke="none"/></svg>
|
||||
|
After Width: | Height: | Size: 437 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M3.5 5v6.38a1.5 1.5 0 0 0 .44 1.06l7.62 7.62a1.5 1.5 0 0 0 2.12 0l6.38-6.38a1.5 1.5 0 0 0 0-2.12L12.44 3.94A1.5 1.5 0 0 0 11.38 3.5H5A1.5 1.5 0 0 0 3.5 5z"/><circle cx="8" cy="8" r="1.4" fill="currentColor" stroke="none"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 674 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#4a515a" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.5 20.5 8 12 12.5 3.5 8z"/><path d="m3.5 12 8.5 4.5 8.5-4.5M3.5 16l8.5 4.5 8.5-4.5"/></svg>
|
||||
|
After Width: | Height: | Size: 305 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M12 3.5 20.5 8 12 12.5 3.5 8z"/><path d="m3.5 12 8.5 4.5 8.5-4.5M3.5 16l8.5 4.5 8.5-4.5"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 542 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#4a515a" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="18.6" r="1.35" fill="currentColor" stroke="none"/><path d="M8.46 15.06a5 5 0 0 1 7.08 0M5.28 11.88a9.5 9.5 0 0 1 13.44 0M2.1 8.7a14 14 0 0 1 19.8 0"/></svg>
|
||||
|
After Width: | Height: | Size: 376 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><circle cx="12" cy="18.6" r="1.35" fill="currentColor" stroke="none"/><path d="M8.46 15.06a5 5 0 0 1 7.08 0M5.28 11.88a9.5 9.5 0 0 1 13.44 0M2.1 8.7a14 14 0 0 1 19.8 0"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 613 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#4a515a" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3 19.5 6v5.5c0 4.6-3.1 8-7.5 9.5-4.4-1.5-7.5-4.9-7.5-9.5V6z"/><path d="M9 16v-3a3 3 0 0 1 6 0v3"/></svg>
|
||||
|
After Width: | Height: | Size: 317 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" color="#9ca0a6" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><mask id="m" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff" stroke="none"/><path d="M4 4 20 20" stroke="#000" stroke-width="5.1"/></mask><g mask="url(#m)"><path d="M12 3 19.5 6v5.5c0 4.6-3.1 8-7.5 9.5-4.4-1.5-7.5-4.9-7.5-9.5V6z"/><path d="M9 16v-3a3 3 0 0 1 6 0v3"/></g><path d="M4 4 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 554 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32"><rect x="1" y="1" width="30" height="30" rx="7" fill="#16181b" stroke="#3a3e44"/><path d="M9 10.5 16 22" fill="none" stroke="#e7e9ec" stroke-width="2.6" stroke-linecap="round"/><path d="M16 22 23 10.5" fill="none" stroke="#c8f031" stroke-width="2.6" stroke-linecap="round"/><circle cx="23" cy="10.5" r="1.9" fill="#c8f031"/></svg>
|
||||
|
After Width: | Height: | Size: 414 B |
@@ -0,0 +1,236 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:918
|
||||
msgid "Actions"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:914
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:915
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:916
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:43
|
||||
msgid "Authorization Required"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1092
|
||||
msgid "Auto"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:69
|
||||
msgid "Breadcrumb"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:263
|
||||
msgid "Buffered"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:274
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:284
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:288
|
||||
msgid "Cache"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:263
|
||||
msgid "Cached"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:344
|
||||
msgid "Channel"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:687
|
||||
msgid "Collapse navigation"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1093
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:81
|
||||
msgid "Colour theme"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:934
|
||||
msgid "Command palette"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1092
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:687
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:54
|
||||
msgid "Expand navigation"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:916
|
||||
msgid "Follow system theme"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:275
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:289
|
||||
msgid "Free"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:48
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:274
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:283
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:287
|
||||
msgid "In use"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:48
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:930
|
||||
msgid "Jump to a page or action…"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1092
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:23
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:60
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:917
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:84
|
||||
msgid "Log out"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:47
|
||||
msgid "Main navigation"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:258
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:273
|
||||
msgid "Memory"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1005
|
||||
msgid "No matching pages"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:90
|
||||
msgid "Page tabs"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:57
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:793
|
||||
msgid "Press"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:932
|
||||
msgid "Results"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:930
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:74
|
||||
msgid "Search pages"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:917
|
||||
msgid "Session"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:44
|
||||
msgid "Skip to content"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:310
|
||||
msgid "Storage"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:296
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:298
|
||||
msgid "Swap"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:263
|
||||
msgid "Swap free"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:275
|
||||
msgid "Total"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:262
|
||||
msgid "Total Available"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:914
|
||||
msgid "Use dark theme"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:915
|
||||
msgid "Use light theme"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:262
|
||||
msgid "Used"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:53
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:337
|
||||
msgid "Wireless"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:279
|
||||
msgid "available"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:940
|
||||
msgid "close"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:325
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:328
|
||||
msgid "free"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1007
|
||||
msgid "items"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:938
|
||||
msgid "navigate"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:939
|
||||
msgid "open"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:773
|
||||
msgid "page"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:773
|
||||
msgid "pages"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:274
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:284
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:288
|
||||
msgid "reclaimable"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:793
|
||||
msgid "to search all pages"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:325
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:328
|
||||
msgid "used"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
# Register the Vantage theme with LuCI (System -> Language and Style).
|
||||
# Select it only on a fresh install and only when the entry is new, so an
|
||||
# upgrade or a reinstall never overrides the theme the administrator chose.
|
||||
|
||||
new=0
|
||||
if [ -z "$(uci -q get luci.themes.Vantage)" ]; then
|
||||
new=1
|
||||
fi
|
||||
uci -q set luci.themes.Vantage=/luci-static/vantage || exit 1
|
||||
|
||||
if [ "$PKG_UPGRADE" != 1 ] && [ "$new" = 1 ]; then
|
||||
uci -q set luci.main.mediaurlbase=/luci-static/vantage
|
||||
fi
|
||||
|
||||
uci -q commit luci
|
||||
exit 0
|
||||
@@ -0,0 +1,33 @@
|
||||
{#
|
||||
Vantage theme - footer.
|
||||
Versions are shortened to what a person reads: "OpenWrt 25.12.3 · LuCI 26.124"
|
||||
(no git describe noise such as "(HEAD detached at …) branch" or "~hash"),
|
||||
entity-encoded, and only shown to logged-in users: error pages reach
|
||||
anonymous visitors too. The menu script is only loaded for a session.
|
||||
(The core header's L.env script still carries the LuCI build for
|
||||
everyone; see docs/luci-contract.md section 2.)
|
||||
-#}
|
||||
{% if (blank_page): %}
|
||||
</div>
|
||||
{% else %}
|
||||
</main>
|
||||
{%
|
||||
const dist_ver = match(version.distversion ?? '', /^[0-9A-Za-z][0-9A-Za-z.+-]*/);
|
||||
const luci_name = match(version.luciname ?? '', /^[A-Za-z][A-Za-z0-9]*/);
|
||||
const luci_ver = match(version.luciversion ?? '', /[0-9]+\.[0-9]+/);
|
||||
-%}
|
||||
<footer class="vt-foot">
|
||||
{% if (ctx.authsession): %}
|
||||
<span>{{ entityencode(version.distname ?? 'OpenWrt', true) }}{{ dist_ver ? ' ' + entityencode(dist_ver[0], true) : '' }}</span>
|
||||
<span class="vt-foot-sep" aria-hidden="true">·</span>
|
||||
<span>{{ entityencode(luci_name ? luci_name[0] : 'LuCI', true) }}{{ luci_ver ? ' ' + entityencode(luci_ver[0], true) : '' }}</span>
|
||||
{% endif %}
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if (ctx.authsession && !blank_page): %}
|
||||
<script>L.require('menu-vantage');</script>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,92 @@
|
||||
{#
|
||||
Vantage theme - header.
|
||||
Data-free: host details and the menu are fetched by menu-vantage.js over
|
||||
rpc after login. Everything request-derived is entity-encoded; visitors who
|
||||
are not logged in (login redirect, 404, CSRF error) get the bare frame with
|
||||
no menu, no host details and a generic title from this template. LuCI's
|
||||
core header.ut, which includes this one, then prints its own
|
||||
L = new LuCI({...}) script (LuCI build, nodespec; on an anonymous 404 the
|
||||
whole menu tree): upstream, see docs/luci-contract.md section 2.
|
||||
-#}
|
||||
{%
|
||||
const authed = !!ctx.authsession;
|
||||
const page_title = (authed && dispatched?.title) ? striptags(_(dispatched.title)) : 'LuCI';
|
||||
const lang = entityencode(dispatcher.lang ?? 'en', true);
|
||||
-%}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ lang }}" data-darkmode="true">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<meta name="color-scheme" content="dark light">
|
||||
<title>{{ entityencode(page_title, true) }} · LuCI</title>
|
||||
<script>
|
||||
(function (r) {
|
||||
var p = 'auto', rail = '';
|
||||
try { p = localStorage.getItem('vantage.theme') || 'auto'; rail = localStorage.getItem('vantage.rail') || ''; } catch (e) {}
|
||||
var dark = (p === 'dark') || (p !== 'light' && !!(window.matchMedia && matchMedia('(prefers-color-scheme: dark)').matches));
|
||||
r.setAttribute('data-darkmode', dark ? 'true' : 'false');
|
||||
r.setAttribute('data-theme', p);
|
||||
if (rail === 'pinned') r.setAttribute('data-rail', 'pinned');
|
||||
})(document.documentElement);
|
||||
</script>
|
||||
<link rel="stylesheet" href="{{ media }}/vantage.css">
|
||||
<link rel="stylesheet" href="{{ media }}/icons.css">
|
||||
<link rel="icon" href="{{ media }}/logo.svg" type="image/svg+xml">
|
||||
<script src="{{ entityencode(dispatcher.build_url('admin/translations', dispatcher.lang), true) }}"></script>
|
||||
<script src="{{ resource }}/cbi.js"></script>
|
||||
</head>
|
||||
<body class="lang_{{ lang }}{{ authed ? ' vt-auth' : ' vt-anon' }}" data-page="{{ entityencode(join('-', ctx.request_path), true) }}">
|
||||
{% if (blank_page): %}
|
||||
<div id="indicators" hidden></div>
|
||||
<div id="maincontent" class="vt-blank">
|
||||
{% else %}
|
||||
<a class="vt-skip" href="#maincontent">{{ entityencode(_('Skip to content'), true) }}</a>
|
||||
<div class="vt-shell">
|
||||
{% if (authed): %}
|
||||
<nav class="vt-rail" id="vt-rail" aria-label="{{ entityencode(_('Main navigation'), true) }}">
|
||||
<a class="vt-brand" href="{{ dispatcher.build_url('admin') }}" aria-label="{{ entityencode(_('Home'), true) }}">
|
||||
<svg viewBox="0 0 32 32" width="32" height="32" aria-hidden="true"><rect x="1" y="1" width="30" height="30" rx="7" class="vt-brand-tile"/><path d="M9 10.5 16 22" class="vt-brand-l"/><path d="M16 22 23 10.5" class="vt-brand-r"/><circle cx="23" cy="10.5" r="1.9" class="vt-brand-dot"/></svg>
|
||||
<span class="vt-brand-word">Vantage</span>
|
||||
</a>
|
||||
<ul class="vt-rail-list" id="vt-rail-list"></ul>
|
||||
<div class="vt-rail-foot">
|
||||
<button type="button" class="vt-rail-pin" id="vt-rail-pin" aria-pressed="false" aria-label="{{ entityencode(_('Expand navigation'), true) }}" title="{{ entityencode(_('Expand navigation'), true) }}">
|
||||
<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path d="M4 5v14M9 12h11M15 7l5 5-5 5"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="vt-flyout" id="vt-flyout" hidden></div>
|
||||
<div class="vt-scrim" id="vt-scrim" hidden></div>
|
||||
{% endif %}
|
||||
<div class="vt-frame">
|
||||
<header class="vt-topbar">
|
||||
{% if (!authed): %}
|
||||
<span class="vt-brand vt-brand-static" aria-hidden="true">
|
||||
<svg viewBox="0 0 32 32" width="28" height="28"><rect x="1" y="1" width="30" height="30" rx="7" class="vt-brand-tile"/><path d="M9 10.5 16 22" class="vt-brand-l"/><path d="M16 22 23 10.5" class="vt-brand-r"/><circle cx="23" cy="10.5" r="1.9" class="vt-brand-dot"/></svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
<nav class="vt-crumbs" id="vt-crumbs" aria-label="{{ entityencode(_('Breadcrumb'), true) }}"><span class="vt-crumb vt-crumb-current">{{ entityencode(page_title, true) }}</span></nav>
|
||||
<div class="vt-top-actions">
|
||||
{% if (authed): %}
|
||||
<button type="button" class="vt-search" id="vt-search-btn" aria-haspopup="dialog" aria-keyshortcuts="Control+K /">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><circle cx="11" cy="11" r="6.5"/><path d="m16 16 4.5 4.5"/></svg>
|
||||
<span class="vt-search-label">{{ entityencode(_('Search pages'), true) }}</span>
|
||||
<kbd class="vt-kbd">Ctrl K</kbd>
|
||||
</button>
|
||||
{% endif %}
|
||||
<div id="indicators" class="vt-indicators" aria-live="polite"></div>
|
||||
{% if (authed): %}
|
||||
<span class="vt-host" id="vt-host" hidden></span>
|
||||
<button type="button" class="vt-icon-btn" id="vt-theme" aria-label="{{ entityencode(_('Colour theme'), true) }}" title="{{ entityencode(_('Colour theme'), true) }}">
|
||||
<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><circle cx="12" cy="12" r="8"/><path d="M12 4a8 8 0 0 1 0 16z" class="vt-fill"/></svg>
|
||||
</button>
|
||||
<a class="vt-icon-btn" href="{{ dispatcher.build_url('admin/logout') }}" aria-label="{{ entityencode(_('Log out'), true) }}" title="{{ entityencode(_('Log out'), true) }}">
|
||||
<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path d="M14 4h4.5A1.5 1.5 0 0 1 20 5.5v13a1.5 1.5 0 0 1-1.5 1.5H14"/><path d="M10 8l-4 4 4 4M6 12h10"/></svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</header>
|
||||
<nav class="vt-tabs" id="vt-tabs" aria-label="{{ entityencode(_('Page tabs'), true) }}" hidden></nav>
|
||||
<main id="maincontent" class="vt-main">
|
||||
{% endif %}
|
||||
@@ -0,0 +1,83 @@
|
||||
{#
|
||||
Vantage theme - login page.
|
||||
Rendered with { duser, fuser } for visitors who are not logged in, so it
|
||||
shows nothing about the device: no hostname, model or firmware version.
|
||||
fuser is attacker-controlled (formvalue also reads the query string): it is
|
||||
only tested, never echoed; the error is generic. The form posts back to the
|
||||
requested URL (no action attribute). The inline script is data-free: the
|
||||
HTTPS probe reads its port list from an entity-encoded data attribute.
|
||||
-#}
|
||||
{%
|
||||
let tls = uci.get('uhttpd', 'main', 'listen_https') ?? [];
|
||||
if (type(tls) == 'string')
|
||||
tls = split(tls, /\s+/);
|
||||
const tls_ports = uniq(filter(map(tls, e => +(match(e, /\d+$/)?.[0] ?? 0)), p => (p > 0 && p <= 65535)));
|
||||
-%}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ entityencode(dispatcher.lang ?? 'en', true) }}" data-darkmode="true">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<meta name="color-scheme" content="dark light">
|
||||
<meta name="robots" content="noindex">
|
||||
<title>{{ entityencode(_('Log in'), true) }} · LuCI</title>
|
||||
<script>
|
||||
(function (r) {
|
||||
var p = 'auto';
|
||||
try { p = localStorage.getItem('vantage.theme') || 'auto'; } catch (e) {}
|
||||
var dark = (p === 'dark') || (p !== 'light' && !!(window.matchMedia && matchMedia('(prefers-color-scheme: dark)').matches));
|
||||
r.setAttribute('data-darkmode', dark ? 'true' : 'false');
|
||||
r.setAttribute('data-theme', p);
|
||||
})(document.documentElement);
|
||||
</script>
|
||||
<link rel="stylesheet" href="{{ media }}/vantage.css">
|
||||
<link rel="icon" href="{{ media }}/logo.svg" type="image/svg+xml">
|
||||
</head>
|
||||
<body class="vt-login-page" data-page="{{ entityencode(join('-', ctx.request_path), true) }}">
|
||||
<main class="vt-login">
|
||||
<div class="vt-login-card">
|
||||
<div class="vt-login-head">
|
||||
<svg class="vt-login-mark" viewBox="0 0 32 32" width="44" height="44" aria-hidden="true"><rect x="1" y="1" width="30" height="30" rx="7" class="vt-brand-tile"/><path d="M9 10.5 16 22" class="vt-brand-l"/><path d="M16 22 23 10.5" class="vt-brand-r"/><circle cx="23" cy="10.5" r="1.9" class="vt-brand-dot"/></svg>
|
||||
<div>
|
||||
<h1 class="vt-login-title">Vantage</h1>
|
||||
<p class="vt-login-sub"><span class="vt-live-dot" aria-hidden="true"></span>{{ entityencode(_('Authorization Required'), true) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if (fuser): %}
|
||||
<div class="vt-login-error" role="alert">{{ entityencode(_('Invalid username and/or password! Please try again.'), true) }}</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" class="vt-login-form" data-https-ports="{{ entityencode(sprintf('%J', tls_ports), true) }}" data-https-probe="{{ entityencode(resource + '/icons/loading.svg', true) }}">
|
||||
<label class="vt-field">
|
||||
<span class="vt-field-label">{{ entityencode(_('Username'), true) }}</span>
|
||||
<input class="cbi-input-text" type="text" name="luci_username" autocomplete="username" autocapitalize="off" spellcheck="false" required value="{{ entityencode(duser ?? '', true) }}">
|
||||
</label>
|
||||
<label class="vt-field">
|
||||
<span class="vt-field-label">{{ entityencode(_('Password'), true) }}</span>
|
||||
<input class="cbi-input-password" type="password" name="luci_password" autocomplete="current-password" autofocus>
|
||||
</label>
|
||||
<button type="submit" class="btn cbi-button cbi-button-apply vt-login-submit">{{ entityencode(_('Log in'), true) }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
(function (form) {
|
||||
var pw = document.querySelector('input[name="luci_password"]');
|
||||
if (pw) pw.focus();
|
||||
if (!form || location.protocol === 'https:') return;
|
||||
var ports = [];
|
||||
try { ports = JSON.parse(form.getAttribute('data-https-ports') || '[]'); } catch (e) {}
|
||||
var probePath = form.getAttribute('data-https-probe') || '';
|
||||
if (!Array.isArray(ports) || probePath.charAt(0) !== '/') return;
|
||||
ports.forEach(function (port) {
|
||||
if (typeof port !== 'number' || port < 1 || port > 65535 || port % 1) return;
|
||||
var probe = new Image(), base = 'https://' + location.hostname + ':' + port;
|
||||
probe.onload = function () { location = base + location.pathname; };
|
||||
probe.src = base + probePath + '?' + Math.random();
|
||||
setTimeout(function () { probe.src = ''; }, 5000);
|
||||
});
|
||||
})(document.querySelector('form.vt-login-form'));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||