This commit is contained in:
alazhar committed 2026-04-27 19:45:25 +07:00
commit d2bf90ccec
9 files changed
+412

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
# Use the lightest official nginx image
FROM nginx:alpine
# Copy static files to the nginx server directory
COPY . /usr/share/nginx/html
# Expose port 80
EXPOSE 80
+6
View File
@@ -0,0 +1,6 @@
@charset "UTF-8";/*!
* Bootstrap v5.3.0 (https://getbootstrap.com/)
* Copyright 2011-2023 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#adb5bd;--bs-body-color-rgb:173,181,189;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(173, 181, 189, 0.75);--bs-secondary-color-rgb:173,181,189;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(173, 181, 189, 0.5);--bs-tertiary-color-rgb:173,181,189;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--Line truncated
/*# sourceMappingURL=bootstrap.min.css.map */
+5
View File
@@ -0,0 +1,5 @@
:root{--dt-row-selected: 13, 110, 253;--dt-row-selected-text: 255, 255, 255;--dt-row-selected-link: 9, 10, 11;--dt-row-stripe: 0, 0, 0;--dt-row-hover: 0, 0, 0;--dt-column-ordering: 0, 0, 0;--dt-html-background: white}:root.dark{--dt-html-background: rgb(33, 37, 41)}table.dataTable td.dt-control{text-align:center;cursor:pointer}table.dataTable td.dt-control:before{display:inline-block;color:rgba(0, 0, 0, 0.5);content:"►"}table.dataTable tr.dt-hasChild td.dt-control:before{content:"▼"}html.dark table.dataTable td.dt-control:before{color:rgba(255, 255, 255, 0.5)}html.dark table.dataTable tr.dt-hasChild td.dt-control:before{color:rgba(255, 255, 255, 0.5)}table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting_asc_disabled,table.dataTable thead>tr>th.sorting_desc_disabled,table.dataTable thead>tr>td.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting_asc_disabled,table.dataTable thead>tr>td.sorting_desc_disabled{cursor:pointer;position:relative;padding-right:26px}table.dataTable thead>tr>th.sorting:before,table.dataTable thead>tr>th.sorting:after,table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_asc:after,table.dataTable thead>tr>th.sorting_desc:before,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>th.sorting_asc_disabled:after,table.dataTable thead>tr>th.sorting_desc_disabled:before,table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting:before,table.dataTable thead>tr>td.sorting:after,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_asc:after,table.dataTable thead>tr>td.sorting_desc:before,table.dataTable thead>tr>td.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_asc_disabled:after,table.dataTable thead>tr>td.sorting_desc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:after{position:absolute;display:block;opacity:.125;right:10px;line-height:9px;font-size:.8em}table.dataTable thead>tr>th.sorting:before,table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_desc:before,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>th.sorting_desc_disabled:before,table.dataTable thead>tr>td.sorting:before,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_desc:before,table.dataTable thead>tr>td.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:before{bottom:50%;content:"▲";content:"▲"/""}table.dataTable thead>tr>th.sorting:after,table.dataTable thead>tr>th.sorting_asc:after,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>th.sorting_asc_disabled:after,table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting:after,table.dataTable thead>tr>td.sorting_asc:after,table.dataTable thead>tr>td.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc_disabled:after,table.dataTable thead>tr>td.sorting_desc_disabled:after{top:50%;content:"▼";content:"▼"/""}table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_desc:after{opacity:.6}table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting_asc_disabled:before{display:none}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}div.dataTables_scrollBody>table.dataTable>thead>tr>th:before,div.dataTables_scrollBody>table.dataTable>thead>tr>th:after,div.dataTables_scrollBody>table.dataTable>thead>tr>td:before,div.dataTables_scrollBody>table.dataTable>thead>tr>td:after{display:none}div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:2px}div.dataTables_processing>div:last-child{position:relative;width:80px;height:15px;margin:1em auto}div.dataTables_processing>div:last-child>div{position:absolute;top:0;width:13px;height:13px;border-radius:50%;background:rgb(13, 110, 253);background:rgb(var(--dt-row-selected));animation-timing-function:cubic-bezier(0, 1, 1, 0)}div.dataTables_processing>div:last-child>div:nth-child(1){left:8px;animation:datatables-loader-1 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(2){left:8px;animation:datatables-loader-2 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(3){left:32px;animation:datatables-loader-2 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(4){left:56px;animation:datatables-loader-3 .6s infinite}@keyframes datLine truncated
*
* ©2020 SpryMedia Ltd, all rights reserved.
* License: MIT datatables.net/license/mit
*/table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important;border-collapse:separate !important;border-spacing:0}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.table-striped>tbody>tr:nth-of-type(2n+1)>*{box-shadow:none}table.dataTable>tbody>tr{background-color:transparent}table.dataTable>tbody>tr.selected>*{box-shadow:inset 0 0 0 9999px rgb(13, 110, 253);box-shadow:inset 0 0 0 9999px rgb(var(--dt-row-selected));color:rgb(255, 255, 255);color:rgb(var(--dt-row-selected-text))}table.dataTable>tbody>tr.selected a{color:rgb(9, 10, 11);color:rgb(var(--dt-row-selected-link))}table.dataTable.table-striped>tbody>tr.odd>*{box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-stripe), 0.05)}table.dataTable.table-striped>tbody>tr.odd.selected>*{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.95);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.95)}table.dataTable.table-hover>tbody>tr:hover>*{box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.075)}table.dataTable.table-hover>tbody>tr.selected:hover>*{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.975);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.975)}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:auto;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:.85em}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap;justify-content:flex-end}div.dataTables_wrapper div.dt-row{position:relative}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody>table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody>table>thead .sorting:before,div.dataTables_scrollBody>table>thead .sorting_asc:before,div.dataTables_scrollBody>table>thead .sorting_desc:before,div.dataTables_scrollBody>table>thead .sorting:after,div.dataTables_scrollBody>table>thead .sorting_asc:after,div.dataTables_scrollBody>table>thead .sorting_desc:after{display:none}div.dataTables_scrollBody>table>tbody tr:first-child th,div.dataTables_scrollBody>table>tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot>.dataTables_scrollFootInner{box-sizing:content-box}div.dataTables_scrollFoot>.dataTables_scrollFootInner>table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}div.dataTables_wrapper div.dataTables_paginate ul.pagination{justify-content:center !important}}table.dataTable.table-sm>thead>tr>th:not(.sorting_disabled){padding-right:20px}table.table-bordered.dataTable{border-right-width:0}table.table-bordered.dataTable thead tr:first-child th,table.table-bordered.dataTable thead tr:first-child td{border-top-width:1px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:first-child,table.table-bordered.dataTable th:first-child,table.table-bordered.dataTable td:first-child,table.table-bordered.dataTable td:first-child{border-left-width:1px}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:1px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-bottom-width:1px}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^=col-]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^=col-]:last-child{padding-right:0}:root[data-bs-theme=dark]{--dt-row-hover: 255, 255, 255;--dt-row-stripe: 255, 255, 255;--dt-column-ordering: 255, 255, 255}
+364
View File
@@ -0,0 +1,364 @@
<!DOCTYPE html>
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Log Viewer</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/dataTables.bootstrap5.min.css" rel="stylesheet">
<script src="js/lucide.min.js"></script>
<style>
:root {
--sidebar-width: 280px;
--brand-color: #4ade80;
--bg-light: #f8fafc;
--bg-dark: #0f172a;
--card-light: #ffffff;
--card-dark: #1e293b;
}
[data-bs-theme="light"] {
--body-bg: var(--bg-light);
--card-bg: var(--card-light);
--border-color: #e2e8f0;
--text-main: #334155;
}
[data-bs-theme="dark"] {
--body-bg: var(--bg-dark);
--card-bg: var(--card-dark);
--border-color: #334155;
--text-main: #f1f5f9;
}
body {
background-color: var(--body-bg);
color: var(--text-main);
font-family: 'Inter', system-ui, -apple-system, sans-serif;
font-size: 0.85rem;
height: 100vh;
overflow: hidden;
}
/* Layout Structure */
.wrapper { display: flex; height: 100vh; }
/* Sidebar */
aside {
width: var(--sidebar-width);
background: var(--card-bg);
border-right: 1px solid var(--border-color);
display: flex;
flex-direction: column;
}
.sidebar-header { padding: 1.5rem; border-bottom: 1px solid var(--border-color); }
.file-list { overflow-y: auto; flex-grow: 1; padding: 0.5rem; }
.file-item {
padding: 8px 12px;
border-radius: 6px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2px;
transition: 0.2s;
}
.file-item:hover { background: rgba(74, 222, 128, 0.1); }
.file-item.active { background: rgba(74, 222, 128, 0.2); color: var(--brand-color); font-weight: 600; }
.file-size { font-size: 0.7rem; opacity: 0.6; }
/* Main Content */
main { flex-grow: 1; display: flex; flex-direction: column; overflow: hidden; }
.top-bar {
padding: 1rem 1.5rem;
background: var(--card-bg);
border-bottom: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
align-items: center;
}
/* Stats & Toggles */
.level-toggles .btn {
border: none;
font-size: 0.75rem;
font-weight: 600;
padding: 5px 12px;
margin-right: 5px;
display: inline-flex;
align-items: center;
gap: 6px;
}
.btn-check:not(:checked) + .btn { opacity: 0.4; filter: grayscale(1); }
/* Level Colors */
.btn-trc { background: #64748b; color: white; }
.btn-dbg { background: #0ea5e9; color: white; }
.btn-inf { background: #10b981; color: white; }
.btn-wrn { background: #f59e0b; color: white; }
.btn-err { background: #ef4444; color: white; }
.btn-crt { background: #a855f7; color: white; }
/* Search & Controls */
.search-wrapper { position: relative; width: 300px; }
.search-wrapper input {
background: rgba(0,0,0,0.1);
border: 1px solid var(--border-color);
border-radius: 6px;
padding: 6px 12px 6px 35px;
width: 100%;
}
.search-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); opacity: 0.5; }
/* Table Area */
.content-area { flex-grow: 1; padding: 1.5rem; overflow-y: auto; }
.table-container { background: var(--card-bg); border-radius: 8px; border: 1px solid var(--border-color); overflow: hidden; }
table.dataTable { margin: 0 !important; border: none; }
table.dataTable thead th {
background: rgba(0,0,0,0.02);
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.5px;
padding: 12px 15px !important;
border-bottom: 1px solid var(--border-color) !important;
}
.lvl-indicator { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 8px; }
.row-TRC .lvl-indicator { background: #64748b; }
.row-DBG .lvl-indicator { background: #0ea5e9; }
.row-INF .lvl-indicator { background: #10b981; }
.row-WRN .lvl-indicator { background: #f59e0b; }
.row-ERR .lvl-indicator { background: #ef4444; }
.row-CRT .lvl-indicator { background: #a855f7; }
.exception-row { background: #000 !important; color: #fb7185 !important; font-family: 'Fira Code', monospace; font-size: 0.75rem; }
.details-btn { cursor: pointer; opacity: 0.5; }
.details-btn:hover { opacity: 1; color: var(--brand-color); }
</style>
</head>
<body>
<div class="wrapper">
<aside>
<div class="sidebar-header">
<h5 class="mb-3 d-flex align-items-center gap-2">
<i data-lucide="scroll-text" class="text-success"></i> Log Viewer
</h5>
<button class="btn btn-sm btn-outline-secondary w-100" onclick="document.getElementById('dir-input').click()">
<i data-lucide="folder-open" size="14"></i> Select Directory
</button>
<input type="file" id="dir-input" webkitdirectory hidden>
</div>
<div class="file-list" id="file-list">
<div class="text-center mt-5 opacity-50 small">No logs loaded</div>
</div>
</aside>
<main>
<div class="top-bar">
<div class="level-toggles d-flex align-items-center" id="filter-buttons">
<input type="checkbox" class="btn-check" id="toggle-DBG" checked value="DBG">
<label class="btn btn-dbg" for="toggle-DBG">Debug: <span id="count-DBG">0</span></label>
<input type="checkbox" class="btn-check" id="toggle-INF" checked value="INF">
<label class="btn btn-inf" for="toggle-INF">Info: <span id="count-INF">0</span></label>
<input type="checkbox" class="btn-check" id="toggle-WRN" checked value="WRN">
<label class="btn btn-wrn" for="toggle-WRN">Warning: <span id="count-WRN">0</span></label>
<input type="checkbox" class="btn-check" id="toggle-ERR" checked value="ERR">
<label class="btn btn-err" for="toggle-ERR">Error: <span id="count-ERR">0</span></label>
</div>
<div class="d-flex align-items-center gap-3">
<div class="search-wrapper">
<i data-lucide="search" size="16" class="search-icon"></i>
<input type="text" id="global-search" placeholder="Search... RegEx welcome!">
</div>
<div class="btn-group">
<button class="btn btn-link p-1 text-reset" id="theme-toggle" title="Toggle Dark/Light">
<i data-lucide="sun"></i>
</button>
<button class="btn btn-link p-1 text-reset" onclick="location.reload()" title="Refresh">
<i data-lucide="refresh-cw"></i>
</button>
</div>
</div>
</div>
<div class="content-area">
<div class="table-container shadow-sm">
<table id="log-table" class="table table-hover w-100">
<thead>
<tr>
<th width="30"></th>
<th width="100">Level</th>
<th width="150">Time</th>
<th>Description</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</main>
</div>
<div class="modal fade" id="detailModal" tabindex="-1">
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h6 class="modal-title">Log Entry Details</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body p-0">
<pre id="modal-content" class="m-0 p-3 bg-black text-danger-emphasis" style="font-size: 0.8rem; overflow-x: auto;"></pre>
</div>
</div>
</div>
</div>
<script src="js/jquery-3.7.0.min.js"></script>
<script src="js/jquery.dataTables.min.js"></script>
<script src="js/dataTables.bootstrap5.min.js"></script>
<script src="js/bootstrap.bundle.min.js"></script>
<script>
lucide.createIcons();
let currentLogs = [];
$(document).ready(function() {
const table = $('#log-table').DataTable({
dom: 'rtip',
pageLength: 50,
order: [[2, 'desc']],
columns: [
{
className: 'details-btn text-center',
orderable: false,
data: null,
render: (d, t, row) => row.exception ? '<i data-lucide="maximize-2" size="14"></i>' : ''
},
{
data: 'level',
render: l => `<span class="lvl-indicator"></span><strong>${l}</strong>`
},
{ data: 'time', className: 'text-muted' },
{
data: 'message',
render: m => `<span class="text-truncate d-block" style="max-width: 800px;">${m}</span>`
}
],
createdRow: function(row, data) {
$(row).addClass('row-' + data.level);
}
});
// Regex Search
$('#global-search').on('keyup', function() {
table.search(this.value, true, false).draw();
});
// Theme Toggle
$('#theme-toggle').on('click', () => {
const current = $('html').attr('data-bs-theme');
const target = current === 'dark' ? 'light' : 'dark';
$('html').attr('data-bs-theme', target);
$('#theme-toggle i').attr('data-lucide', target === 'dark' ? 'sun' : 'moon');
lucide.createIcons();
});
// Filter Buttons Logic
$('.btn-check').on('change', function() {
table.draw();
});
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
const level = data[1];
const checkedLevels = $('.btn-check:checked').map((i, el) => $(el).val()).get();
return checkedLevels.includes(level);
});
// Directory Selection
$('#dir-input').on('change', function(e) {
const files = Array.from(e.target.files).filter(f => f.name.endsWith('.log'));
const list = $('#file-list').empty();
files.forEach((file, idx) => {
const size = (file.size / 1024).toFixed(2) + ' KB';
list.append(`
<div class="file-item" onclick="loadLogFile(this, ${idx})">
<span>${file.name}</span>
<span class="file-size">${size}</span>
</div>
`);
file.raw = file;
});
window.loadedFiles = files;
});
// File Loading
window.loadLogFile = function(el, idx) {
$('.file-item').removeClass('active');
$(el).addClass('active');
const file = window.loadedFiles[idx];
const reader = new FileReader();
reader.onload = function(e) {
const parsed = parseLogs(e.target.result);
currentLogs = parsed;
table.clear().rows.add(parsed).draw();
updateCounts(parsed);
lucide.createIcons();
};
reader.readAsText(file);
};
function parseLogs(text) {
const lines = text.split(/\r?\n/);
const logs = [];
const headerRegex = /^(\d{2}:\d{2}:\d{2}\.\d{3})\s\[(\w+)\]\s(.*)$/;
lines.forEach(line => {
if (!line.trim()) return;
const match = line.match(headerRegex);
if (match) {
let content = match[3];
let msg = content, props = "";
const lastParen = content.lastIndexOf(' (');
if (lastParen !== -1 && content.endsWith(')')) {
msg = content.substring(0, lastParen).trim();
props = content.substring(lastParen + 2, content.length - 1);
}
logs.push({ time: match[1], level: match[2], message: msg, props, exception: "" });
} else if (logs.length > 0) {
logs[logs.length - 1].exception += line + "\n";
}
});
return logs;
}
function updateCounts(logs) {
const counts = { DBG: 0, INF: 0, WRN: 0, ERR: 0, CRT: 0 };
logs.forEach(l => { if(counts[l.level] !== undefined) counts[l.level]++; });
Object.keys(counts).forEach(lvl => {
$(`#count-${lvl}`).text(counts[lvl].toLocaleString());
});
}
// Row Detail Modal
$('#log-table tbody').on('click', '.details-btn', function() {
const data = table.row($(this).closest('tr')).data();
const fullContent = `[${data.time}] [${data.level}] ${data.message}\n\nProperties: ${data.props}\n\n${data.exception}`;
$('#modal-content').text(fullContent);
new bootstrap.Modal('#detailModal').show();
});
});
</script>
</body>
</html>
+7
View File
@@ -0,0 +1,7 @@
/*!
* Bootstrap v5.3.0 (https://getbootstrap.com/)
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=N(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return M(s,{delegateTarget:r}),n.oneOff&&P.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return M(n,{delegateTarget:t}),i.oneOff&&P.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function I(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function N(t){return t=t.replace(y,""),T[t]||t}const P={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))I(t,l,i,e.slLine truncated
//# sourceMappingURL=bootstrap.bundle.min.js.map
+4
View File
@@ -0,0 +1,4 @@
/*! DataTables Bootstrap 5 integration
* 2020 SpryMedia Ltd - datatables.net/license
*/
!function(t){var n,r;"function"==typeof define&&define.amd?define(["jquery","datatables.net"],function(e){return t(e,window,document)}):"object"==typeof exports?(n=require("jquery"),r=function(e,a){a.fn.dataTable||require("datatables.net")(e,a)},"undefined"==typeof window?module.exports=function(e,a){return e=e||window,a=a||n(e),r(e,a),t(a,0,e.document)}:(r(window,n),module.exports=t(n,window,window.document))):t(jQuery,window,document)}(function(x,e,r,o){"use strict";var i=x.fn.dataTable;return x.extend(!0,i.defaults,{dom:"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>><'row dt-row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",renderer:"bootstrap"}),x.extend(i.ext.classes,{sWrapper:"dataTables_wrapper dt-bootstrap5",sFilterInput:"form-control form-control-sm",sLengthSelect:"form-select form-select-sm",sProcessing:"dataTables_processing card",sPageButton:"paginate_button page-item"}),i.ext.renderer.pageButton.bootstrap=function(d,e,s,a,l,c){function u(e,a){for(var t,n,r=function(e){e.preventDefault(),x(e.currentTarget).hasClass("disabled")||b.page()==e.data.action||b.page(e.data.action).draw("page")},o=0,i=a.length;o<i;o++)if(t=a[o],Array.isArray(t))u(e,t);else{switch(f=p="",t){case"ellipsis":p="&#x2026;",f="disabled";break;case"first":p=g.sFirst,f=t+(0<l?"":" disabled");break;case"previous":p=g.sPrevious,f=t+(0<l?"":" disabled");break;case"next":p=g.sNext,f=t+(l<c-1?"":" disabled");break;case"last":p=g.sLast,f=t+(l<c-1?"":" disabled");break;default:p=t+1,f=l===t?"active":""}p&&(n=-1!==f.indexOf("disabled"),n=x("<li>",{class:m.sPageButton+" "+f,id:0===s&&"string"==typeof t?d.sTableId+"_"+t:null}).append(x("<a>",{href:n?null:"#","aria-controls":d.sTableId,"aria-disabled":n?"true":null,"aria-label":w[t],role:"link","aria-current":"active"===f?"page":null,"data-dt-idx":t,tabindex:n?-1:d.iTabIndex,class:"page-link"}).html(p)).appendTo(e),d.oApi._fnBindAction(n,{action:t},r))}}var p,f,t,b=new i.Api(d),m=d.oClasses,g=d.oLanguage.oPaginate,w=d.oLanguage.oAria.paginate||{},e=x(e);try{t=e.find(r.activeElement).data("dt-idx")}catch(e){}var n=e.children("ul.pagination");n.length?n.empty():n=e.html("<ul/>").children("ul").addClass("pagination"),u(n,a),t!==o&&e.find("[data-dt-idx="+t+"]").trigger("focus")},i});
+2
View File
@@ -0,0 +1,2 @@
/*! jQuery v3.7.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.0",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}function fe(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}ce.fn=ce.prototype={jquery:t,constructor:ce,length:0,toArray:function(){return ae.call(this)},get:function(e){return null==e?ae.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=ce.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return ce.each(this,e)},map:function(n){return this.pushStack(ce.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(ae.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(ce.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(ce.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:oe.sort,splice:oe.splice},ce.extend=ce.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||v(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(ce.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||ce.isPlainObject(n)?n:{},i=!1,a[t]=ce.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},ce.extend({expando:"jQuery"+(t+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==i.call(e))&&(!(t=r(e))||"function"==typeof(n=ue.call(t,"constructor")&&t.constructor)&&o.call(n)===a)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){m(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(c(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},text:function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i)return e.textContent;if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=ce.text(t);return n},makeArray:function(e,t){var n=t||[];return null!=e&&(c(Object(e))?ce.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:se.call(t,e,n)},isXMLDoc:function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!l.test(t||n&&n.nodeName||"HTML")},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(c(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:le}),"function"==typeof Symbol&&(ce.fn[Symbol.iterator]=oe[Symbol.iterator]),ce.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var pe=oe.pop,de=oe.sort,he=oe.splice,ge="[\\x20\\t\\r\\n\\f]",ve=new RegExp("^"+ge+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ge+"+$","g");ce.contains=function(e,t){var n=t&&t.parentNode;return e===n||!(!n||1!==n.nodeType||!(e.contains?e.contains(n):e.compareDocumentPosition&&16&e.compareDocumentPosition(n)))};var f=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;function p(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e}ce.escapeSelector=function(e){return(e+"").replace(f,p)};var ye=C,me=s;!function(){var e,b,w,o,a,T,r,C,d,i,k=me,S=ce.expando,E=0,n=0,s=W(),c=W(),u=W(),h=W(),l=function(e,t){return e===t&&(a=!0),0},f="checked|selected|async|autofocus|autoplay|controlLine truncated
+4
View File
@@ -0,0 +1,4 @@
/*! DataTables 1.13.6
* ©2008-2023 SpryMedia Ltd - datatables.net/license
*/
!function(n){"use strict";var a;"function"==typeof define&&define.amd?define(["jquery"],function(t){return n(t,window,document)}):"object"==typeof exports?(a=require("jquery"),"undefined"==typeof window?module.exports=function(t,e){return t=t||window,e=e||a(t),n(e,t,t.document)}:n(a,window,window.document)):window.DataTable=n(jQuery,window,document)}(function(P,j,v,H){"use strict";function d(t){var e=parseInt(t,10);return!isNaN(e)&&isFinite(t)?e:null}function l(t,e,n){var a=typeof t,r="string"==a;return"number"==a||"bigint"==a||!!h(t)||(e&&r&&(t=$(t,e)),n&&r&&(t=t.replace(q,"")),!isNaN(parseFloat(t))&&isFinite(t))}function a(t,e,n){var a;return!!h(t)||(h(a=t)||"string"==typeof a)&&!!l(t.replace(V,"").replace(/<script/i,""),e,n)||null}function m(t,e,n,a){var r=[],o=0,i=e.length;if(a!==H)for(;o<i;o++)t[e[o]][n]&&r.push(t[e[o]][n][a]);else for(;o<i;o++)r.push(t[e[o]][n]);return r}function f(t,e){var n,a=[];e===H?(e=0,n=t):(n=e,e=t);for(var r=e;r<n;r++)a.push(r);return a}function _(t){for(var e=[],n=0,a=t.length;n<a;n++)t[n]&&e.push(t[n]);return e}function s(t,e){return-1!==this.indexOf(t,e=e===H?0:e)}var p,e,t,w=function(t,v){if(w.factory(t,v))return w;if(this instanceof w)return P(t).DataTable(v);v=t,this.$=function(t,e){return this.api(!0).$(t,e)},this._=function(t,e){return this.api(!0).rows(t,e).data()},this.api=function(t){return new B(t?ge(this[p.iApiIndex]):this)},this.fnAddData=function(t,e){var n=this.api(!0),t=(Array.isArray(t)&&(Array.isArray(t[0])||P.isPlainObject(t[0]))?n.rows:n.row).add(t);return e!==H&&!e||n.draw(),t.flatten().toArray()},this.fnAdjustColumnSizing=function(t){var e=this.api(!0).columns.adjust(),n=e.settings()[0],a=n.oScroll;t===H||t?e.draw(!1):""===a.sX&&""===a.sY||Qt(n)},this.fnClearTable=function(t){var e=this.api(!0).clear();t!==H&&!t||e.draw()},this.fnClose=function(t){this.api(!0).row(t).child.hide()},this.fnDeleteRow=function(t,e,n){var a=this.api(!0),t=a.rows(t),r=t.settings()[0],o=r.aoData[t[0][0]];return t.remove(),e&&e.call(this,r,o),n!==H&&!n||a.draw(),o},this.fnDestroy=function(t){this.api(!0).destroy(t)},this.fnDraw=function(t){this.api(!0).draw(t)},this.fnFilter=function(t,e,n,a,r,o){var i=this.api(!0);(null===e||e===H?i:i.column(e)).search(t,n,a,o),i.draw()},this.fnGetData=function(t,e){var n,a=this.api(!0);return t!==H?(n=t.nodeName?t.nodeName.toLowerCase():"",e!==H||"td"==n||"th"==n?a.cell(t,e).data():a.row(t).data()||null):a.data().toArray()},this.fnGetNodes=function(t){var e=this.api(!0);return t!==H?e.row(t).node():e.rows().nodes().flatten().toArray()},this.fnGetPosition=function(t){var e=this.api(!0),n=t.nodeName.toUpperCase();return"TR"==n?e.row(t).index():"TD"==n||"TH"==n?[(n=e.cell(t).index()).row,n.columnVisible,n.column]:null},this.fnIsOpen=function(t){return this.api(!0).row(t).child.isShown()},this.fnOpen=function(t,e,n){return this.api(!0).row(t).child(e,n).show().child()[0]},this.fnPageChange=function(t,e){t=this.api(!0).page(t);e!==H&&!e||t.draw(!1)},this.fnSetColumnVis=function(t,e,n){t=this.api(!0).column(t).visible(e);n!==H&&!n||t.columns.adjust().draw()},this.fnSettings=function(){return ge(this[p.iApiIndex])},this.fnSort=function(t){this.api(!0).order(t).draw()},this.fnSortListener=function(t,e,n){this.api(!0).order.listener(t,e,n)},this.fnUpdate=function(t,e,n,a,r){var o=this.api(!0);return(n===H||null===n?o.row(e):o.cell(e,n)).data(t),r!==H&&!r||o.columns.adjust(),a!==H&&!a||o.draw(),0},this.fnVersionCheck=p.fnVersionCheck;var e,y=this,D=v===H,_=this.length;for(e in D&&(v={}),this.oApi=this.internal=p.internal,w.ext.internal)e&&(this[e]=$e(e));return this.each(function(){var r=1<_?be({},v,!0):v,o=0,t=this.getAttribute("id"),i=!1,e=w.defaults,l=P(this);if("table"!=this.nodeName.toLowerCase())W(null,0,"Non-table node initialisation ("+this.nodeName+")",2);else{K(e),Q(e.column),C(e,e,!0),C(e.column,e.column,!0),C(e,P.extend(r,l.data()),!0);for(var n=w.settings,o=0,s=n.length;o<s;o++){var a=n[o];if(a.nTable==this||a.nTHead&&a.nTHead.parentNode==this||a.nTFoot&&a.nTFoot.parentNode==this){var u=(r.bRetrieve!==H?r:e).bRetrieve,c=(r.bDestroy!==H?r:e).bDestroy;if(D||u)return a.oInstance;if(c){a.oInstance.fnDestroy();break}return void W(a,0,"Cannot reinitialise DataTable",3)}if(a.sTableId==this.id){n.splice(o,1);break}}null!==t&&""!==t||(t="DataTables_Table_"+w.ext._unique++,this.id=t);var f,d,h=P.extend(!0,{},w.models.oSettings,{sDestroyWidth:l[0].style.width,sInstance:t,sTableId:t}),p=(h.nTable=this,h.oApi=y.internal,h.oInit=r,n.push(h),h.oInstance=1===y.length?y:l.dataTable(),K(r),Z(r.oLanguage),r.aLengthMenu&&!r.iDisplayLength&&(r.iDisplayLength=(Array.isArray(r.aLengthMenu[0])?r.aLengthMenu[0]:r.aLengthMenu)[0]),r=be(P.extend(!0,{},e),r),F(h.oFeatures,r,["bPaginate","bLengthChange","bFilter","bSort","bSortMulti","bInfo","bProcessing","bAutoWidth","bSortClasses","bServerSide","bDeferRender"]),F(h,r,["asStripeClasses","ajax","fnServerData","fnFormatNumber","sServerMethod","aaSorting","aaSortingFixed","aLengthMenu","sPaginationType","sAjaxSource","sLine truncated
+12
View File
@@ -0,0 +1,12 @@
/**
* @license lucide v1.11.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
(function(a,n){typeof exports=="object"&&typeof module<"u"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(a=typeof globalThis<"u"?globalThis:a||self,n(a.lucide={}))})(this,(function(a){"use strict";const n={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"},fa=([t,h,d])=>{const c=document.createElementNS("http://www.w3.org/2000/svg",t);return Object.keys(h).forEach(M=>{c.setAttribute(M,String(h[M]))}),d?.length&&d.forEach(M=>{const p=fa(M);c.appendChild(p)}),c},ka=(t,h={})=>{const d={...n,...h};return fa(["svg",d,t])},Xu=t=>{for(const h in t)if(h.startsWith("aria-")||h==="role"||h==="title")return!0;return!1},ju=(...t)=>t.filter((h,d,c)=>!!h&&h.trim()!==""&&c.indexOf(h)===d).join(" ").trim(),Nu=t=>t.replace(/^([A-Z])|[\s-_]+(\w)/g,(h,d,c)=>c?c.toUpperCase():d.toLowerCase()),Ku=t=>{const h=Nu(t);return h.charAt(0).toUpperCase()+h.slice(1)},Qu=t=>Array.from(t.attributes).reduce((h,d)=>(h[d.name]=d.value,h),{}),Pa=t=>typeof t=="string"?t:!t||!t.class?"":t.class&&typeof t.class=="string"?t.class.split(" "):t.class&&Array.isArray(t.class)?t.class:"",Ba=(t,{nameAttr:h,icons:d,attrs:c})=>{const M=t.getAttribute(h);if(M==null)return;const p=Ku(M),Sa=d[p];if(!Sa)return console.warn(`${t.outerHTML} icon name was not found in the provided icons object.`);const La=Qu(t),Ju=Xu(La)?{}:{"aria-hidden":"true"},Eu={...n,"data-lucide":M,...Ju,...c,...La},Yu=Pa(La),_u=Pa(c),Iu=ju("lucide",`lucide-${M}`,...Yu,..._u);Iu&&Object.assign(Eu,{class:Iu});const xu=ka(Sa,Eu);return t.parentNode?.replaceChild(xu,t)},za=[["path",{d:"m14 12 4 4 4-4"}],["path",{d:"M18 16V7"}],["path",{d:"m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16"}],["path",{d:"M3.304 13h6.392"}]],Fa=[["path",{d:"m14 11 4-4 4 4"}],["path",{d:"M18 16V7"}],["path",{d:"m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16"}],["path",{d:"M3.304 13h6.392"}]],Da=[["circle",{cx:"16",cy:"4",r:"1"}],["path",{d:"m18 19 1-7-6 1"}],["path",{d:"m5 8 3-3 5.5 3-2.36 3.5"}],["path",{d:"M4.24 14.5a5 5 0 0 0 6.88 6"}],["path",{d:"M13.76 17.5a5 5 0 0 0-6.88-6"}]],Ra=[["path",{d:"m15 16 2.536-7.328a1.02 1.02 1 0 1 1.928 0L22 16"}],["path",{d:"M15.697 14h5.606"}],["path",{d:"m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16"}],["path",{d:"M3.304 13h6.392"}]],ba=[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"}]],Ta=[["path",{d:"M18 17.5a2.5 2.5 0 1 1-4 2.03V12"}],["path",{d:"M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"}],["path",{d:"M6 8h12"}],["path",{d:"M6.6 15.572A2 2 0 1 0 10 17v-5"}]],qa=[["path",{d:"M5 17H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-1"}],["path",{d:"m12 15 5 6H7Z"}]],g=[["circle",{cx:"12",cy:"13",r:"8"}],["path",{d:"M5 3 2 6"}],["path",{d:"m22 6-3-3"}],["path",{d:"M6.38 18.7 4 21"}],["path",{d:"M17.64 18.67 20 21"}],["path",{d:"m9 13 2 2 4-4"}]],C=[["circle",{cx:"12",cy:"13",r:"8"}],["path",{d:"M5 3 2 6"}],["path",{d:"m22 6-3-3"}],["path",{d:"M6.38 18.7 4 21"}],["path",{d:"M17.64 18.67 20 21"}],["path",{d:"M9 13h6"}]],Ua=[["path",{d:"M6.87 6.87a8 8 0 1 0 11.26 11.26"}],["path",{d:"M19.9 14.25a8 8 0 0 0-9.15-9.15"}],["path",{d:"m22 6-3-3"}],["path",{d:"M6.26 18.67 4 21"}],["path",{d:"m2 2 20 20"}],["path",{d:"M4 4 2 6"}]],u=[["circle",{cx:"12",cy:"13",r:"8"}],["path",{d:"M5 3 2 6"}],["path",{d:"m22 6-3-3"}],["path",{d:"M6.38 18.7 4 21"}],["path",{d:"M17.64 18.67 20 21"}],["path",{d:"M12 10v6"}],["path",{d:"M9 13h6"}]],Oa=[["circle",{cx:"12",cy:"13",r:"8"}],["path",{d:"M12 9v4l2 2"}],["path",{d:"M5 3 2 6"}],["path",{d:"m22 6-3-3"}],["path",{d:"M6.38 18.7 4 21"}],["path",{d:"M17.64 18.67 20 21"}]],Za=[["path",{d:"M11 21c0-2.5 2-2.5 2-5"}],["path",{d:"M16 21c0-2.5 2-2.5 2-5"}],["path",{d:"m19 8-.8 3a1.25 1.25 0 0 1-1.2 1H7a1.25 1.25 0 0 1-1.2-1L5 8"}],["path",{d:"M21 3a1 1 0 0 1 1 1v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V4a1 1 0 0 1 1-1z"}],["path",{d:"M6 21c0-2.5 2-2.5 2-5"}]],Ga=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",ry:"2"}],["polyline",{points:"11 3 11 11 14 8 17 11 17 3"}]],Wa=[["path",{d:"M2 12h20"}],["path",{d:"M10 16v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-4"}],["path",{d:"M10 8V4a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v4"}],["path",{d:"M20 16v1a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2v-1"}],["path",{d:"M14 8V7c0-1.1.9-2 2-2h2a2 2 0 0 1 2 2v1"}]],Ea=[["path",{d:"M12 2v20"}],["path",{d:"M8 10H4a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h4"}],["path",{d:"M16 10h4a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2h-4"}],["path",{d:"M8 20H7a2 2 0 0 1-2-2v-2c0-1.1.9-2 2-2h1"}],["path",{d:"M16 14h1a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2h-1"}]],Ia=[["rect",{width:"6",height:"16",x:"4",y:"2",rx:"2"}],["rect",{width:"6",height:"9",x:"14",y:"9",rx:"2"}],["path",{d:"M22 22H2"}]],Xa=[["rect",{width:"16",height:"6",x:"2",y:"4",rx:"2"}],["rect",{width:"9",height:"6",x:"9",y:"14",rx:"2"}],["path",{d:"M22 22V2"}]],ja=[["rect",{width:"6",height:"14",x:"4",y:"5",rx:"2"}],["rect",{widtLine truncated
If you want to use all the icons you can import it like:
\`import { createIcons, icons } from 'lucide';
lucide.createIcons({icons});\``);if(typeof c>"u")throw new Error("`createIcons()` only works in a browser environment.");if(Array.from(c.querySelectorAll(`[${h}]`)).forEach(p=>Ba(p,{nameAttr:h,icons:t,attrs:d})),M&&Array.from(c.querySelectorAll("template")).forEach(p=>Wu({icons:t,nameAttr:h,attrs:d,root:p.content,inTemplates:M})),h==="data-lucide"){const p=c.querySelectorAll("[icon-name]");p.length>0&&(console.warn("[Lucide] Some icons were found with the now deprecated icon-name attribute. These will still be replaced for backwards compatibility, but will no longer be supported in v1.0 and you should switch to data-lucide"),Array.from(p).forEach(Sa=>Ba(Sa,{nameAttr:"icon-name",icons:t,attrs:d})))}};a.AArrowDown=za,a.AArrowUp=Fa,a.ALargeSmall=Ra,a.Accessibility=Da,a.Activity=ba,a.ActivitySquare=d0,a.AirVent=Ta,a.Airplay=qa,a.AlarmCheck=g,a.AlarmClock=Oa,a.AlarmClockCheck=g,a.AlarmClockMinus=C,a.AlarmClockOff=Ua,a.AlarmClockPlus=u,a.AlarmMinus=C,a.AlarmPlus=u,a.AlarmSmoke=Za,a.Album=Ga,a.AlertCircle=K,a.AlertOctagon=F2,a.AlertTriangle=ra,a.AlignCenter=ca,a.AlignCenterHorizontal=Wa,a.AlignCenterVertical=Ea,a.AlignEndHorizontal=Ia,a.AlignEndVertical=Xa,a.AlignHorizontalDistributeCenter=ja,a.AlignHorizontalDistributeEnd=Na,a.AlignHorizontalDistributeStart=Ka,a.AlignHorizontalJustifyCenter=Qa,a.AlignHorizontalJustifyEnd=Ja,a.AlignHorizontalJustifyStart=Ya,a.AlignHorizontalSpaceAround=_a,a.AlignHorizontalSpaceBetween=xa,a.AlignJustify=pa,a.AlignLeft=s,a.AlignRight=Ma,a.AlignStartHorizontal=at,a.AlignStartVertical=tt,a.AlignVerticalDistributeCenter=ht,a.AlignVerticalDistributeEnd=dt,a.AlignVerticalDistributeStart=ct,a.AlignVerticalJustifyCenter=Mt,a.AlignVerticalJustifyEnd=pt,a.AlignVerticalJustifyStart=it,a.AlignVerticalSpaceAround=nt,a.AlignVerticalSpaceBetween=lt,a.Ambulance=et,a.Ampersand=rt,a.Ampersands=ot,a.Amphora=vt,a.Anchor=$t,a.Angry=mt,a.Annoyed=yt,a.Antenna=st,a.Anvil=Ct,a.Aperture=gt,a.AppWindow=Ht,a.AppWindowMac=ut,a.Apple=At,a.Archive=St,a.ArchiveRestore=Vt,a.ArchiveX=wt,a.AreaChart=b,a.Armchair=Lt,a.ArrowBigDown=kt,a.ArrowBigDownDash=ft,a.ArrowBigLeft=Bt,a.ArrowBigLeftDash=Pt,a.ArrowBigRight=Ft,a.ArrowBigRightDash=zt,a.ArrowBigUp=Rt,a.ArrowBigUpDash=Dt,a.ArrowDown=It,a.ArrowDown01=bt,a.ArrowDown10=Tt,a.ArrowDownAZ=A,a.ArrowDownAz=A,a.ArrowDownCircle=Q,a.ArrowDownFromLine=qt,a.ArrowDownLeft=Ut,a.ArrowDownLeftFromCircle=Y,a.ArrowDownLeftFromSquare=n0,a.ArrowDownLeftSquare=c0,a.ArrowDownNarrowWide=Ot,a.ArrowDownRight=Zt,a.ArrowDownRightFromCircle=_,a.ArrowDownRightFromSquare=l0,a.ArrowDownRightSquare=M0,a.ArrowDownSquare=p0,a.ArrowDownToDot=Gt,a.ArrowDownToLine=Wt,a.ArrowDownUp=Et,a.ArrowDownWideNarrow=H,a.ArrowDownZA=V,a.ArrowDownZa=V,a.ArrowLeft=Kt,a.ArrowLeftCircle=J,a.ArrowLeftFromLine=Xt,a.ArrowLeftRight=jt,a.ArrowLeftSquare=i0,a.ArrowLeftToLine=Nt,a.ArrowRight=_t,a.ArrowRightCircle=t1,a.ArrowRightFromLine=Qt,a.ArrowRightLeft=Jt,a.ArrowRightSquare=o0,a.ArrowRightToLine=Yt,a.ArrowUp=nh,a.ArrowUp01=xt,a.ArrowUp10=ah,a.ArrowUpAZ=w,a.ArrowUpAz=w,a.ArrowUpCircle=h1,a.ArrowUpDown=th,a.ArrowUpFromDot=hh,a.ArrowUpFromLine=dh,a.ArrowUpLeft=ch,a.ArrowUpLeftFromCircle=x,a.ArrowUpLeftFromSquare=e0,a.ArrowUpLeftSquare=v0,a.ArrowUpNarrowWide=S,a.ArrowUpRight=ph,a.ArrowUpRightFromCircle=a1,a.ArrowUpRightFromSquare=r0,a.ArrowUpRightSquare=$0,a.ArrowUpSquare=m0,a.ArrowUpToLine=Mh,a.ArrowUpWideNarrow=ih,a.ArrowUpZA=L,a.ArrowUpZa=L,a.ArrowsUpFromLine=lh,a.Asterisk=eh,a.AsteriskSquare=s0,a.AtSign=rh,a.Atom=oh,a.AudioLines=vh,a.AudioWaveform=$h,a.Award=mh,a.Axe=yh,a.Axis3D=f,a.Axis3d=f,a.Baby=sh,a.Backpack=gh,a.Badge=Dh,a.BadgeAlert=Ch,a.BadgeCent=uh,a.BadgeCheck=k,a.BadgeDollarSign=Ah,a.BadgeEuro=Hh,a.BadgeHelp=P,a.BadgeIndianRupee=Vh,a.BadgeInfo=wh,a.BadgeJapaneseYen=Sh,a.BadgeMinus=Lh,a.BadgePercent=fh,a.BadgePlus=kh,a.BadgePoundSterling=Ph,a.BadgeQuestionMark=P,a.BadgeRussianRuble=Bh,a.BadgeSwissFranc=zh,a.BadgeTurkishLira=Fh,a.BadgeX=Rh,a.BaggageClaim=bh,a.Balloon=Th,a.Ban=qh,a.Banana=Uh,a.Bandage=Oh,a.Banknote=Eh,a.BanknoteArrowDown=Zh,a.BanknoteArrowUp=Gh,a.BanknoteX=Wh,a.BarChart=E,a.BarChart2=I,a.BarChart3=G,a.BarChart4=Z,a.BarChartBig=U,a.BarChartHorizontal=q,a.BarChartHorizontalBig=T,a.Barcode=Ih,a.Barrel=Xh,a.Baseline=jh,a.Bath=Nh,a.Battery=a4,a.BatteryCharging=Kh,a.BatteryFull=Qh,a.BatteryLow=Jh,a.BatteryMedium=Yh,a.BatteryPlus=_h,a.BatteryWarning=xh,a.Beaker=t4,a.Bean=d4,a.BeanOff=h4,a.Bed=p4,a.BedDouble=c4,a.BedSingle=M4,a.Beef=n4,a.BeefOff=i4,a.Beer=e4,a.BeerOff=l4,a.Bell=g4,a.BellCheck=r4,a.BellDot=o4,a.BellElectric=v4,a.BellMinus=$4,a.BellOff=m4,a.BellPlus=y4,a.BellRing=s4,a.BetweenHorizonalEnd=B,a.BetweenHorizonalStart=z,a.BetweenHorizontalEnd=B,a.BetweenHorizontalStart=z,a.BetweenVerticalEnd=C4,a.BetweenVerticalStart=A4,a.BicepsFlexed=u4,a.Bike=H4,a.Binary=V4,a.Binoculars=w4,a.Biohazard=S4,a.Bird=L4,a.Birdhouse=f4,a.Bitcoin=P4,a.Blend=k4,a.Blinds=B4,a.Blocks=z4,a.Bluetooth=b4,a.BluetoothConnected=F4,a.BluetoothOff=D4,a.BluetoothSearching=R4,a.Bold=T4,a.Bolt=q4,a.Bomb=U4,a.Bone=O4,a.Book=e5,a.BookLine truncated
//# sourceMappingURL=lucide.min.js.map